email.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package services
  2. import (
  3. "crypto/tls"
  4. "eta/eta_api/models"
  5. "eta/eta_api/utils"
  6. "fmt"
  7. "strconv"
  8. "strings"
  9. "gopkg.in/gomail.v2"
  10. )
  11. func SendEmailToCompany() {
  12. // 获取收件人列表
  13. emailCond := " AND enabled = 1 AND status in (1,2) "
  14. //emailCond += ` AND email IN ('qychen@hzinsights.com','hsji@hzinsights.com') `
  15. //emailCond := ""
  16. emailPars := make([]interface{}, 0)
  17. emails, e := models.GetEnglishReportEmailList(emailCond, emailPars, "")
  18. if e != nil {
  19. fmt.Println("获取收件人列表失败, Err: " + e.Error())
  20. return
  21. }
  22. if len(emails) == 0 {
  23. fmt.Println("收件人列表为空")
  24. return
  25. }
  26. // TODO:这是HTML模板内容
  27. template := `<!DOCTYPE html>
  28. <html lang="en">
  29. <head>
  30. <meta charset="UTF-8" />
  31. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  32. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  33. <title>Document</title>
  34. </head>
  35. <body>
  36. <div>
  37. <p>Hello,</p>
  38. <p></p>
  39. <p>We warmly welcome you to join our Oil & Shipping Market Sharing Session. The details of the meeting are as follows:</p>
  40. <p></p>
  41. <div style="font-weight: bold;">Event Details:</div>
  42. <ul>
  43. <li>Date: January 14, 2025</li>
  44. <li>Time: 4PM SGT/8AM GMT</li>
  45. </ul>
  46. <br/>
  47. <div style="font-weight: bold;">Agenda:</div>
  48. <p></p>
  49. <p>4:00-4:20pm Eyes on Sanctioned Oil -- Jackson Zhang, Oil Analyst at Horizon Insights</p>
  50. <p>4:20-4:40pm Near Term Drivers and Events That Drive Container Freight Rates -- Johnson Leung, Co-Founder at Linerlytica</p>
  51. <p>4:40-5:00pm 2025 Container Shipping Market Outlook -- Junchen Yu, Shipping Market Analyst at Nanhua Futures </p>
  52. <p style="margin-top: 50px;">
  53. <span>To </span>
  54. <span style="font-weight: bold;">RSVP</span>
  55. <span>, please scan the QR code on poster below or click here:</span>
  56. <a href="https://us06web.zoom.us/webinar/register/WN_G32A_sRYRjefbPTf-CAn_A">https://us06web.zoom.us/webinar/register/WN_G32A_sRYRjefbPTf-CAn_A</a>
  57. </p>
  58. <img style="max-width: 375px;width: 100%;" src="https://hzstatic.hzinsights.com/eta/cloud_disk/202501/20250113/BMW1oUdkKqOn0gRSHclihnBdCuuS.png" alt="">
  59. <p>If you have any questions, feel free to reach out to Eunice (myyu@hzinsights.com). We look forward to your participation! </p>
  60. <p></p>
  61. <p>Best regards,<br>Horizon Insights</p>
  62. </div>
  63. </body>
  64. </html>
  65. `
  66. // 推送信息
  67. sendData := make([]*EnglishReportSendEmailRequest, 0)
  68. for i := range emails {
  69. r := new(EnglishReportSendEmailRequest)
  70. r.EmailId = emails[i].Id
  71. r.Email = strings.Replace(emails[i].Email, " ", "", -1)
  72. r.Subject = "【Horizon Insights】Invitation to Oil & Shipping Market Update" // TODO:这是主题
  73. r.FromAlias = "Horizon FICC" // TODO:这是推送人(中文)
  74. r.HtmlBody = template
  75. sendData = append(sendData, r)
  76. }
  77. if len(sendData) == 0 {
  78. fmt.Println("无邮件可推送")
  79. return
  80. }
  81. // 请求阿里云接口批量推送
  82. aliEmail := new(AliyunEmail)
  83. resultList, e := aliEmail.BatchSendEmail(sendData)
  84. if e != nil {
  85. fmt.Println("批量推送失败, Err: " + e.Error())
  86. return
  87. }
  88. for _, r := range resultList {
  89. utils.FileLog.Info("email: %s, ok: %v, res: %s", r.Email, r.Ok, r.ResultData)
  90. if r.Ok {
  91. fmt.Println("发送成功")
  92. } else {
  93. fmt.Println("发送失败:" + r.ResultData)
  94. }
  95. }
  96. }
  97. type SendEmailReq struct {
  98. Title string `description:"标题"`
  99. Content string `description:"内容"`
  100. ToUser []string `description:"收信人邮箱"`
  101. }
  102. func SendEmail(req SendEmailReq) (success bool, err error) {
  103. if req.Title == "" {
  104. err = fmt.Errorf("邮件主题不可为空")
  105. return
  106. }
  107. if req.Content == "" {
  108. err = fmt.Errorf("邮件内容不可为空")
  109. return
  110. }
  111. if len(req.ToUser) <= 0 {
  112. err = fmt.Errorf("收信人不可为空")
  113. return
  114. }
  115. // 邮箱配置
  116. confMap, e := models.GetBusinessConf()
  117. if e != nil {
  118. err = fmt.Errorf("GetBusinessConf err: %s", e.Error())
  119. return
  120. }
  121. checkArr := []string{
  122. models.BusinessConfEmailServerHost, models.BusinessConfEmailServerPort,
  123. models.BusinessConfEmailSender, models.BusinessConfEmailSenderUserName,
  124. models.BusinessConfEmailSenderPassword,
  125. }
  126. for _, v := range checkArr {
  127. if confMap[v] == "" {
  128. err = fmt.Errorf("%s配置有误", v)
  129. return
  130. }
  131. }
  132. port, _ := strconv.Atoi(confMap[models.BusinessConfEmailServerPort])
  133. if port <= 0 {
  134. port = 587 // 默认587端口
  135. }
  136. m := gomail.NewMessage()
  137. m.SetHeader("From", confMap[models.BusinessConfEmailSender])
  138. m.SetHeader("To", req.ToUser...)
  139. m.SetHeader("Subject", req.Title)
  140. m.SetBody("text/html", req.Content)
  141. d := gomail.NewDialer(confMap[models.BusinessConfEmailServerHost], port, confMap[models.BusinessConfEmailSenderUserName], confMap[models.BusinessConfEmailSenderPassword])
  142. // 解决x509报错的问题。证书不通过。跳过证书验证
  143. config := &tls.Config{ServerName: confMap[models.BusinessConfEmailServerHost], InsecureSkipVerify: true}
  144. d.TLSConfig = config
  145. if e = d.DialAndSend(m); e != nil {
  146. err = fmt.Errorf("邮件发送失败, Err: %s", e.Error())
  147. return
  148. }
  149. success = true
  150. return
  151. }