|
@@ -3,49 +3,125 @@ package mail
|
|
|
import (
|
|
|
"errors"
|
|
|
"eta/eta_email_analysis/global"
|
|
|
+ "eta/eta_email_analysis/models/report"
|
|
|
"fmt"
|
|
|
"github.com/emersion/go-imap"
|
|
|
"github.com/emersion/go-imap/client"
|
|
|
+ "github.com/emersion/go-message"
|
|
|
"github.com/emersion/go-message/mail"
|
|
|
"log"
|
|
|
"strings"
|
|
|
+ "time"
|
|
|
)
|
|
|
|
|
|
-func ListenMailV2(c *client.Client, index int) (fromAddress, fromName string, err error) { // 收件箱
|
|
|
+func ListenMailV2(c *client.Client, to uint32) (err error) { // 收件箱
|
|
|
+ obj := new(report.OutsideEmailBaseInfo)
|
|
|
// 创建一个序列集,用于批量读取邮件
|
|
|
seqSet := new(imap.SeqSet)
|
|
|
- seqSet.AddRange(uint32(index), uint32(index)) // 添加指定范围内的邮件编号
|
|
|
-
|
|
|
- // 获取整个消息正文
|
|
|
- // imap.FetchEnvelope:请求获取邮件的信封数据(例如发件人、收件人、主题等元数据)。
|
|
|
- // imap.FetchRFC822:请求获取完整的邮件内容,包括所有头部和正文。
|
|
|
- items := []imap.FetchItem{imap.FetchFlags, imap.FetchEnvelope, imap.FetchRFC822}
|
|
|
-
|
|
|
- // 获取邮件内容 Start
|
|
|
- messages := make(chan *imap.Message, 5) // 创建一个通道,用于接收邮件消息
|
|
|
- fetchDone := make(chan error, 1) // 创建一个通道,用于接收错误消息
|
|
|
- go func() {
|
|
|
- // Fetch方法用于从服务器获取邮件数据,这里请求了邮件的信封和完整内容
|
|
|
- fetchDone <- c.Fetch(seqSet, items, messages)
|
|
|
- }()
|
|
|
-
|
|
|
- err = <-fetchDone
|
|
|
- if err != nil {
|
|
|
- global.LOG.Errorf("获取邮件信息出现错误:%v \n", err)
|
|
|
- return
|
|
|
- }
|
|
|
- // 获取邮件内容 End
|
|
|
|
|
|
- //log.Println("开始读取邮件内容")
|
|
|
- for msg := range messages {
|
|
|
- return readEveryMsgV2(msg)
|
|
|
+ var isStopFor bool
|
|
|
+ step := uint32(1)
|
|
|
+ for i := to; i >= 1; {
|
|
|
+ start := i - step + 1
|
|
|
+ if start < 0 {
|
|
|
+ start = 1
|
|
|
+ }
|
|
|
+
|
|
|
+ //fmt.Printf("当前剩余%d封邮件待处理\n", i-minIndex+1)
|
|
|
+
|
|
|
+ seqSet.Clear()
|
|
|
+ seqSet.AddRange(start, i) // 添加指定范围内的邮件编号
|
|
|
+
|
|
|
+ // 获取整个消息正文
|
|
|
+ // imap.FetchEnvelope:请求获取邮件的信封数据(例如发件人、收件人、主题等元数据)。
|
|
|
+ // imap.FetchRFC822:请求获取完整的邮件内容,包括所有头部和正文。
|
|
|
+ items := []imap.FetchItem{imap.FetchFlags, imap.FetchEnvelope, imap.FetchRFC822}
|
|
|
+
|
|
|
+ // 获取邮件内容 Start
|
|
|
+ messages := make(chan *imap.Message, global.CONFIG.Email.ReadBatchSize) // 创建一个通道,用于接收邮件消息
|
|
|
+ fetchDone := make(chan error, 1) // 创建一个通道,用于接收错误消息
|
|
|
+ go func() {
|
|
|
+ // Fetch方法用于从服务器获取邮件数据,这里请求了邮件的信封和完整内容
|
|
|
+ fetchDone <- c.Fetch(seqSet, items, messages)
|
|
|
+ }()
|
|
|
+
|
|
|
+ err = <-fetchDone
|
|
|
+ if err != nil {
|
|
|
+ global.LOG.Errorf("获取邮件信息出现错误:%v \n", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 获取邮件内容 End
|
|
|
+
|
|
|
+ //log.Println("开始读取邮件内容")
|
|
|
+ for msg := range messages {
|
|
|
+ // 如果需要终止,那么就不处理了
|
|
|
+ if isStopFor {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ emailMessage, isRead, tmpErr := readEveryMsgV2(msg)
|
|
|
+ if tmpErr != nil {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if !isRead {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ // 记录邮件信息
|
|
|
+ {
|
|
|
+ outEmail, _ := obj.GetByEmailMessageIdAndFolder(emailMessage.Uid, emailMessage.Folder)
|
|
|
+ if outEmail == nil || outEmail.EmailMessageUid <= 0 {
|
|
|
+ outsideEmail := &report.OutsideEmailBaseInfo{
|
|
|
+ Id: 0,
|
|
|
+ Folder: emailMessage.Folder,
|
|
|
+ EmailMessageUid: emailMessage.Uid,
|
|
|
+ Title: emailMessage.Title,
|
|
|
+ FromAddress: emailMessage.FromAddress,
|
|
|
+ From: emailMessage.From,
|
|
|
+ DeliveryTime: emailMessage.Date,
|
|
|
+ CreateTime: time.Now(),
|
|
|
+ }
|
|
|
+ tmpErr := obj.Add(outsideEmail)
|
|
|
+ if tmpErr != nil {
|
|
|
+ fmt.Println("保存邮件基础信息失败:" + tmpErr.Error())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if isStopFor {
|
|
|
+ // 已经找到了最小的邮件id,那么就退出循环了
|
|
|
+ }
|
|
|
+ //time.Sleep(time.Second * 5) // 休眠10秒
|
|
|
+
|
|
|
+ i = i - step
|
|
|
}
|
|
|
|
|
|
+ log.Println("读取了所有邮件,完毕!")
|
|
|
+
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// document link: https://github.com/emersion/go-imap/wiki/Fetching-messages
|
|
|
-func readEveryMsgV2(msg *imap.Message) (fromAddress, fromName string, err error) {
|
|
|
+func readEveryMsgV2(msg *imap.Message) (emailMessage MailMessage, ok bool, err error) {
|
|
|
+ emailMessage = MailMessage{}
|
|
|
+
|
|
|
+ message.CharsetReader = myCharsetReader
|
|
|
+ emailMessage.Resources = make(map[string]string) // 内嵌资源
|
|
|
+ emailMessage.Attachment = make(map[string]string) // 附件
|
|
|
+
|
|
|
+ emailMessage.Uid = msg.Uid
|
|
|
+ emailMessage.Folder = global.CONFIG.Email.Folder
|
|
|
+ if IsHandleMessageIdMap != nil {
|
|
|
+ if _, has := IsHandleMessageIdMap[int(emailMessage.Uid)]; has {
|
|
|
+ fmt.Println("邮件已处理,邮件下标:", emailMessage.Uid)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //log.Printf("当前邮件的消息序列号 %+v \n", msg.SeqNum)
|
|
|
+ //log.Println("-------------------------")
|
|
|
// 获取邮件正文
|
|
|
r := msg.GetBody(&imap.BodySectionName{})
|
|
|
if r == nil {
|
|
@@ -59,31 +135,59 @@ func readEveryMsgV2(msg *imap.Message) (fromAddress, fromName string, err error)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+ // 收件时间
|
|
|
+ {
|
|
|
+ date, err := mr.Header.Date()
|
|
|
+ if err != nil {
|
|
|
+ log.Println("收件时间 异常:", err.Error())
|
|
|
+ }
|
|
|
+ emailMessage.Date = date
|
|
|
+ //log.Println("收件时间 Date:", date)
|
|
|
+ }
|
|
|
+
|
|
|
// 发件人
|
|
|
{
|
|
|
fromStr := mr.Header.Get("From")
|
|
|
//fmt.Println(fromStr)
|
|
|
// 处理无效地址的情况
|
|
|
if !strings.Contains(fromStr, "@") {
|
|
|
- fromStr = strings.TrimSpace(fromStr)
|
|
|
- fromStr = strings.TrimPrefix(fromStr, `"`)
|
|
|
- fromStr = strings.TrimSuffix(fromStr, `"`)
|
|
|
- //fmt.Println(fromStr)
|
|
|
- fromAddress = fromStr
|
|
|
- fromName = fromStr
|
|
|
+ emailMessage.FromAddress = fromStr
|
|
|
+ emailMessage.From = fromStr
|
|
|
} else {
|
|
|
from, tmpErr := mr.Header.AddressList("From")
|
|
|
if tmpErr != nil {
|
|
|
log.Println("发件人 异常:", err.Error())
|
|
|
}
|
|
|
if len(from) > 0 {
|
|
|
- fromAddress = from[0].Address
|
|
|
- fromName = from[0].Name
|
|
|
+ emailMessage.FromAddress = from[0].Address
|
|
|
+ emailMessage.From = from[0].Name
|
|
|
//mailMessage.From = from[0].String()
|
|
|
//log.Println("发件人 From:", from)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ //if to, err := mr.Header.AddressList("To"); err == nil {
|
|
|
+ // log.Println("收件人 To:", to)
|
|
|
+ //}
|
|
|
+ //log.Printf("抄送 Cc: %+v \n", msg.Envelope.Cc)
|
|
|
+
|
|
|
+ // 邮件标题
|
|
|
+ subject, err := mr.Header.Subject()
|
|
|
+ if err != nil {
|
|
|
+ log.Println("邮件主题 Subject ERR:", err)
|
|
|
+ } else {
|
|
|
+ //log.Println("邮件主题 Subject:", subject)
|
|
|
+ }
|
|
|
+ emailMessage.Title = subject
|
|
|
+
|
|
|
+ // 过滤
|
|
|
+ if isIgnore(emailMessage) {
|
|
|
+ ok = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ ok = true
|
|
|
+
|
|
|
return
|
|
|
}
|