golang封装一个发送邮件的代码
golang发送邮件非常简单,下面是一个封装好的代码,只需要把这两个文件放到一个包里,就可以直接使用
email.go
package emailimport ("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 emailimport ("context""fmt""gopkg.in/gomail.v2""io""io/ioutil""net/http""path"
)type ClientImpl struct {EmailClient *gomail.Dialer
}type ClientOpt struct {Host stringPort intUserName stringPwd 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: "",},)
}
这样,一个发送邮件的工具包就封装好了