package utils import ( "fmt" "io" "log" "strings" "github.com/PuerkitoBio/goquery" "github.com/emersion/go-imap" "github.com/emersion/go-imap/client" "github.com/emersion/go-message/mail" ) type EmailImap struct { } // 获取最新一封邮件的正文内容 func (*EmailImap) GetLatestMailContent(server, username, password string) (string, error) { // 1. 连接 IMAP 服务器 (SSL/TLS, 端口 993) c, err := client.DialTLS(server, nil) if err != nil { return "", fmt.Errorf("连接失败: %v", err) } defer c.Logout() // 2. 登录 if err := c.Login(username, password); err != nil { return "", fmt.Errorf("登录失败: %v", err) } // 3. 选择收件箱 mbox, err := c.Select("INBOX", false) if err != nil { return "", fmt.Errorf("选择收件箱失败: %v", err) } if mbox.Messages == 0 { return "", nil // 没有邮件 } // 4. 获取最新一封邮件 seqset := new(imap.SeqSet) seqset.AddNum(mbox.Messages) section := &imap.BodySectionName{} messages := make(chan *imap.Message, 1) go func() { if err := c.Fetch(seqset, []imap.FetchItem{section.FetchItem()}, messages); err != nil { log.Println("获取邮件失败:", err) } }() msg := <-messages if msg == nil { return "", nil } r := msg.GetBody(section) if r == nil { return "", nil } // 5. 解析邮件正文 mr, err := mail.CreateReader(r) if err != nil { return "", fmt.Errorf("解析邮件失败: %v", err) } var content string for { p, err := mr.NextPart() if err == io.EOF { break } if err != nil { return "", fmt.Errorf("读取邮件失败: %v", err) } switch p.Header.(type) { case *mail.InlineHeader: b, _ := io.ReadAll(p.Body) content = strings.TrimSpace(string(b)) // 只取第一个正文即可 return content, nil } } return content, nil } func (e *EmailImap) GetMailCode(server, username, password string) string { res, err := e.GetLatestMailContent(server, username, password) if err != nil { return "0" } htmlStr := res fmt.Println(htmlStr) doc, err := goquery.NewDocumentFromReader(strings.NewReader(htmlStr)) if err != nil { return "0" } code := "" doc.Find("td.h1.black").Each(func(i int, s *goquery.Selection) { if code == "" { code = strings.TrimSpace(s.Text()) } }) if code == "" { return "0" } return code } func test() { var emailImap EmailImap content, err := emailImap.GetLatestMailContent("pop.dragonsmail.com:993", "CamilleMathews1u8K@dragonsmail.com", "vDgADn`zga.") if err != nil { log.Fatal(err) } fmt.Println("最新邮件内容:\n", content) }