feat: Implement browserless Codex API authentication with PoW solving and a new mail service, and update gitignore to exclude get_code.go.

This commit is contained in:
2026-02-04 09:43:22 +08:00
parent 381cbd41fa
commit 61712cf4fb
3 changed files with 106 additions and 3 deletions

View File

@@ -129,6 +129,7 @@ type EmailListResponse struct {
// EmailItem 邮件项
type EmailItem struct {
EmailID int `json:"emailId"`
Content string `json:"content"`
Text string `json:"text"`
Subject string `json:"subject"`
@@ -504,3 +505,57 @@ func GetVerificationCode(email string, timeout time.Duration) (string, error) {
client := NewClientForEmail(email)
return client.WaitForCode(email, timeout)
}
// GetLatestEmailID 获取邮箱最新邮件的ID
// 基于 get_code.go 的实现用于在发送验证码请求前记录最新邮件ID
func GetLatestEmailID(email string) int {
client := NewClientForEmail(email)
emails, err := client.GetEmails(email, 1)
if err != nil || len(emails) == 0 {
return 0
}
return emails[0].EmailID
}
// GetEmailOTPAfterID 获取指定邮件ID之后的OTP验证码
// 基于 get_code.go 的实现,只获取 afterEmailID 之后的新邮件中的验证码
func GetEmailOTPAfterID(email string, afterEmailID int, timeout time.Duration) (string, error) {
client := NewClientForEmail(email)
start := time.Now()
codeRegex := regexp.MustCompile(`\b(\d{6})\b`)
for time.Since(start) < timeout {
emails, err := client.GetEmails(email, 5)
if err == nil {
for _, mail := range emails {
// 只处理 afterEmailID 之后的新邮件
if mail.EmailID <= afterEmailID {
continue
}
subject := strings.ToLower(mail.Subject)
// 匹配 OpenAI/ChatGPT 验证码邮件
if !strings.Contains(subject, "code") {
continue
}
// 从标题提取验证码
if matches := codeRegex.FindStringSubmatch(mail.Subject); len(matches) >= 2 {
return matches[1], nil
}
// 从内容提取验证码
content := mail.Content
if content == "" {
content = mail.Text
}
if matches := codeRegex.FindStringSubmatch(content); len(matches) >= 2 {
return matches[1], nil
}
}
}
time.Sleep(1 * time.Second)
}
return "", fmt.Errorf("验证码获取超时 (afterEmailID=%d)", afterEmailID)
}