/* 邮件发送操作包装,
暂支持邮件发送功能。
邮件内容若想模板化,请在应用程序中处理。
暂不支持附件 */ package mail import ( "bytes" "crypto/tls" "fmt" "log" "net" "net/smtp" "strings" ) const ( SPLIT = "\r\n" ) //邮箱认证信息 type MailAuth struct { SmtpHost string //邮箱服务器 SmtpPort int //邮箱端口 User string //用户 Pwd string //密码 } //邮件消息 type Message struct { Subject string //主题 From string //来自 To []string //接收人,可以是多个接收人 Body string //html邮件内容 } //发送邮件 func SendMail(auth *MailAuth, mes *Message) { go sendMailJob(auth, mes) } //发送邮件 func sendMailJob(auth *MailAuth, mes *Message) error { buf := bytes.NewBuffer(nil) buf.WriteString("Subject: " + mes.Subject + SPLIT) buf.WriteString("MIME-Version: 1.0" + SPLIT) buf.WriteString("From: " + mes.From + SPLIT) buf.WriteString("To: " + strings.Join(mes.To, ";") + SPLIT) buf.WriteString("Content-Type: " + "text/html; charset=UTF-8" + SPLIT) buf.WriteString(SPLIT + mes.Body) smtpauth := smtp.PlainAuth( "", auth.User, auth.Pwd, auth.SmtpHost, ) err := sendMailUsingTLS( fmt.Sprintf("%s:%d", auth.SmtpHost, auth.SmtpPort), smtpauth, auth.User, mes.To, buf.Bytes(), ) if err != nil { fmt.Println(err.Error()) } return err } func dial(addr string) (*smtp.Client, error) { config := &tls.Config{ServerName: addr, InsecureSkipVerify: true} conn, err := tls.Dial("tcp", addr, config) if err != nil { log.Println("Dialing Error:", err) return nil, err } //分解主机端口字符串 host, _, _ := net.SplitHostPort(addr) return smtp.NewClient(conn, host) } //安全协议发送邮件 func sendMailUsingTLS(addr string, auth smtp.Auth, from string, to []string, msg []byte) (err error) { //create smtp client c, err := dial(addr) if err != nil { log.Println("Create smpt client error:", err) return err } defer c.Close() if auth != nil { if ok, _ := c.Extension("AUTH"); ok { if err = c.Auth(auth); err != nil { log.Println("Error during AUTH", err) return err } } } if err = c.Mail(from); err != nil { return err } for _, addr := range to { if err = c.Rcpt(addr); err != nil { return err } } w, err := c.Data() if err != nil { return err } _, err = w.Write(msg) if err != nil { return err } err = w.Close() if err != nil { return err } return c.Quit() }