feat: Add automated ChatGPT account registration with backend API, TLS client, and fingerprinting, alongside new frontend pages for configuration, monitoring, and upload.

This commit is contained in:
2026-02-03 02:39:08 +08:00
parent 389b8eca28
commit 51ba54856d
18 changed files with 1382 additions and 674 deletions

View File

@@ -11,6 +11,7 @@ import (
"time"
"codex-pool/internal/client"
"codex-pool/internal/logger"
"codex-pool/internal/mail"
)
@@ -236,6 +237,7 @@ func (r *ChatGPTReg) CreateAccount(name, birthdate string) error {
return fmt.Errorf("创建账户失败,状态码: %d", resp.StatusCode)
}
// 处理可能出现的继续 URL
var result map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&result); err == nil {
if continueURL, ok := result["continue_url"].(string); ok && continueURL != "" {
@@ -274,142 +276,134 @@ func (r *ChatGPTReg) GetSessionToken() error {
return fmt.Errorf("响应中没有 accessToken")
}
// Run 完整的注册流程
func Run(email, password, name, birthdate, proxy string) (*ChatGPTReg, error) {
return RunWithRetry(email, password, name, birthdate, proxy, 3)
// Run 执行单次注册(由 main.go 调用)
func Run(email, password, realName, birthdate, proxy string) (*ChatGPTReg, error) {
return APIRegister(email, password, realName, birthdate, proxy, "[RegTest]")
}
// RunWithRetry 带重试的注册流程
// 当验证码获取超过5秒就换新邮箱重新注册
func RunWithRetry(email, password, name, birthdate, proxy string, maxRetries int) (*ChatGPTReg, error) {
for attempt := 0; attempt < maxRetries; attempt++ {
if attempt > 0 {
// 重试时生成新邮箱
email = mail.GenerateEmail()
password = GeneratePassword()
fmt.Printf(" [Retry %d] New email: %s\n", attempt, email)
// APIRegister 使用 API 完成注册 (集成 403 重试机制)
func APIRegister(email, password, realName, birthdate, proxy string, logPrefix string) (*ChatGPTReg, error) {
var reg *ChatGPTReg
var lastErr error
// 403 重试机制 - 最多重试 3 次,每次换新指纹
for retry := 0; retry < 3; retry++ {
var err error
reg, err = New(proxy)
if err != nil {
lastErr = err
if retry < 2 {
logger.Warning(fmt.Sprintf("%s 客户端创建失败,重试 %d/3...", logPrefix, retry+1), email, "register")
continue
}
return nil, fmt.Errorf("客户端创建失败: %v", err)
}
reg, err := runOnce(email, password, name, birthdate, proxy)
if err == nil {
return reg, nil
fpInfo := reg.Client.GetFingerprintInfo()
if retry == 0 {
logger.Info(fmt.Sprintf("%s 初始化会话... [%s]", logPrefix, fpInfo), email, "register")
} else {
logger.Warning(fmt.Sprintf("%s 403 重试 %d/3换指纹 [%s]", logPrefix, retry, fpInfo), email, "register")
}
// 如果不是验证码超时错误,直接返回
if !strings.Contains(err.Error(), "验证码获取超时") {
return nil, err
if err := reg.InitSession(); err != nil {
if strings.Contains(err.Error(), "403") {
lastErr = err
reg.Client.Close()
continue // 403 则换指纹重试
}
return nil, fmt.Errorf("初始化失败: %v", err)
}
fmt.Printf(" [!] OTP timeout, retrying with new email...\n")
// 初始化成功
lastErr = nil
break
}
return nil, fmt.Errorf("注册失败: 已重试 %d 次", maxRetries)
}
// runOnce 执行一次注册流程(使用短超时获取验证码)
func runOnce(email, password, name, birthdate, proxy string) (*ChatGPTReg, error) {
reg, err := New(proxy)
if err != nil {
return nil, err
if lastErr != nil {
return nil, fmt.Errorf("初始化失败: %v (已重试3次)", lastErr)
}
// 初始化
if err := reg.InitSession(); err != nil {
return nil, fmt.Errorf("初始化失败: %v", err)
}
// 获取授权 URL
if err := reg.GetAuthorizeURL(email); err != nil {
return nil, fmt.Errorf("获取授权URL失败: %v", err)
}
// 开始授权流程
if err := reg.StartAuthorize(); err != nil {
return nil, fmt.Errorf("启动授权失败: %v", err)
return nil, fmt.Errorf("授权流程失败: %v", err)
}
// 注册
// 注册账户
if err := reg.Register(email, password); err != nil {
return nil, fmt.Errorf("注册失败: %v", err)
return nil, fmt.Errorf("注册账号失败: %v", err)
}
// 发送验证邮件
if err := reg.SendVerificationEmail(); err != nil {
return nil, fmt.Errorf("发送邮件失败: %v", err)
return nil, fmt.Errorf("发送验证邮件失败: %v", err)
}
logger.Success(fmt.Sprintf("%s 已发送验证邮件", logPrefix), email, "register")
// 先用5秒超时尝试获取验证码
otpCode, err := mail.GetVerificationCode(email, 5*time.Second)
// 获取验证码 (带超时 90s)
logger.Info(fmt.Sprintf("%s 等待验证码...", logPrefix), email, "register")
otpCode, err := mail.GetVerificationCode(email, 90*time.Second)
if err != nil {
// 5秒内没获取到再等120秒总共等待更多时间
otpCode, err = mail.GetVerificationCode(email, 120*time.Second)
if err != nil {
return nil, fmt.Errorf("验证码获取超时")
}
return nil, err
}
logger.Success(fmt.Sprintf("%s 验证码: %s", logPrefix, otpCode), email, "register")
// 验证 OTP
if err := reg.ValidateOTP(otpCode); err != nil {
return nil, fmt.Errorf("OTP验证失败: %v", err)
return nil, fmt.Errorf("验证OTP失败: %v", err)
}
// 创建账户
if err := reg.CreateAccount(name, birthdate); err != nil {
if err := reg.CreateAccount(realName, birthdate); err != nil {
return nil, fmt.Errorf("创建账户失败: %v", err)
}
// 获取 Token
// 预热 session (可选)
_ = reg.GetSessionToken()
return reg, nil
}
// ==================== 工具函数 ====================
// GenerateName 生成随机姓名
func GenerateName() string {
firstNames := []string{"James", "John", "Robert", "Michael", "David", "William", "Richard", "Joseph", "Thomas", "Charles"}
lastNames := []string{"Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez"}
return firstNames[rand.Intn(len(firstNames))] + " " + lastNames[rand.Intn(len(lastNames))]
}
// GenerateUUID 生成 UUID
func GenerateUUID() string {
b := make([]byte, 16)
rand.Read(b)
b[6] = (b[6] & 0x0f) | 0x40
b[8] = (b[8] & 0x3f) | 0x80
return fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:16])
return fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
}
// GenerateBirthdate 生成随机生日
// GenerateName 随机生成姓名
func GenerateName() string {
firstNames := []string{"James", "Mary", "John", "Patricia", "Robert", "Jennifer", "Michael", "Linda", "William", "Elizabeth"}
lastNames := []string{"Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez"}
return firstNames[rand.Intn(len(firstNames))] + " " + lastNames[rand.Intn(len(lastNames))]
}
// GenerateBirthdate 随机生成生日
func GenerateBirthdate() string {
year := 2000 + rand.Intn(5)
month := 1 + rand.Intn(12)
day := 1 + rand.Intn(28)
return fmt.Sprintf("%d-%02d-%02d", year, month, day)
year := rand.Intn(20) + 1980
month := rand.Intn(12) + 1
day := rand.Intn(28) + 1
return fmt.Sprintf("%04d-%02d-%02d", year, month, day)
}
// GeneratePassword 生成随机密码
// GeneratePassword 随机生成密码
func GeneratePassword() string {
const (
upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
lower = "abcdefghijklmnopqrstuvwxyz"
digits = "0123456789"
special = "!@#$%"
)
b := make([]byte, 13)
for i := 0; i < 2; i++ {
b[i] = upper[rand.Intn(len(upper))]
chars := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*"
p := make([]byte, 12)
for i := range p {
p[i] = chars[rand.Intn(len(chars))]
}
for i := 2; i < 10; i++ {
b[i] = lower[rand.Intn(len(lower))]
}
for i := 10; i < 12; i++ {
b[i] = digits[rand.Intn(len(digits))]
}
b[12] = special[rand.Intn(len(special))]
return string(b)
return string(p)
}
func truncateStr(s string, maxLen int) string {
if len(s) <= maxLen {
func truncateStr(s string, max int) string {
if len(s) <= max {
return s
}
return s[:maxLen] + "..."
return s[:max] + "..."
}