go 邮件功能(全)

邮件+模板

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     = "[email protected]"
	password = "xxxx"

	to   = []string{"[email protected]"}
	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"

go get gopkg.in/gomail.v2

func sendEmailByGmail() {
	m := gomail.NewMessage()
	m.SetHeader("From", from)
	m.SetHeader("To", to[0])
	//m.SetAddressHeader("Cc", "[email protected]", "Dan")
	m.SetHeader("Subject", "Hello!")
	m.SetBody("text", "test")
	//m.SetBody("text/html", "Hello Bob and Cora!")
	//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授权,比较麻烦但后期不需要再去处理这个问题。

你可能感兴趣的:(go,golang,开发语言,后端)