email.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package utils
  2. import (
  3. "crypto/tls"
  4. "fmt"
  5. "net/smtp"
  6. "strings"
  7. "github.com/flipped-aurora/gin-vue-admin/server/plugin/email/global"
  8. "github.com/jordan-wright/email"
  9. )
  10. //@author: [maplepie](https://github.com/maplepie)
  11. //@function: Email
  12. //@description: Email发送方法
  13. //@param: subject string, body string
  14. //@return: error
  15. func Email(To, subject string, body string) error {
  16. to := strings.Split(To, ",")
  17. return send(to, subject, body)
  18. }
  19. //@author: [SliverHorn](https://github.com/SliverHorn)
  20. //@function: ErrorToEmail
  21. //@description: 给email中间件错误发送邮件到指定邮箱
  22. //@param: subject string, body string
  23. //@return: error
  24. func ErrorToEmail(subject string, body string) error {
  25. to := strings.Split(global.GlobalConfig.To, ",")
  26. if to[len(to)-1] == "" { // 判断切片的最后一个元素是否为空,为空则移除
  27. to = to[:len(to)-1]
  28. }
  29. return send(to, subject, body)
  30. }
  31. //@author: [maplepie](https://github.com/maplepie)
  32. //@function: EmailTest
  33. //@description: Email测试方法
  34. //@param: subject string, body string
  35. //@return: error
  36. func EmailTest(subject string, body string) error {
  37. to := []string{global.GlobalConfig.To}
  38. return send(to, subject, body)
  39. }
  40. //@author: [maplepie](https://github.com/maplepie)
  41. //@function: send
  42. //@description: Email发送方法
  43. //@param: subject string, body string
  44. //@return: error
  45. func send(to []string, subject string, body string) error {
  46. from := global.GlobalConfig.From
  47. nickname := global.GlobalConfig.Nickname
  48. secret := global.GlobalConfig.Secret
  49. host := global.GlobalConfig.Host
  50. port := global.GlobalConfig.Port
  51. isSSL := global.GlobalConfig.IsSSL
  52. isLoginAuth := global.GlobalConfig.IsLoginAuth
  53. var auth smtp.Auth
  54. if isLoginAuth {
  55. auth = LoginAuth(from, secret)
  56. } else {
  57. auth = smtp.PlainAuth("", from, secret, host)
  58. }
  59. e := email.NewEmail()
  60. if nickname != "" {
  61. e.From = fmt.Sprintf("%s <%s>", nickname, from)
  62. } else {
  63. e.From = from
  64. }
  65. e.To = to
  66. e.Subject = subject
  67. e.HTML = []byte(body)
  68. var err error
  69. hostAddr := fmt.Sprintf("%s:%d", host, port)
  70. if isSSL {
  71. err = e.SendWithTLS(hostAddr, auth, &tls.Config{ServerName: host})
  72. } else {
  73. err = e.Send(hostAddr, auth)
  74. }
  75. return err
  76. }
  77. // LoginAuth 用于IBM、微软邮箱服务器的LOGIN认证方式
  78. type loginAuth struct {
  79. username, password string
  80. }
  81. func LoginAuth(username, password string) smtp.Auth {
  82. return &loginAuth{username, password}
  83. }
  84. func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
  85. return "LOGIN", []byte{}, nil
  86. }
  87. func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
  88. if more {
  89. switch string(fromServer) {
  90. case "Username:":
  91. return []byte(a.username), nil
  92. case "Password:":
  93. return []byte(a.password), nil
  94. default:
  95. // 邮箱服务器可能发送的其他提示信息
  96. prompt := strings.ToLower(string(fromServer))
  97. if strings.Contains(prompt, "username") || strings.Contains(prompt, "user") {
  98. return []byte(a.username), nil
  99. }
  100. if strings.Contains(prompt, "password") || strings.Contains(prompt, "pass") {
  101. return []byte(a.password), nil
  102. }
  103. }
  104. }
  105. return nil, nil
  106. }