• 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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    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}}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    footer.html

    {{define "footer"}}
    <div>
        <p>此邮箱为系统邮箱,请勿回复。p>
    div>
    body>
    html>
    {{end}}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    sys.html

    {{ template "header" }}
    <div style="padding: 8px 40px 8px 50px;">
        <p>您的系统发生了错误,错误原因如下:p>
        <p>{{.Error}}p>
    div>
    {{ template "footer" }}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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" }}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    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
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    发邮件的三种方式

    头部公共

    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)
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    原生

    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
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    使用包"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)
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    使用包"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", "xx@example.com", "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)
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    比较三种方式

    • 速度:原生最快
    • 适用:qq,163,gmail都适应。
    • office365,个人账号
      • gomail:适用
      • jordan-wright/email:无法发送(但我使用gomail和python都可以发送成功,所以是这个包的问题,或者我没使用正确的打开方式?)
    • office365,组织账号,需要申请开通。有两种方式:第一种是开通二次登录(同gmail)然后启用授权码(据说后期不推荐,但由于一些老旧的设备比如打印机无法使用auth2验证,所以一直还是拖着保留这种方式),第二种是office的admin后台开通后使用auth2授权,比较麻烦但后期不需要再去处理这个问题。
  • 相关阅读:
    【MySQL】sql语句之库操作
    JAVA优先级队列详解
    php 校园oa办公系统xammp
    电脑开机就一直自动修复,固态硬盘突然变成RAW格式,怎么数据恢复(未解决)
    【剑指Offer】11-15题(二分+DFS+BFS+DP+简单位运算)
    VMware vCenter Server 7 升级
    MySQL 流程控制
    HP服务器Smart Storage Administrator 配置阵列
    网络安全(黑客)——2024自学
    ROS学习笔记(19):建图与定位(3)
  • 原文地址:https://blog.csdn.net/junjiahuang/article/details/132803962