fix.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. package mail
  2. import (
  3. "errors"
  4. "eta/eta_email_analysis/global"
  5. "eta/eta_email_analysis/models/report"
  6. "fmt"
  7. "github.com/emersion/go-imap"
  8. "github.com/emersion/go-imap/client"
  9. "github.com/emersion/go-message"
  10. "github.com/emersion/go-message/mail"
  11. "log"
  12. "strings"
  13. "time"
  14. )
  15. func ListenMailV2(c *client.Client, to uint32) (err error) { // 收件箱
  16. obj := new(report.OutsideEmailBaseInfo)
  17. // 创建一个序列集,用于批量读取邮件
  18. seqSet := new(imap.SeqSet)
  19. var isStopFor bool
  20. step := uint32(1)
  21. for i := to; i >= 1; {
  22. start := i - step + 1
  23. if start < 0 {
  24. start = 1
  25. }
  26. //fmt.Printf("当前剩余%d封邮件待处理\n", i-minIndex+1)
  27. seqSet.Clear()
  28. seqSet.AddRange(start, i) // 添加指定范围内的邮件编号
  29. // 获取整个消息正文
  30. // imap.FetchEnvelope:请求获取邮件的信封数据(例如发件人、收件人、主题等元数据)。
  31. // imap.FetchRFC822:请求获取完整的邮件内容,包括所有头部和正文。
  32. items := []imap.FetchItem{imap.FetchFlags, imap.FetchEnvelope, imap.FetchRFC822}
  33. // 获取邮件内容 Start
  34. messages := make(chan *imap.Message, global.CONFIG.Email.ReadBatchSize) // 创建一个通道,用于接收邮件消息
  35. fetchDone := make(chan error, 1) // 创建一个通道,用于接收错误消息
  36. go func() {
  37. // Fetch方法用于从服务器获取邮件数据,这里请求了邮件的信封和完整内容
  38. fetchDone <- c.Fetch(seqSet, items, messages)
  39. }()
  40. err = <-fetchDone
  41. if err != nil {
  42. global.LOG.Errorf("获取邮件信息出现错误:%v \n", err)
  43. return
  44. }
  45. // 获取邮件内容 End
  46. //log.Println("开始读取邮件内容")
  47. for msg := range messages {
  48. // 如果需要终止,那么就不处理了
  49. if isStopFor {
  50. continue
  51. }
  52. emailMessage, isRead, tmpErr := readEveryMsgV2(msg)
  53. if tmpErr != nil {
  54. continue
  55. }
  56. if !isRead {
  57. continue
  58. }
  59. // 记录邮件信息
  60. {
  61. outEmail, _ := obj.GetByEmailMessageIdAndFolder(emailMessage.Uid, emailMessage.Folder)
  62. if outEmail == nil || outEmail.EmailMessageUid <= 0 {
  63. outsideEmail := &report.OutsideEmailBaseInfo{
  64. Id: 0,
  65. Folder: emailMessage.Folder,
  66. EmailMessageUid: emailMessage.Uid,
  67. Title: emailMessage.Title,
  68. FromAddress: emailMessage.FromAddress,
  69. From: emailMessage.From,
  70. DeliveryTime: emailMessage.Date,
  71. CreateTime: time.Now(),
  72. }
  73. tmpErr := obj.Add(outsideEmail)
  74. if tmpErr != nil {
  75. fmt.Println("保存邮件基础信息失败:" + tmpErr.Error())
  76. }
  77. }
  78. }
  79. }
  80. if isStopFor {
  81. // 已经找到了最小的邮件id,那么就退出循环了
  82. }
  83. //time.Sleep(time.Second * 5) // 休眠10秒
  84. i = i - step
  85. }
  86. log.Println("读取了所有邮件,完毕!")
  87. return
  88. }
  89. // document link: https://github.com/emersion/go-imap/wiki/Fetching-messages
  90. func readEveryMsgV2(msg *imap.Message) (emailMessage MailMessage, ok bool, err error) {
  91. emailMessage = MailMessage{}
  92. message.CharsetReader = myCharsetReader
  93. emailMessage.Resources = make(map[string]string) // 内嵌资源
  94. emailMessage.Attachment = make(map[string]string) // 附件
  95. emailMessage.Uid = msg.Uid
  96. emailMessage.Folder = global.CONFIG.Email.Folder
  97. if IsHandleMessageIdMap != nil {
  98. if _, has := IsHandleMessageIdMap[int(emailMessage.Uid)]; has {
  99. fmt.Println("邮件已处理,邮件下标:", emailMessage.Uid)
  100. return
  101. }
  102. }
  103. //log.Printf("当前邮件的消息序列号 %+v \n", msg.SeqNum)
  104. //log.Println("-------------------------")
  105. // 获取邮件正文
  106. r := msg.GetBody(&imap.BodySectionName{})
  107. if r == nil {
  108. global.FILE_LOG.Info("服务器没有返回消息内容")
  109. }
  110. mr, err := mail.CreateReader(r)
  111. if err != nil {
  112. //log.Fatalf("邮件读取时出现错误: %v \n", err)
  113. err = errors.New(fmt.Sprintf("邮件读取时出现错误:%v \n", err))
  114. return
  115. }
  116. // 收件时间
  117. {
  118. date, err := mr.Header.Date()
  119. if err != nil {
  120. log.Println("收件时间 异常:", err.Error())
  121. }
  122. emailMessage.Date = date
  123. //log.Println("收件时间 Date:", date)
  124. }
  125. // 发件人
  126. {
  127. fromStr := mr.Header.Get("From")
  128. //fmt.Println(fromStr)
  129. // 处理无效地址的情况
  130. if !strings.Contains(fromStr, "@") {
  131. emailMessage.FromAddress = fromStr
  132. emailMessage.From = fromStr
  133. } else {
  134. from, tmpErr := mr.Header.AddressList("From")
  135. if tmpErr != nil {
  136. log.Println("发件人 异常:", err.Error())
  137. }
  138. if len(from) > 0 {
  139. emailMessage.FromAddress = from[0].Address
  140. emailMessage.From = from[0].Name
  141. //mailMessage.From = from[0].String()
  142. //log.Println("发件人 From:", from)
  143. }
  144. }
  145. }
  146. //if to, err := mr.Header.AddressList("To"); err == nil {
  147. // log.Println("收件人 To:", to)
  148. //}
  149. //log.Printf("抄送 Cc: %+v \n", msg.Envelope.Cc)
  150. // 邮件标题
  151. subject, err := mr.Header.Subject()
  152. if err != nil {
  153. log.Println("邮件主题 Subject ERR:", err)
  154. } else {
  155. //log.Println("邮件主题 Subject:", subject)
  156. }
  157. emailMessage.Title = subject
  158. // 过滤
  159. if isIgnore(emailMessage) {
  160. ok = false
  161. return
  162. }
  163. ok = true
  164. return
  165. }