简介:
电子邮件的应用非常广泛,常见在某网站注册一个账号,自动发送一封激活邮件,通过邮件找回密码,自动批量发送活动信息等等。这些应用不可能与平时发邮件一样,先打开浏览器,登录邮箱在发送。
如何通过Go语言代码来创建电子邮件,并连接邮件服务器发送邮件?
电子邮件在网络中传输和网页一样需要遵守特定的协议。常见的电子邮件协议包括:SMTP,POP3,LMAP。其中邮件的创建和发送只需要用到SMTP协议,本文只会涉及到SMTP协议。SMTP是Simple Mail Transfer Protocol 简称,即简单邮件传输协议。
安装
go get github.com/jordan-wright/email
需要额外一些工作。邮箱使用SMTP/POP3/IMAP等协议从邮件服务器上拉取邮件。邮件并不是直接发送到邮箱的,而是邮箱请求拉取的。
所以,需要配置SMTP/POP3/IMAP服务器。从头搭建固然可行,而且也有现成的开源库,但是比较麻烦。现在一般的邮箱服务商都开放了SMTP/POP3/IMAP服务器。这里拿 QQ 邮箱来举例。
- 首先我们登录QQ邮箱,设置->账户 找到图片的位置开启
POP3/SMTP/IMAP
并且按照要求生产授权码
代码
1、实现简单的邮件发送:
package main
import (
"log"
"net/smtp"
"sync"
"github.com/jordan-wright/email"
)
func main() {
//创建一个电子邮件
e := email.NewEmail()
//设置发送方邮件
e.From = "xxxx@qq.com"
//设置接收方得邮件
e.To = []string{"xxxx@qq.com"}
//设置主题
e.Subject = "中国"
//设置文件发送内容
e.Text = []byte("北京是个好地方")
//设置服务器相关的配置
err := e.Send("smtp.qq.com:25", smtp.PlainAuth("", "xxxx@qq.com", "你的授权码", "smtp.qq.com"))
if err != nil {
log.Fatal(err)
}
}
运行程序就会给你设置的邮箱发送一个邮件,有的邮箱会把邮件当成垃圾邮件发到垃圾箱里面,如果找不到邮件可以去垃圾箱看下。
2、实现抄送功能
该插件有两种抄送模式即 CC(Carbon Copy)和 BCC (Blind Carbon Copy);抄送功能只需要添加两个参数就好了
//设置抄送
e.Cc = []string{"xxxx@qq.com"} //如果抄送给多人,逗号隔开
//设置秘密抄送
e.Bcc = []string{"xxxx@qq.com"} //如果抄送给多人,逗号隔开
3.实现发送HTML代码的邮件
e.HTML = []byte(`
<h1><a href="http://www.baidu.com/">百度一下</a></h1>
`)
4.实现邮件附件发送
e.AttachFile("./test.txt")
连接池
package main
import (
"fmt"
"log"
"net/smtp"
"os"
"sync"
"time"
"github.com/jordan-wright/email"
)
func main() {
cp := make(chan *email.Email, 10)
p, err := email.NewPool(
"smtp.qq.com:25",
3,
smtp.PlainAuth("", "xxxx@qq.com", "你的授权码", "smtp.qq.com"),
)
if err != nil {
log.Fatal("failed to create pool:", err)
}
var wg sync.WaitGroup
wg.Add(3)
for i := 0; i < 4; i++ {
go func() {
defer wg.Done()
for e := range cp {
err := p.Send(e, 10*time.Second)
if err != nil {
fmt.Fprintf(os.Stderr, "email:%v send err:%v
", e, err)
}
}
}()
}
for i := 0; i < 10; i++ {
e := email.NewEmail()
e.From = "xxxx@qq.com"
e.To = []string{"xxxx@qq.com"}
e.Subject = "中国"
e.Text = []byte(fmt.Sprintf("Awesome Place %d", i+1))
cp <- e
}
close(cp)
wg.Wait()
}
创建 3 goroutine 共用一个连接池发送邮件,发送 10 封邮件后程序退出。
为了等邮件都发送完成或失败,程序才退出,使用了sync.WaitGroup。由于使用 goroutine 邮件顺序无法保证。