程序中時常有發送郵件的需求。有異常狀況了須要通知管理員和負責人,用戶下單後可能須要通知訂單信息,電商平臺、中國移動和聯通都有每個月帳單,這些均可以經過郵件來推送。還有咱們平時收到的垃圾郵件大都也是經過這種方式發送的😭。那麼如何在 Go 語言發送郵件?本文咱們介紹一下email
庫的使用。git
這個庫的使用快不了,爲何呢?github
先安裝庫,這個自沒必要說:golang
$ go get github.com/jordan-wright/email
複製代碼
咱們須要額外一些工做。咱們知道郵箱使用SMTP/POP3/IMAP
等協議從郵件服務器上拉取郵件。郵件並非直接發送到郵箱的,而是郵箱請求拉取的。 因此,咱們須要配置SMTP/POP3/IMAP
服務器。從頭搭建當然可行,並且也有現成的開源庫,可是比較麻煩。如今通常的郵箱服務商都開放了SMTP/POP3/IMAP
服務器。 我這裏拿 126 郵箱來舉例,使用SMTP
服務器。固然,用 QQ 郵箱也能夠。web
POP3/SMTP/IMAP
;IMAP/SMTP
服務,按照步驟開啓便可,有個密碼設置,記住這個密碼,後面有用。而後就能夠編碼了:安全
package main
import (
"log"
"net/smtp"
"github.com/jordan-wright/email"
)
func main() {
e := email.NewEmail()
e.From = "dj <xxx@126.com>"
e.To = []string{"935653229@qq.com"}
e.Subject = "Awesome web"
e.Text = []byte("Text Body is, of course, supported!")
err := e.Send("smtp.126.com:25", smtp.PlainAuth("", "xxx@126.com", "yyy", "smtp.126.com"))
if err != nil {
log.Fatal(err)
}
}
複製代碼
這裏爲了個人信息安全,我把真實信息都隱藏了。代碼中xxx
替換成你的郵箱帳號,yyy
替換成上面設置的密碼。服務器
代碼步驟比較簡單清晰:微信
NewEmail
建立一封郵件;From
發送方,To
接收者,Subject
郵件主題(標題),Text
設置郵件內容;Send
發送,參數1是 SMTP 服務器的地址,參數2爲驗證信息。運行程序將會向個人 QQ 郵箱發送一封郵件:網絡
有的郵箱會把這種郵件放在垃圾箱中,例如 QQ😭。若是收件箱找不到,記獲得垃圾箱瞅瞅。性能
日常咱們發郵件的時候可能會抄送給一些人,還有一些人要祕密抄送😄,即 CC(Carbon Copy)和 BCC (Blind Carbon Copy)。 email
咱們也能夠設置這兩個參數:學習
package main
import (
"log"
"net/smtp"
"github.com/jordan-wright/email"
)
func main() {
e := email.NewEmail()
e.From = "dj <xxx@126.com>"
e.To = []string{"935653229@qq.com"}
e.Cc = []string{"test1@126.com", "test2@126.com"}
e.Bcc = []string{"secret@126.com"}
e.Subject = "Awesome web"
e.Text = []byte("Text Body is, of course, supported!")
err := e.Send("smtp.126.com:25", smtp.PlainAuth("", "xxx@126.com", "yyy", "smtp.126.com"))
if err != nil {
log.Fatal(err)
}
}
複製代碼
仍是同樣的,抄送的郵箱本身替換test1/test2/secret
用本身的。
運行程序將會向個人 QQ 郵件發送一封郵件,同時抄送一封到我另外一個 126 郵箱:
發送純文本,郵件不太美觀。email
支持發送 HTML 格式的內容。與發送純文本相似,直接設置對象的HTML
字段:
package main
import (
"log"
"net/smtp"
"github.com/jordan-wright/email"
)
func main() {
e := email.NewEmail()
e.From = "dj <xxx@126.com>"
e.To = []string{"935653229@qq.com"}
e.Cc = []string{"xxx@126.com"}
e.Subject = "Go 每日一庫"
e.HTML = []byte(` <ul> <li><a "https://darjun.github.io/2020/01/10/godailylib/flag/">Go 每日一庫之 flag</a></li> <li><a "https://darjun.github.io/2020/01/10/godailylib/go-flags/">Go 每日一庫之 go-flags</a></li> <li><a "https://darjun.github.io/2020/01/14/godailylib/go-homedir/">Go 每日一庫之 go-homedir</a></li> <li><a "https://darjun.github.io/2020/01/15/godailylib/go-ini/">Go 每日一庫之 go-ini</a></li> <li><a "https://darjun.github.io/2020/01/17/godailylib/cobra/">Go 每日一庫之 cobra</a></li> <li><a "https://darjun.github.io/2020/01/18/godailylib/viper/">Go 每日一庫之 viper</a></li> <li><a "https://darjun.github.io/2020/01/19/godailylib/fsnotify/">Go 每日一庫之 fsnotify</a></li> <li><a "https://darjun.github.io/2020/01/20/godailylib/cast/">Go 每日一庫之 cast</a></li> </ul> `)
err := e.Send("smtp.126.com:25", smtp.PlainAuth("", "xxx@126.com", "yyy", "smtp.126.com"))
if err != nil {
log.Fatal("failed to send email:", err)
}
}
複製代碼
發送結果:
注意,126 的 SMTP 服務器檢測比較嚴格,加上 HTML 以後,很容易被識別爲垃圾郵件不讓發送,這時 CC 本身就 OK 了。
添加附件也很容易,直接調用AttachFile
便可:
package main
import (
"log"
"net/smtp"
"github.com/jordan-wright/email"
)
func main() {
e := email.NewEmail()
e.From = "dj <xxx@126.com>"
e.To = []string{"935653229@qq.com"}
e.Subject = "Go 每日一庫"
e.Text = []byte("請看附件")
e.AttachFile("test.txt")
err := e.Send("smtp.126.com:25", smtp.PlainAuth("", "xxx@126.com", "yyy", "smtp.126.com"))
if err != nil {
log.Fatal("failed to send email:", err)
}
}
複製代碼
收到的郵件:
實際上每次調用Send
時都會和 SMTP 服務器創建一次鏈接,若是發送郵件不少很頻繁的話可能會有性能問題。email
提供了鏈接池,能夠複用網絡鏈接:
package main
import (
"fmt"
"log"
"net/smtp"
"os"
"sync"
"time"
"github.com/jordan-wright/email"
)
func main() {
ch := make(chan *email.Email, 10)
p, err := email.NewPool(
"smtp.126.com:25",
4,
smtp.PlainAuth("", "leedarjun@126.com", "358942617ldj", "smtp.126.com"),
)
if err != nil {
log.Fatal("failed to create pool:", err)
}
var wg sync.WaitGroup
wg.Add(4)
for i := 0; i < 4; i++ {
go func() {
defer wg.Done()
for e := range ch {
err := p.Send(e, 10*time.Second)
if err != nil {
fmt.Fprintf(os.Stderr, "email:%v sent error:%v\n", e, err)
}
}
}()
}
for i := 0; i < 10; i++ {
e := email.NewEmail()
e.From = "dj <leedarjun@126.com>"
e.To = []string{"935653229@qq.com"}
e.Subject = "Awesome web"
e.Text = []byte(fmt.Sprintf("Awesome Web %d", i+1))
ch <- e
}
close(ch)
wg.Wait()
}
複製代碼
上面程序中,咱們建立 4 goroutine 共用一個鏈接池發送郵件,發送 10 封郵件後程序退出。爲了等郵件都發送完成或失敗,程序才退出,咱們使用了sync.WaitGroup
。
郵箱被轟炸了:
因爲使用了 goroutine,郵件順序不能保證。
本文介紹瞭如何使用 Go 程序發送郵件,程序代碼都已經放在 GitHub 上github.com/darjun/go-d…。全部代碼都經過測試,你們請放心食用~
你們若是發現好玩、好用的 Go 語言庫,歡迎到 Go 每日一庫 GitHub 上提交 issue😄
歡迎關注個人微信公衆號【GoUpUp】,共同窗習,一塊兒進步~
本文由博客一文多發平臺 OpenWrite 發佈!