feat: implement mail service client for email generation, mailbox creation, and verification code retrieval.
This commit is contained in:
@@ -355,30 +355,61 @@ func (m *Client) GetEmails(email string, size int) ([]EmailItem, error) {
|
|||||||
// WaitForCode 等待验证码邮件
|
// WaitForCode 等待验证码邮件
|
||||||
func (m *Client) WaitForCode(email string, timeout time.Duration) (string, error) {
|
func (m *Client) WaitForCode(email string, timeout time.Duration) (string, error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
// 匹配6位数字验证码
|
||||||
codeRegex := regexp.MustCompile(`\b(\d{6})\b`)
|
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 {
|
for time.Since(start) < timeout {
|
||||||
emails, err := m.GetEmails(email, 10)
|
emails, err := m.GetEmails(email, 10)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for _, mail := range emails {
|
for _, mail := range emails {
|
||||||
subject := strings.ToLower(mail.Subject)
|
subject := strings.ToLower(mail.Subject)
|
||||||
// 匹配多种可能的验证码邮件主题
|
// 匹配 OpenAI/ChatGPT 验证码邮件
|
||||||
// 包括 "Your ChatGPT code is 016547" 格式
|
// 标题格式: "Your ChatGPT code is 016547" 或包含 "verify", "code" 等
|
||||||
isCodeEmail := strings.Contains(subject, "code") ||
|
isCodeEmail := strings.Contains(subject, "chatgpt code") ||
|
||||||
strings.Contains(subject, "verify") ||
|
|
||||||
strings.Contains(subject, "verification") ||
|
|
||||||
strings.Contains(subject, "openai") ||
|
strings.Contains(subject, "openai") ||
|
||||||
strings.Contains(subject, "confirm") ||
|
strings.Contains(subject, "verify your email") ||
|
||||||
strings.Contains(subject, "chatgpt")
|
(strings.Contains(subject, "code") && strings.Contains(subject, "is"))
|
||||||
|
|
||||||
if !isCodeEmail {
|
if !isCodeEmail {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// 优先从标题中提取验证码 (如 "Your ChatGPT code is 016547")
|
// 优先使用专门的标题正则匹配 (如 "Your ChatGPT code is 016547")
|
||||||
matches := codeRegex.FindStringSubmatch(mail.Subject)
|
if matches := titleCodeRegex.FindStringSubmatch(mail.Subject); len(matches) >= 2 {
|
||||||
if len(matches) >= 2 {
|
code := matches[1]
|
||||||
return matches[1], nil
|
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 == "" {
|
if content == "" {
|
||||||
content = mail.Text
|
content = mail.Text
|
||||||
}
|
}
|
||||||
matches = codeRegex.FindStringSubmatch(content)
|
// 在内容中查找验证码,优先匹配 "enter this code:" 后面的数字
|
||||||
if len(matches) >= 2 {
|
contentCodeRegex := regexp.MustCompile(`(?i)(?:enter\s+this\s+code[::]\s*|code[::]\s*)(\d{6})`)
|
||||||
return matches[1], nil
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user