go-imap包体使用指南
前言:
- 需要分析邮件基本信息
- 解析邮件正文
- 下载附件文件
使用方式
- 导入包体:
1
2
3
4
5
6
7
8
9import (
"github.com/emersion/go-imap"
"github.com/emersion/go-imap/client"
_ "github.com/emersion/go-message/charset"
"github.com/emersion/go-message/mail"
"io"
"log"
"os"
) - 连接服务器,登录服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17log.Println("Connecting to server...")
//连接到服务器
c, err := client.DialTLS("imap.feishu.cn:993", nil)
if err != nil {
log.Fatal(err)
}
log.Println("Connected")
// 最后不要忘记登出
defer c.Logout()
// 登录服务器
if err := c.Login("[email protected]", "00Bg9ve0yYEYrTJW"); err != nil {
log.Fatal(err)
}
log.Println("Logged in") - 使用Search 方法去查找对应条件的邮件
- 查找未读的邮箱为:
&imap.SearchCriteria{Not: []*imap.SearchCriteria{{WithFlags: []string{imap.SeenFlag}}}}
1
2
3
4
5
6
7
8
9
10// 获取所有的邮箱文件夹
mailboxes := make(chan *imap.MailboxInfo, 10)
done := make(chan error, 1)
go func() {
done <- c.List("", "*", mailboxes)
}()
if err := <-done; err != nil {
log.Fatal(err)
} - 返回的是查找到对应的Uid区间,需要遍历才可以找出对应的邮件。
- 读取邮件内容需要配合
github.com/emersion/go-message/mail
库进行1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99//选择对应的文件夹
log.Println("* " + m.Name)
mbox, err := c.Select(m.Name, false)
if err != nil {
log.Fatal(err)
}
log.Println("Flags for INBOX:", mbox.Flags)
//获取文件夹中的未读邮件
searchSeq, err := c.Search(&imap.SearchCriteria{Not: []*imap.SearchCriteria{{WithFlags: []string{imap.SeenFlag}}}})
if err != nil {
log.Printf("Error occured while searching: %s\n", err)
return
}
if len(searchSeq) != 0 {
log.Println("search:", searchSeq)
//遍历未读取的邮件
for _, u := range searchSeq {
seqSet := new(imap.SeqSet)
seqSet.AddRange(u, u)
// Get the whole message body
var section imap.BodySectionName
items := []imap.FetchItem{section.FetchItem()}
//读取邮件内容
messages := make(chan *imap.Message, 1)
go func() {
if err := c.Fetch(seqSet, items, messages); err != nil {
log.Fatal(err)
}
}()
msg := <-messages
if msg == nil {
log.Fatal("Server didn't returned message")
}
r := msg.GetBody(§ion)
if r == nil {
log.Fatal("Server didn't returned message body")
}
// Create a new mail reader
mr, err := mail.CreateReader(r)
if err != nil {
log.Fatal(err)
}
// Print some info about the message
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)
}
// 从mr中读取邮件信息
for {
//读取邮件内容
p, err := mr.NextPart()
if err == io.EOF {
break
} else if err != nil {
log.Fatal(err)
}
mailDate, errs := header.Date()
if errs == nil {
log.Println("Date:", mailDate.Format("01-02-2006"))
}
switch h := p.Header.(type) {
case *mail.InlineHeader:
//获取邮件的主体信息(可能是纯文本也可能是html)
b, _ := io.ReadAll(p.Body)
log.Printf("Got text: %v", string(b))
case *mail.AttachmentHeader:
//获取邮件的附件
filename, _ := h.Filename()
log.Printf("Got attachment: %v \n", filename)
dir := mkDir(mailDate.Format("01-02-2006"))
filename = dir + "/" + filename
content, _ := io.ReadAll(p.Body)
writeToFile(filename, string(content))
}
}
//标记邮件为已读
flags := []interface{}{imap.SeenFlag}
if err := c.Store(seqSet, imap.AddFlags, flags, nil); err != nil {
log.Fatal(err)
}
}
}
}
坑:
- 别用V2
- Collect() 不适用于附件提取
引用
go-imap包体使用指南
https://blog.codefish.net/2023/07/13/package-demo-GoPackage-go-imap包体使用指南/