使用go-imap v1无法读取邮箱全部邮件?问题求助
问题:使用go-imap v1仅获取到最新一封邮件,无法获取全部内容?
我尝试使用go-imap v1获取某指定发件人的全部邮件,但收件箱共有45封邮件,代码仅打印出最新的一封。
我的代码如下:
package main import ( "fmt" "log" "github.com/emersion/go-imap" "github.com/emersion/go-imap/client" "github.com/emersion/go-message/mail" ) func main() { ccc, err := client.DialTLS("imappro.zoho.com:993", nil) if err := ccc.Login("xxxxxxxxxx", "xxxxxxxxxx"); err != nil { fmt.Printf("Failed to login: %v", err) } else { fmt.Printf("Succesfully logged in...\n") } mbox, err := ccc.Select("INBOX", false) if err != nil { log.Fatal(err) } if mbox.Messages == 0 { log.Fatal("No message in mailbox") } else { fmt.Printf("Total message(s) in inbox: %d\n", mbox.Messages) } seqSet := new(imap.SeqSet) seqSet.AddNum(mbox.Messages) var section imap.BodySectionName items := []imap.FetchItem{section.FetchItem()} messages := make(chan *imap.Message, 1) go func() { if err := ccc.Fetch(seqSet, items, messages); err != nil { log.Fatal(err) } }() for elem := range messages { if elem == nil { log.Fatal("Server didn't returned message") } r := elem.GetBody(§ion) if r == nil { log.Fatal("Server didn't returned message body") } mr, err := mail.CreateReader(r) if err != nil { log.Fatal(err) } header := mr.Header if date, err := header.Date(); err == nil { log.Println("Date:", date) } if from, err := header.AddressList("From"); err == nil { log.Println("From:", from) } if to, err := header.AddressList("To"); err == nil { log.Println("To:", to) } if subject, err := header.Subject(); err == nil { log.Println("Subject:", subject) } } if err := ccc.Logout(); err != nil { fmt.Printf("Failed to logout: %v\n", err) } }
代码输出仅显示最新一封邮件的信息:
2023/09/11 17:22:33 Date: 2023-09-05 15:28:28 +0000 +0000 2023/09/11 17:22:33 From: ["xxxxx" <xxxxx@xxxxx.xxxx>] 2023/09/11 17:22:33 To: ["xxxxx@xxxxx.xxxxx" <xxxxx@xxxxx.xxxxx>] 2023/09/11 17:22:33 Subject: Yet another test
原因分析与解决方案
核心问题:仅指定了单封邮件的编号
代码中seqSet.AddNum(mbox.Messages)只向序列集合中添加了最后一封邮件的编号(也就是最新的那封),所以Fetch操作只会请求这一封邮件的数据。
解决步骤
获取全部邮件
将序列集合的添加逻辑改为覆盖所有邮件编号范围:seqSet := new(imap.SeqSet) // 添加从第1封到最后一封的所有邮件 seqSet.AddRange(1, mbox.Messages)针对指定发件人优化(推荐)
如果目标是获取指定发件人的邮件,直接获取全部邮件再过滤效率较低,建议先用Search功能筛选出符合条件的邮件ID,再进行Fetch:// 构建搜索条件,指定目标发件人 criteria := imap.NewSearchCriteria() criteria.Header.Add("From", "target_sender@example.com") // 执行搜索,得到符合条件的邮件UID uids, err := ccc.Search(criteria) if err != nil { log.Fatal(err) } if len(uids) == 0 { log.Fatal("No messages found from the specified sender") } // 将搜索到的UID添加到序列集合 seqSet := new(imap.SeqSet) seqSet.AddNum(uids...)其他细节优化
- 补充
DialTLS的错误处理,避免后续操作使用无效客户端:ccc, err := client.DialTLS("imappro.zoho.com:993", nil) if err != nil { log.Fatal(err) } // 使用defer确保程序退出时执行Logout,避免资源泄漏 defer func() { if err := ccc.Logout(); err != nil { fmt.Printf("Failed to logout: %v\n", err) } }() - 调整消息通道的缓冲大小,避免因通道阻塞导致的问题:
messages := make(chan *imap.Message, 10)
- 补充
修改后的完整代码(带指定发件人搜索)
package main import ( "fmt" "log" "github.com/emersion/go-imap" "github.com/emersion/go-imap/client" "github.com/emersion/go-message/mail" ) func main() { ccc, err := client.DialTLS("imappro.zoho.com:993", nil) if err != nil { log.Fatal(err) } defer func() { if err := ccc.Logout(); err != nil { fmt.Printf("Failed to logout: %v\n", err) } }() if err := ccc.Login("xxxxxxxxxx", "xxxxxxxxxx"); err != nil { fmt.Printf("Failed to login: %v", err) return } fmt.Printf("Successfully logged in...\n") mbox, err := ccc.Select("INBOX", false) if err != nil { log.Fatal(err) } if mbox.Messages == 0 { log.Fatal("No message in mailbox") } fmt.Printf("Total message(s) in inbox: %d\n", mbox.Messages) // 搜索指定发件人的邮件 targetSender := "target_sender@example.com" criteria := imap.NewSearchCriteria() criteria.Header.Add("From", targetSender) uids, err := ccc.Search(criteria) if err != nil { log.Fatal(err) } if len(uids) == 0 { log.Fatalf("No messages found from sender: %s", targetSender) } fmt.Printf("Found %d messages from %s\n", len(uids), targetSender) seqSet := new(imap.SeqSet) seqSet.AddNum(uids...) var section imap.BodySectionName items := []imap.FetchItem{section.FetchItem()} messages := make(chan *imap.Message, 10) go func() { if err := ccc.Fetch(seqSet, items, messages); err != nil { log.Fatal(err) } }() for elem := range messages { if elem == nil { log.Fatal("Server didn't return message") } r := elem.GetBody(§ion) if r == nil { log.Fatal("Server didn't return message body") } mr, err := mail.CreateReader(r) if err != nil { log.Fatal(err) } header := mr.Header if date, err := header.Date(); err == nil { log.Println("Date:", date) } if from, err := header.AddressList("From"); err == nil { log.Println("From:", from) } if to, err := header.AddressList("To"); err == nil { log.Println("To:", to) } if subject, err := header.Subject(); err == nil { log.Println("Subject:", subject) } } }
内容的提问来源于stack exchange,提问作者anta40
相关产品推荐
相关产品推荐

