golang封装一个发送邮件的代码
golang发送邮件非常简单,下面是一个封装好的代码,只需要把这两个文件放到一个包里,就可以直接使用
email.go
package email
import (
"context"
"github.com/go-playground/validator/v10"
"github.com/pkg/errors"
)
type Client interface {
// Send 发送邮件
Send(ctx context.Context, opt *SendOpt) error
}
type SendOpt struct {
From string `validate:"required"` // 发件人
To []string `validate:"required"` // 收件人 多个
Cc []string // 抄送
Bcc []string // 密送
Subject string `validate:"required"` // 主题
Body string `validate:"required"` // 内容
AttachName string // 附件名称 为空则取附件地址名称
AttachUrl string // 附件地址
}
func (p *SendOpt) Valid() error {
if err := validator.New().Struct(p); err != nil {
return errors.WithStack(err)
}
return nil
}
impl.go
package email
import (
"context"
"fmt"
"gopkg.in/gomail.v2"
"io"
"io/ioutil"
"net/http"
"path"
)
type ClientImpl struct {
EmailClient *gomail.Dialer
}
type ClientOpt struct {
Host string
Port int
UserName string
Pwd string
}
func NewClient(opt *ClientOpt) Client {
return &ClientImpl{
EmailClient: gomail.NewDialer(opt.Host, opt.Port, opt.UserName, opt.Pwd),
}
}
func (p *ClientImpl) Send(_ context.Context, opt *SendOpt) error {
if err := opt.Valid(); err != nil {
return err
}
m := gomail.NewMessage()
m.SetHeader("From", opt.From)
m.SetHeader("To", opt.To...) //主送
if len(opt.Cc) > 0 {
m.SetHeader("Cc", opt.Cc...) //抄送
}
if len(opt.Bcc) > 0 {
m.SetHeader("Bcc", opt.Bcc...) // 密送
}
m.SetHeader("Subject", opt.Subject)
//发送html格式邮件。
m.SetBody("text/html", opt.Body)
//添加附件
if err := p.attach(opt, m); err != nil {
return err
}
return p.EmailClient.DialAndSend(m)
}
func (p *ClientImpl) attach(opt *SendOpt, m *gomail.Message) error {
if opt.AttachUrl != "" {
if opt.AttachName != "" {
if fileType := path.Ext(opt.AttachName); fileType == "" {
fileType = path.Ext(opt.AttachUrl)
opt.AttachName = fmt.Sprintf("%s%s", opt.AttachName, fileType)
}
} else {
opt.AttachName = opt.AttachUrl
}
m.Attach(opt.AttachName, gomail.SetCopyFunc(func(w io.Writer) error {
// 读取oss文件内容
resp, err := http.Get(opt.AttachUrl)
if err != nil {
return err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
_, err = w.Write(body)
return err
}))
}
return nil
}
调用代码
func EmailClient() email.Client {
return email.NewClient(
&email.ClientOpt{
Host: "smtp.exmail.qq.com",
Port: 465,
UserName: "",
Pwd: "",
},
)
}
这样,一个发送邮件的工具包就封装好了