mail.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. 邮件发送操作包装,<br/>
  3. 暂支持邮件发送功能。<br/>
  4. 邮件内容若想模板化,请在应用程序中处理。<br/>
  5. 暂不支持附件
  6. */
  7. package mail
  8. import (
  9. "bytes"
  10. "crypto/tls"
  11. "fmt"
  12. "log"
  13. "net"
  14. "net/smtp"
  15. "strings"
  16. )
  17. const (
  18. SPLIT = "\r\n"
  19. )
  20. //邮箱认证信息
  21. type MailAuth struct {
  22. SmtpHost string //邮箱服务器
  23. SmtpPort int //邮箱端口
  24. User string //用户
  25. Pwd string //密码
  26. }
  27. //邮件消息
  28. type Message struct {
  29. Subject string //主题
  30. From string //来自
  31. To []string //接收人,可以是多个接收人
  32. Body string //html邮件内容
  33. }
  34. //发送邮件
  35. func SendMail(auth *MailAuth, mes *Message) {
  36. go sendMailJob(auth, mes)
  37. }
  38. //发送邮件
  39. func sendMailJob(auth *MailAuth, mes *Message) error {
  40. buf := bytes.NewBuffer(nil)
  41. buf.WriteString("Subject: " + mes.Subject + SPLIT)
  42. buf.WriteString("MIME-Version: 1.0" + SPLIT)
  43. buf.WriteString("From: " + mes.From + SPLIT)
  44. buf.WriteString("To: " + strings.Join(mes.To, ";") + SPLIT)
  45. buf.WriteString("Content-Type: " + "text/html; charset=UTF-8" + SPLIT)
  46. buf.WriteString(SPLIT + mes.Body)
  47. smtpauth := smtp.PlainAuth(
  48. "",
  49. auth.User,
  50. auth.Pwd,
  51. auth.SmtpHost,
  52. )
  53. err := sendMailUsingTLS(
  54. fmt.Sprintf("%s:%d", auth.SmtpHost, auth.SmtpPort),
  55. smtpauth,
  56. auth.User,
  57. mes.To,
  58. buf.Bytes(),
  59. )
  60. if err != nil {
  61. fmt.Println(err.Error())
  62. }
  63. return err
  64. }
  65. func dial(addr string) (*smtp.Client, error) {
  66. config := &tls.Config{ServerName: addr, InsecureSkipVerify: true}
  67. conn, err := tls.Dial("tcp", addr, config)
  68. if err != nil {
  69. log.Println("Dialing Error:", err)
  70. return nil, err
  71. }
  72. //分解主机端口字符串
  73. host, _, _ := net.SplitHostPort(addr)
  74. return smtp.NewClient(conn, host)
  75. }
  76. //安全协议发送邮件
  77. func sendMailUsingTLS(addr string, auth smtp.Auth, from string,
  78. to []string, msg []byte) (err error) {
  79. //create smtp client
  80. c, err := dial(addr)
  81. if err != nil {
  82. log.Println("Create smpt client error:", err)
  83. return err
  84. }
  85. defer c.Close()
  86. if auth != nil {
  87. if ok, _ := c.Extension("AUTH"); ok {
  88. if err = c.Auth(auth); err != nil {
  89. log.Println("Error during AUTH", err)
  90. return err
  91. }
  92. }
  93. }
  94. if err = c.Mail(from); err != nil {
  95. return err
  96. }
  97. for _, addr := range to {
  98. if err = c.Rcpt(addr); err != nil {
  99. return err
  100. }
  101. }
  102. w, err := c.Data()
  103. if err != nil {
  104. return err
  105. }
  106. _, err = w.Write(msg)
  107. if err != nil {
  108. return err
  109. }
  110. err = w.Close()
  111. if err != nil {
  112. return err
  113. }
  114. return c.Quit()
  115. }