135 lines
2.8 KiB
Go
135 lines
2.8 KiB
Go
package utils
|
||
|
||
import (
|
||
"crypto/tls"
|
||
"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)
|
||
tlsConfig := &tls.Config{InsecureSkipVerify: true}
|
||
c, err := client.DialTLS(server, tlsConfig)
|
||
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 htmlContent, textContent string
|
||
|
||
for {
|
||
p, err := mr.NextPart()
|
||
if err == io.EOF {
|
||
break
|
||
}
|
||
if err != nil {
|
||
return "", fmt.Errorf("读取邮件失败: %v", err)
|
||
}
|
||
|
||
switch h := p.Header.(type) {
|
||
case *mail.InlineHeader:
|
||
mediaType, _, _ := h.ContentType()
|
||
b, _ := io.ReadAll(p.Body)
|
||
if strings.HasPrefix(mediaType, "text/html") {
|
||
htmlContent = string(b)
|
||
} else if strings.HasPrefix(mediaType, "text/plain") {
|
||
textContent = string(b)
|
||
}
|
||
}
|
||
}
|
||
|
||
// 优先返回 HTML,没有就退回纯文本
|
||
if htmlContent != "" {
|
||
return htmlContent, nil
|
||
}
|
||
return textContent, nil
|
||
}
|
||
|
||
func (e *EmailImap) GetMailCode(server, username, password string) string {
|
||
res, err := e.GetLatestMailContent(server, username, password)
|
||
if err != nil {
|
||
return "0"
|
||
}
|
||
|
||
htmlStr := res
|
||
|
||
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 strings.TrimSpace(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)
|
||
}
|