feat: implement mail service client for email generation, mailbox creation, and verification code retrieval.

This commit is contained in:
2026-02-03 08:59:49 +08:00
parent d92c64f2c2
commit 1bd3d120c1

View File

@@ -355,30 +355,61 @@ func (m *Client) GetEmails(email string, size int) ([]EmailItem, error) {
// WaitForCode 等待验证码邮件
func (m *Client) WaitForCode(email string, timeout time.Duration) (string, error) {
start := time.Now()
// 匹配6位数字验证码
codeRegex := regexp.MustCompile(`\b(\d{6})\b`)
// 专门匹配 OpenAI 验证码邮件标题格式: "Your ChatGPT code is 016547" 或 "OpenAI - Verify your email"
titleCodeRegex := regexp.MustCompile(`(?i)(?:code\s+is\s+|code:\s*|验证码[:]\s*)(\d{6})`)
// 记录已经看到的验证码,避免重复返回旧验证码
seenCodes := make(map[string]bool)
// 第一次获取邮件,记录已有的验证码(这些是旧的)
initialEmails, _ := m.GetEmails(email, 10)
for _, mail := range initialEmails {
// 从标题提取
if matches := codeRegex.FindStringSubmatch(mail.Subject); len(matches) >= 2 {
seenCodes[matches[1]] = true
}
// 从内容提取
content := mail.Content
if content == "" {
content = mail.Text
}
if matches := codeRegex.FindStringSubmatch(content); len(matches) >= 2 {
seenCodes[matches[1]] = true
}
}
for time.Since(start) < timeout {
emails, err := m.GetEmails(email, 10)
if err == nil {
for _, mail := range emails {
subject := strings.ToLower(mail.Subject)
// 匹配多种可能的验证码邮件主题
// 包括 "Your ChatGPT code is 016547" 格式
isCodeEmail := strings.Contains(subject, "code") ||
strings.Contains(subject, "verify") ||
strings.Contains(subject, "verification") ||
// 匹配 OpenAI/ChatGPT 验证码邮件
// 标题格式: "Your ChatGPT code is 016547" 或包含 "verify", "code" 等
isCodeEmail := strings.Contains(subject, "chatgpt code") ||
strings.Contains(subject, "openai") ||
strings.Contains(subject, "confirm") ||
strings.Contains(subject, "chatgpt")
strings.Contains(subject, "verify your email") ||
(strings.Contains(subject, "code") && strings.Contains(subject, "is"))
if !isCodeEmail {
continue
}
// 优先从标题中提取验证码 (如 "Your ChatGPT code is 016547")
matches := codeRegex.FindStringSubmatch(mail.Subject)
if len(matches) >= 2 {
return matches[1], nil
// 优先使用专门的标题正则匹配 (如 "Your ChatGPT code is 016547")
if matches := titleCodeRegex.FindStringSubmatch(mail.Subject); len(matches) >= 2 {
code := matches[1]
if !seenCodes[code] {
return code, nil
}
}
// 从标题中提取6位数字
if matches := codeRegex.FindStringSubmatch(mail.Subject); len(matches) >= 2 {
code := matches[1]
if !seenCodes[code] {
return code, nil
}
}
// 如果标题中没有,从内容中提取
@@ -386,9 +417,20 @@ func (m *Client) WaitForCode(email string, timeout time.Duration) (string, error
if content == "" {
content = mail.Text
}
matches = codeRegex.FindStringSubmatch(content)
if len(matches) >= 2 {
return matches[1], nil
// 在内容中查找验证码,优先匹配 "enter this code:" 后面的数字
contentCodeRegex := regexp.MustCompile(`(?i)(?:enter\s+this\s+code[:]\s*|code[:]\s*)(\d{6})`)
if matches := contentCodeRegex.FindStringSubmatch(content); len(matches) >= 2 {
code := matches[1]
if !seenCodes[code] {
return code, nil
}
}
// 最后尝试普通6位数字匹配
if matches := codeRegex.FindStringSubmatch(content); len(matches) >= 2 {
code := matches[1]
if !seenCodes[code] {
return code, nil
}
}
}
}