邮件+模板
pkg/email/email.go
type SenderOptions struct {
UserName string
PassWord string
Host string
Port string
MailFrom string
}
type Sender struct {
options SenderOptions
e *gomail.Message
}
func NewSender(opt SenderOptions) *Sender {
e := gomail.NewMessage()
e.SetHeader("From", opt.MailFrom)
return &Sender{
options: opt,
e: e,
}
}
func (a *Sender) SetHTML(html string) {
a.e.SetBody("text/html", html)
}
func (a *Sender) SetReceivers(receivers []string) {
a.e.SetHeader("To", receivers...)
}
func (a *Sender) SendEmail(ctx context.Context, subject string) error {
m := a.e
o := a.options
m.SetHeader("Subject", subject)
port, _ := strconv.Atoi(o.Port)
d := gomail.NewDialer(o.Host, port, o.UserName, o.PassWord)
if err := d.DialAndSend(m); err != nil {
return err
}
fmt.Println("send email successful!")
return nil
}
internal/app/email/templates
header.html
{{define "header"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>系统邮件</title>
</head>
<body>
<div>
尊敬的用户,您好!
</div>
{{end}}
footer.html
{{define "footer"}}
<div>
<p>此邮箱为系统邮箱,请勿回复。</p>
</div>
</body>
</html>
{{end}}
sys.html
{{ template "header" }}
<div style="padding: 8px 40px 8px 50px;">
<p>您的系统发生了错误,错误原因如下:</p>
<p>{{.Error}}</p>
</div>
{{ template "footer" }}
verify.html
{{ template "header" }}
<div style="padding: 8px 40px 8px 50px;">
<p>你本次的验证码为<u>{{.VerifyCode}}</u>,为了保证账号安全,验证码有效期为<span style="color:red">{{.Expired}}</span>。请确认为本人操作,切勿向他人泄露,感谢您的理解与使用。</p>
</div>
{{ template "footer" }}
internal/app/email/email.go
package email
import (
"bytes"
"fmt"
"html/template"
"os"
"path/filepath"
)
type SysError struct {
Error string
}
type Verify struct {
VerifyCode string
Expired string
}
const (
SysTemplateName = "sys"
VerifyTemplateName = "verify"
)
func GetTemplate(templateName string, content interface{}) (string, error) {
wd, err := os.Getwd()
dir := filepath.Join(wd, "/internal/app/email/templates")
if err != nil {
return "", err
}
templates := []string{
fmt.Sprintf("%s/%s.html", dir, templateName),
fmt.Sprintf("%s/header.html", dir),
fmt.Sprintf("%s/footer.html", dir),
}
t, err := template.ParseFiles(templates...)
if err != nil {
return "", err
}
body := new(bytes.Buffer)
err = t.Execute(body, content)
if err != nil {
return "", err
}
return body.String(), nil
}
发邮件的三种方式
头部公共
var (
host = "smtp.qq.com"
port = 587
from = "xxx@qq.com"
password = "xxxx"
to = []string{"xxx@163.com"}
msg = []byte("This is my message")
addr = fmt.Sprintf("%s:%d", host, port)
auth = smtp.PlainAuth("", from, password, host)
)
原生
func sendToEmailOrigin(user, pwd, host, to, subject, body, mailtype string) error {
hp := strings.Split(host, ":")
auth := smtp.PlainAuth("", user, pwd, hp[0])
var content_type string
if mailtype == "html" {
content_type = "Content-Type: text/" + mailtype + "; charset=UTF-8"
} else {
content_type = "Content-Type: text/plain" + "; charset=UTF-8"
}
msg := []byte("To: " + to + "\r\nFrom: " + user + "\r\nSubject: " + subject + "\r\n" + content_type + "\r\n\r\n" + body)
send_to := strings.Split(to, ";")
err := smtp.SendMail(host, auth, user, send_to, msg)
return err
}
使用包"github.com/jordan-wright/email"
go get github.com/jordan-wright/email
func sendEmailStartTLS() {
e := email.NewEmail()
e.From = from
e.To = to
e.Subject = "test"
e.Text = msg
err := e.SendWithStartTLS(addr, auth, &tls.Config{InsecureSkipVerify: true, ServerName: host})
if err != nil {
fmt.Println(err)
}
}
使用包"gopkg.in/gomail.v2"
文章来源:https://uudwc.com/A/y5wmW
go get gopkg.in/gomail.v2文章来源地址https://uudwc.com/A/y5wmW
func sendEmailByGmail() {
m := gomail.NewMessage()
m.SetHeader("From", from)
m.SetHeader("To", to[0])
//m.SetAddressHeader("Cc", "xx@example.com", "Dan")
m.SetHeader("Subject", "Hello!")
m.SetBody("text", "test")
//m.SetBody("text/html", "Hello <b>Bob</b> and <i>Cora</i>!")
//m.Attach("/home/Alex/lolcat.jpg")
d := gomail.NewDialer(host, port, from, password)
if err := d.DialAndSend(m); err != nil {
panic(err)
}
}
比较三种方式
- 速度:原生最快
- 适用:qq,163,gmail都适应。
- office365,个人账号
- gomail:适用
- jordan-wright/email:无法发送(但我使用gomail和python都可以发送成功,所以是这个包的问题,或者我没使用正确的打开方式?)
- office365,组织账号,需要申请开通。有两种方式:第一种是开通二次登录(同gmail)然后启用授权码(据说后期不推荐,但由于一些老旧的设备比如打印机无法使用auth2验证,所以一直还是拖着保留这种方式),第二种是office的admin后台开通后使用auth2授权,比较麻烦但后期不需要再去处理这个问题。