123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- 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, to uint32) (err error) { // 收件箱
- obj := new(report.OutsideEmailBaseInfo)
- // 创建一个序列集,用于批量读取邮件
- seqSet := new(imap.SeqSet)
- 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) (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 {
- global.FILE_LOG.Info("服务器没有返回消息内容")
- }
- mr, err := mail.CreateReader(r)
- if err != nil {
- //log.Fatalf("邮件读取时出现错误: %v \n", err)
- err = errors.New(fmt.Sprintf("邮件读取时出现错误:%v \n", err))
- 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, "@") {
- emailMessage.FromAddress = fromStr
- emailMessage.From = fromStr
- } else {
- from, tmpErr := mr.Header.AddressList("From")
- if tmpErr != nil {
- log.Println("发件人 异常:", err.Error())
- }
- if len(from) > 0 {
- 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
- }
|