在使用Go語言開發(fā)時(shí)鹿响,我們會(huì)遇到發(fā)送郵件的需求,在Go語言標(biāo)準(zhǔn)包中傻唾,也提供了郵件發(fā)送客戶端smtp
的封裝投慈。不過,該標(biāo)準(zhǔn)包只提供了基礎(chǔ)的郵件發(fā)送過程冠骄,對(duì)于一些復(fù)雜的定義還需要自己去封裝伪煤,封裝過程就需要依據(jù)郵件協(xié)議RFC2822了。還好凛辣,github上有人專門為我們封裝好了這個(gè)包:https://github.com/go-gomail/gomail抱既。這個(gè)包封裝了發(fā)送附件、圖片扁誓、HTML內(nèi)容模板防泵、SSL和TLS等的支持,可以滿足我們的大部分應(yīng)用場景蝗敢。下面捷泞,我就對(duì)gomail
實(shí)現(xiàn)發(fā)送郵件做一下簡單介紹。
1. 需要先安裝gomail
包
$ go get -v gopkg.in/gomail.v2
2. 導(dǎo)入gomail
包
$ import "gopkg.in/gomail.v2"
3. 需要?jiǎng)?chuàng)建一個(gè)Message
實(shí)例寿谴,Message
提供了整個(gè)郵件協(xié)議內(nèi)容的構(gòu)建锁右,默認(rèn)實(shí)例采用UTF-8
字符集和Quoted-printable
編碼。
對(duì)于
Quoted-printable
編碼的定義,維基百科上是這樣說的:Quoted-printable是使用可打印的ASCII字符(如字母骡湖、數(shù)字與“=”)表示各種編碼格式下的字符贱纠,以便能在7-bit數(shù)據(jù)通路上傳輸8-bit數(shù)據(jù), 或者更一般地說在非8-bit clean媒體上正確處理數(shù)峻厚。
m := gomail.NewMessage()
4. 構(gòu)造郵件內(nèi)容响蕴,包括:發(fā)件人信息、收件人惠桃、主題浦夷、內(nèi)容,更多內(nèi)容設(shè)定可參考協(xié)議:RFC2822
// 發(fā)件人信息
m.SetHeader("From", m.FormatAddress("user@example.com", "張三"))
// 收件人
m.SetHeader("To", "user@qq.com")
// 主題
m.SetHeader("Subject", "郵件標(biāo)題")
// 內(nèi)容
m.SetBody("text/html", "系統(tǒng)郵件請(qǐng)勿回復(fù)")
特殊說明辜王,構(gòu)造
From(發(fā)件人信息)
時(shí)需要使用m.FormatAddress
方法劈狐,因?yàn)榘l(fā)件人指定中文名或特殊字符時(shí),需要進(jìn)行編碼
5. 構(gòu)造附件信息呐馆,同時(shí)對(duì)附件進(jìn)行重命名
比如肥缔,我有一個(gè)臨時(shí)文件:
/tmp/foo.txt
,我需要將這個(gè)文件以郵件附件的方式進(jìn)行發(fā)送汹来,同時(shí)指定附件名為:附件.txt
name := "附件.txt"
m.Attach("/tmp/foo.txt",
gomail.Rename(name),
)
6. 創(chuàng)建SMTP
客戶端续膳,連接到遠(yuǎn)程的郵件服務(wù)器,需要指定服務(wù)器地址收班、端口號(hào)坟岔、用戶名源梭、密碼来庭,如果端口號(hào)為465
的話,自動(dòng)開啟SSL燃箭,這個(gè)時(shí)候需要指定TLSConfig
這里的用戶名和密碼指的是能夠登錄該郵箱的郵箱地址和密碼
d := gomail.NewDialer("smtp.example.com", 465, "user@example.com", "password")
d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
7. 執(zhí)行郵件發(fā)送
err := d.DialAndSend(m)
if err != nil {
// 處理錯(cuò)誤
}
至此邻耕,郵件已經(jīng)發(fā)送成功了鸥咖,整個(gè)郵件的內(nèi)容為(其中,附件內(nèi)容為foo.bar
):
Mime-Version: 1.0
Date: Sat, 10 Nov 2018 21:40:13 +0800
From: =?UTF-8?q?=E5=BC=A0=E4=B8=89?= <user@example.com>
To: user@qq.com
Subject: =?UTF-8?q?=E9=82=AE=E4=BB=B6=E6=A0=87=E9=A2=98?=
Content-Type: multipart/mixed;
boundary=92142f9522a20d2f4feffce957bf68b46ad1a620e68fbecbf35669266e9a
--92142f9522a20d2f4feffce957bf68b46ad1a620e68fbecbf35669266e9a
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
=E7=B3=BB=E7=BB=9F=E9=82=AE=E4=BB=B6=E8=AF=B7=E5=8B=BF=E5=9B=9E=E5=A4=8D
--92142f9522a20d2f4feffce957bf68b46ad1a620e68fbecbf35669266e9a
Content-Disposition: attachment; filename="附件.txt"
Content-Transfer-Encoding: base64
Content-Type: text/plain; charset=utf-8; name="附件.txt"
Zm9vLmJhcgo=
--92142f9522a20d2f4feffce957bf68b46ad1a620e68fbecbf35669266e9a--
打印郵件內(nèi)容兄世,可以將
Message
寫入到一個(gè)緩沖區(qū)中啼辣,代碼如下:
buf := new(bytes.Buffer)
m.WriteTo(buf)
fmt.Println(buf.String())
解決gomail v2.0.0
版本下中文附件名亂碼的問題
在不同的郵件服務(wù)器中,對(duì)于中文附件名的編碼存在不同的規(guī)范碘饼,我們可以嘗試一下熙兔,將上面的郵件附件發(fā)送到QQ郵箱,附件名顯示正常艾恼,發(fā)送到126的郵箱就是亂碼(這是我測試的結(jié)果)住涉。對(duì)此,我們可以通過給附件名進(jìn)行編碼的方式來解決這個(gè)問題钠绍。
name := "附件.txt"
m.Attach("/tmp/foo.txt",
gomail.Rename(name),
gomail.SetHeader(map[string][]string{
"Content-Disposition": []string{
fmt.Sprintf(`attachment; filename="%s"`, mime.QEncoding.Encode("UTF-8", name)),
},
}),
)
將郵件內(nèi)容更改為Base64
編碼
m := gomail.NewMessage(
gomail.SetEncoding(gomail.Base64),
)
// ...
name := "附件.txt"
m.Attach("/tmp/foo.txt",
gomail.Rename(name),
gomail.SetHeader(map[string][]string{
"Content-Disposition": []string{
fmt.Sprintf(`attachment; filename="%s"`, mime.BEncoding.Encode("UTF-8", name)),
},
}),
)
使用
Base64
編碼后的郵件內(nèi)容為:
Mime-Version: 1.0
Date: Sat, 10 Nov 2018 21:53:22 +0800
From: =?UTF-8?b?5byg5LiJ?= <user@example.com>
To: user@qq.com
Subject: =?UTF-8?b?6YKu5Lu25qCH6aKY?=
Content-Type: multipart/mixed;
boundary=42839966777f27ebe3861a73eabbf615036ea57b3222968e21519c64cdd5
--42839966777f27ebe3861a73eabbf615036ea57b3222968e21519c64cdd5
Content-Transfer-Encoding: base64
Content-Type: text/html; charset=UTF-8
57O757uf6YKu5Lu26K+35Yu/5Zue5aSN
--42839966777f27ebe3861a73eabbf615036ea57b3222968e21519c64cdd5
Content-Disposition: attachment; filename="=?UTF-8?b?6ZmE5Lu2LnR4dA==?="
Content-Transfer-Encoding: base64
Content-Type: text/plain; charset=utf-8; name="附件.txt"
Zm9vLmJhcgo=
--42839966777f27ebe3861a73eabbf615036ea57b3222968e21519c64cdd5--