@@ -179,6 +179,51 @@ func displaySubject(subject string) string {
179179 return subject
180180}
181181
182+ func messageDateForFilter (msg * imap.Message ) time.Time {
183+ if msg == nil {
184+ return time.Time {}
185+ }
186+ if msg .Envelope != nil && ! msg .Envelope .Date .IsZero () {
187+ return msg .Envelope .Date
188+ }
189+ return msg .InternalDate
190+ }
191+
192+ func messageDateForStore (msg * imap.Message ) time.Time {
193+ if msg == nil || msg .Envelope == nil || msg .Envelope .Date .IsZero () {
194+ return time.Time {}
195+ }
196+ return msg .Envelope .Date
197+ }
198+
199+ func displayMessageDate (date time.Time ) string {
200+ if date .IsZero () {
201+ return "无发送时间"
202+ }
203+ utc8 := time .FixedZone ("UTC+8" , 8 * 60 * 60 )
204+ return date .In (utc8 ).Format ("2006-01-02 15:04:05" )
205+ }
206+
207+ func fetchFirstMessage (c * client.Client , seqSet * imap.SeqSet , items []imap.FetchItem ) (* imap.Message , error ) {
208+ messages := make (chan * imap.Message , 1 )
209+ fetchDone := make (chan error , 1 )
210+
211+ go func () {
212+ fetchDone <- c .UidFetch (seqSet , items , messages )
213+ }()
214+
215+ var msg * imap.Message
216+ for m := range messages {
217+ if msg == nil {
218+ msg = m
219+ }
220+ }
221+ if err := <- fetchDone ; err != nil {
222+ return nil , err
223+ }
224+ return msg , nil
225+ }
226+
182227func checkMailForAccount (account * EmailAccount ) {
183228 if ! account .Enabled {
184229 return
@@ -270,22 +315,8 @@ func checkFolderForAccount(account *EmailAccount, folder string) {
270315 seqSet := new (imap.SeqSet )
271316 seqSet .AddNum (uid )
272317
273- var section imap.BodySectionName
274- items := []imap.FetchItem {section .FetchItem (), imap .FetchEnvelope , imap .FetchInternalDate }
275- messages := make (chan * imap.Message , 1 )
276- fetchDone := make (chan error , 1 )
277-
278- go func () {
279- fetchDone <- c .UidFetch (seqSet , items , messages )
280- }()
281-
282- var msg * imap.Message
283- for m := range messages {
284- if msg == nil {
285- msg = m // 获取第一个拿去处理,剩下的强行消费完(防止 IMAP Server 返回多个对象导致 Channel 卡死 goroutine 泄露)
286- }
287- }
288- if fetchErr := <- fetchDone ; fetchErr != nil {
318+ msg , fetchErr := fetchFirstMessage (c , seqSet , []imap.FetchItem {imap .FetchEnvelope , imap .FetchInternalDate })
319+ if fetchErr != nil {
289320 addLog (fmt .Sprintf ("读取邮件失败 [%s/%s uid=%d]: %v" , account .Name , folder , uid , fetchErr ), "error" )
290321 continue
291322 }
@@ -294,13 +325,30 @@ func checkFolderForAccount(account *EmailAccount, folder string) {
294325 addLog (fmt .Sprintf ("读取邮件为空 [%s/%s uid=%d]" , account .Name , folder , uid ), "warning" )
295326 continue
296327 }
328+ filterDate := messageDateForFilter (msg )
329+ if filterDate .IsZero () || filterDate .Before (serviceStartedAt ) {
330+ addLog (fmt .Sprintf ("跳过历史邮件 [%s/%s uid=%d]: %s" , account .Name , folder , uid , displaySubject (msg .Envelope .Subject )), "info" )
331+ continue
332+ }
297333
298334 from := ""
299335 if len (msg .Envelope .From ) > 0 {
300336 from = msg .Envelope .From [0 ].Address ()
301337 }
302338
303- r := msg .GetBody (& section )
339+ var section imap.BodySectionName
340+ bodyMsg , fetchErr := fetchFirstMessage (c , seqSet , []imap.FetchItem {section .FetchItem ()})
341+ if fetchErr != nil {
342+ addLog (fmt .Sprintf ("读取邮件正文失败 [%s/%s uid=%d]: %v" , account .Name , folder , uid , fetchErr ), "error" )
343+ continue
344+ }
345+
346+ if bodyMsg == nil {
347+ addLog (fmt .Sprintf ("读取邮件正文为空 [%s/%s uid=%d]: %s" , account .Name , folder , uid , displaySubject (msg .Envelope .Subject )), "warning" )
348+ continue
349+ }
350+
351+ r := bodyMsg .GetBody (& section )
304352 if r == nil {
305353 addLog (fmt .Sprintf ("邮件正文为空 [%s/%s uid=%d]: %s" , account .Name , folder , uid , displaySubject (msg .Envelope .Subject )), "warning" )
306354 continue
@@ -342,7 +390,7 @@ func checkFolderForAccount(account *EmailAccount, folder string) {
342390 Subject : msg .Envelope .Subject ,
343391 From : from ,
344392 To : account .EmailUser ,
345- Date : msg . Envelope . Date ,
393+ Date : messageDateForStore ( msg ) ,
346394 Body : body ,
347395 BodyHTML : bodyHTML ,
348396 Status : "pending" ,
0 commit comments