email.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. package services
  2. import (
  3. "crypto/tls"
  4. "eta/eta_api/models"
  5. "eta/eta_api/utils"
  6. "fmt"
  7. "gopkg.in/gomail.v2"
  8. "strconv"
  9. "strings"
  10. )
  11. func SendEmailToCompany() {
  12. // 获取收件人列表
  13. //emailCond := " AND enabled = 1 "
  14. emailCond := ""
  15. emailPars := make([]interface{}, 0)
  16. emails, e := models.GetEnglishReportEmailList(emailCond, emailPars, "")
  17. if e != nil {
  18. fmt.Println("获取收件人列表失败, Err: " + e.Error())
  19. return
  20. }
  21. if len(emails) == 0 {
  22. fmt.Println("收件人列表为空")
  23. return
  24. }
  25. // TODO:这是HTML模板内容
  26. template := `<!DOCTYPE html>
  27. <html lang="en">
  28. <head>
  29. <meta charset="UTF-8">
  30. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  31. <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,viewport-fit=cover">
  32. <title>Horizon Insights x Fastmarkets x FGE: 2024 Macro & Commodities Outlook - Registration Open!</title>
  33. </head>
  34. <body style="padding:0;margin:0;background-color:#fff">
  35. <div id="app" style="max-width:1280px;margin:0 auto;font-size:14px;min-height:100vh;">
  36. <div class="main-box" style="padding:25px 20px;">
  37. <div style="line-height:1.7;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;"
  38. class=" __aliyun_node_has_color">
  39. <div style="clear:both;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-variant-ligatures:normal;font-variant-caps:normal;text-align:center;text-indent:.0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"
  40. class=" __aliyun_node_has_color"><span
  41. style="font-size:18.0px;font-weight:bold;font-style:normal;text-transform:none;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-family:arial;color:#000000;text-decoration:underline;"
  42. class=" __aliyun_node_has_color">2024 Macro &amp; Commodities Outlook Invite</span></div>
  43. <div style="clear:both;margin:.0px;padding:.0px;border:.0px;outline:.0px;color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"
  44. class=" __aliyun_node_has_color"><span
  45. style="margin:.0px;padding:.0px;border:.0px;outline:.0px;font-family:arial;font-size:13.0px;color:#000000;"
  46. class=" __aliyun_node_has_color"><br></span></div>
  47. <div style="clear:both;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-variant-ligatures:normal;font-variant-caps:normal;text-align:start;text-indent:.0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"
  48. class=" __aliyun_node_has_color"><span
  49. style="font-style:normal;font-weight:400;text-transform:none;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-family:arial;font-size:13.0px;color:#000000;"
  50. class=" __aliyun_node_has_color">Dear Client,</span></div>
  51. <div style="clear:both;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-variant-ligatures:normal;font-variant-caps:normal;text-align:start;text-indent:.0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"
  52. class=" __aliyun_node_has_color"><span
  53. style="font-style:normal;font-weight:400;text-transform:none;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-family:arial;font-size:13.0px;color:#000000;"
  54. class=" __aliyun_node_has_color"><br></span></div>
  55. <div style="clear:both;">
  56. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;font-variant-ligatures:normal;font-variant-caps:normal;text-align:start;text-indent:.0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;clear:both;"
  57. class=" __aliyun_node_has_color"></div>
  58. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;font-variant-ligatures:normal;font-variant-caps:normal;text-align:start;text-indent:.0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;clear:both;"
  59. class=" __aliyun_node_has_color"></div>
  60. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;font-variant-ligatures:normal;font-variant-caps:normal;text-align:start;text-indent:.0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;clear:both;"
  61. class=" __aliyun_node_has_color"><span
  62. style="font-style:normal;font-weight:400;text-transform:none;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-family:arial;font-size:13.0px;color:#000000;"
  63. class=" __aliyun_node_has_color">Happy Year-End Holidays!</span></div>
  64. </div>
  65. <div style="clear:both;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-variant-ligatures:normal;font-variant-caps:normal;text-align:start;text-indent:.0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"
  66. class=" __aliyun_node_has_color"><span
  67. style="font-style:normal;font-weight:400;text-transform:none;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-family:arial;font-size:13.0px;color:#000000;"
  68. class=" __aliyun_node_has_color"><br></span></div>
  69. <div style="clear:both;">
  70. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;font-variant-ligatures:normal;font-variant-caps:normal;text-align:start;text-indent:.0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;clear:both;"
  71. class=" __aliyun_node_has_color"></div>
  72. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;font-variant-ligatures:normal;font-variant-caps:normal;text-align:start;text-indent:.0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;clear:both;"
  73. class=" __aliyun_node_has_color"></div>
  74. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;font-variant-ligatures:normal;font-variant-caps:normal;text-align:start;text-indent:.0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;clear:both;"
  75. class=" __aliyun_node_has_color"><span
  76. style="color:#000000;font-style:normal;font-weight:400;text-transform:none;border:.0px;font-family:arial;margin:.0px;padding:.0px;outline:.0px;font-size:13.0px;"
  77. class=" __aliyun_node_has_color">As we usher in the new year, Horizon Insights, in collaboration
  78. with Fastmarkets and FGE, is proud to announce</span><span
  79. style="color:#000000;font-style:normal;font-weight:400;text-transform:none;font-family:arial;font-size:13.0px;"
  80. class=" __aliyun_node_has_color">&nbsp;our 2024 Macro &amp; Commodities Outlook which will be
  81. held&nbsp;</span><span
  82. style="font-weight:bold;color:#000000;font-style:normal;text-transform:none;font-family:arial;font-size:13.0px;text-decoration:none;"
  83. class=" __aliyun_node_has_color">virtually</span><span
  84. style="color:#000000;font-style:normal;font-weight:400;text-transform:none;font-family:arial;font-size:13.0px;text-decoration:none;"
  85. class=" __aliyun_node_has_color">&nbsp;on&nbsp;</span><span
  86. style="font-weight:bold;color:#000000;font-style:normal;text-transform:none;font-family:arial;font-size:13.0px;text-decoration:none;"
  87. class=" __aliyun_node_has_color">10 &amp; 11 Jan 2024</span><span
  88. style="color:#000000;font-style:normal;font-weight:400;text-transform:none;font-family:arial;font-size:13.0px;"
  89. class=" __aliyun_node_has_color">,&nbsp;</span><span
  90. style="color:#000000;font-family:arial;font-size:13.0px;font-style:normal;font-weight:bold;text-transform:none;"
  91. class=" __aliyun_node_has_color">5pm - 8pm SGT</span><span
  92. style="color:#000000;font-style:normal;font-weight:400;text-transform:none;font-family:arial;font-size:13.0px;"
  93. class=" __aliyun_node_has_color">&nbsp;(i.e.&nbsp;</span><span
  94. style="color:#000000;font-family:arial;font-size:13.0px;font-style:normal;font-weight:bold;text-transform:none;"
  95. class=" __aliyun_node_has_color">9am - 12pm BST</span><span
  96. style="color:#000000;font-style:normal;font-weight:400;text-transform:none;font-family:arial;font-size:13.0px;"
  97. class=" __aliyun_node_has_color">). Our experienced analysts from Horizon Insights together with
  98. guest speakers from our valued partners will present our views in the fields of Macro, Ferrous
  99. Metals, Base Metals, Energy, as well as Petrochemicals.</span></div>
  100. </div>
  101. <div style="clear:both;margin:.0px;padding:.0px;border:.0px;outline:.0px;color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"
  102. class=" __aliyun_node_has_color"><span
  103. style="margin:.0px;padding:.0px;border:.0px;outline:.0px;font-size:13.0px;font-family:arial;"><br></span>
  104. </div>
  105. <div style="clear:both;margin:.0px;padding:.0px;border:.0px;outline:.0px;color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"
  106. class=" __aliyun_node_has_color"><span
  107. style="margin:.0px;padding:.0px;border:.0px;outline:.0px;font-size:13.0px;font-family:arial;">Please
  108. see below for our event schedule:</span></div>
  109. <div
  110. style="clear:both;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-variant-ligatures:normal;font-variant-caps:normal;text-align:start;text-indent:.0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;">
  111. <br></div>
  112. <div
  113. style="clear:both;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-variant-ligatures:normal;font-variant-caps:normal;text-align:start;text-indent:.0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;">
  114. <span
  115. style="color:#000000;font-style:normal;font-weight:400;text-transform:none;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-size:13.0px;font-family:arial;"
  116. class=" __aliyun_node_has_color">&nbsp;&nbsp;<img style="vertical-align: bottom; margin: 0px;"
  117. height="3301"
  118. src="https://hzstatic.hzinsights.com/static/images/202312/20231228/KeDTAxIZ3UrZR5DZKKIQLdoIaOVB.png"
  119. width="890"></span></div>
  120. <div
  121. style="clear:both;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-variant-ligatures:normal;font-variant-caps:normal;text-align:start;text-indent:.0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;">
  122. <span
  123. style="color:#000000;font-style:normal;font-weight:400;text-transform:none;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-size:13.0px;font-family:arial;"
  124. class=" __aliyun_node_has_color">&nbsp; &nbsp;</span></div>
  125. <div
  126. style="clear:both;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-variant-ligatures:normal;font-variant-caps:normal;text-align:start;text-indent:.0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;">
  127. <br></div>
  128. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;clear:both;"
  129. class=" __aliyun_node_has_color"><span
  130. style="margin:.0px;padding:.0px;border:.0px;outline:.0px;font-family:arial;font-size:13.0px;"><br></span>
  131. </div>
  132. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;clear:both;"
  133. class=" __aliyun_node_has_color"><span
  134. style="margin:.0px;padding:.0px;border:.0px;outline:.0px;font-family:arial;font-size:13.0px;">To
  135. register, simply scan the QR code in the posters above to indicate your interest. Alternatively, you
  136. may also&nbsp;</span><span
  137. style="font-weight:bold;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-family:arial;font-size:13.0px;"><a
  138. href="https://forms.gle/yhPRDcri43P2QyPt8" target="_blank">register here</a></span><span
  139. style="margin:.0px;padding:.0px;border:.0px;outline:.0px;font-family:arial;font-size:13.0px;">.</span>
  140. </div>
  141. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;clear:both;"
  142. class=" __aliyun_node_has_color"><span
  143. style="margin:.0px;padding:.0px;border:.0px;outline:.0px;font-family:arial;font-size:13.0px;color:#000000;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline;"
  144. class=" __aliyun_node_has_color">Should you encounter any difficulties registering, please contact
  145. Stephanie (stephanie@hzinsights.com).</span></div>
  146. <div>
  147. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;clear:both;"
  148. class=" __aliyun_node_has_color"></div>
  149. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;clear:both;"
  150. class=" __aliyun_node_has_color"><span
  151. style="font-weight:bold;margin:.0px;padding:.0px;border:.0px;outline:.0px;font-family:arial;font-size:13.0px;">The
  152. virtual meeting details will be disseminated to you a few days prior to the event.</span></div>
  153. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;clear:both;"
  154. class=" __aliyun_node_has_color"><br></div>
  155. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;clear:both;"
  156. class=" __aliyun_node_has_color"><span
  157. style="margin:.0px;padding:.0px;border:.0px;outline:.0px;font-family:arial;font-size:13.0px;">Lastly,
  158. our firm would like to wish all of you a prosperous Happy New Year! We look forward to seeing
  159. everyone on the 10th &amp; 11th.</span></div>
  160. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;clear:both;"
  161. class=" __aliyun_node_has_color"><span
  162. style="margin:.0px;padding:.0px;border:.0px;outline:.0px;font-family:arial;font-size:13.0px;"><br></span>
  163. </div>
  164. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;clear:both;"
  165. class=" __aliyun_node_has_color"><span
  166. style="margin:.0px;padding:.0px;border:.0px;outline:.0px;font-family:arial;font-size:13.0px;">Cheers!</span>
  167. </div>
  168. </div>
  169. <div><br></div>
  170. <div>
  171. <div style="clear:both;"><span style="font-family:arial;font-size:13.0px;color:#000000;"
  172. class=" __aliyun_node_has_color"><br></span></div>
  173. <div style="clear:both;">
  174. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;clear:both;font-variant-caps:normal;text-align:start;text-indent:.0px;"
  175. class="x___aliyun_node_has_color"><br></div>
  176. <div style="margin:.0px;padding:.0px;border:.0px;outline:.0px;clear:both;font-variant-caps:normal;text-align:start;text-indent:.0px;"
  177. class="x___aliyun_node_has_color"></div>
  178. </div>
  179. </div>
  180. <div><br></div>
  181. <div><br></div>
  182. <div><br></div>
  183. <div style="line-height:20.0px;clear:both;"><br></div>
  184. </div>
  185. </div>
  186. </div>
  187. </body>
  188. </html>`
  189. // 推送信息
  190. sendData := make([]*EnglishReportSendEmailRequest, 0)
  191. for i := range emails {
  192. r := new(EnglishReportSendEmailRequest)
  193. r.EmailId = emails[i].Id
  194. r.Email = strings.Replace(emails[i].Email, " ", "", -1)
  195. r.Subject = "Horizon Insights x Fastmarkets x FGE: 2024 Macro & Commodities Outlook - Registration Open!" // TODO:这是主题
  196. r.FromAlias = "Horizon FICC" // TODO:这是推送人(中文)
  197. r.HtmlBody = template
  198. sendData = append(sendData, r)
  199. }
  200. if len(sendData) == 0 {
  201. fmt.Println("无邮件可推送")
  202. return
  203. }
  204. // 请求阿里云接口批量推送
  205. aliEmail := new(AliyunEmail)
  206. resultList, e := aliEmail.BatchSendEmail(sendData)
  207. if e != nil {
  208. fmt.Println("批量推送失败, Err: " + e.Error())
  209. return
  210. }
  211. for _, r := range resultList {
  212. utils.FileLog.Info("email: %s, ok: %v, res: %s", r.Email, r.Ok, r.ResultData)
  213. if r.Ok {
  214. fmt.Println("发送成功")
  215. } else {
  216. fmt.Println("发送失败:" + r.ResultData)
  217. }
  218. }
  219. }
  220. type SendEmailReq struct {
  221. Title string `description:"标题"`
  222. Content string `description:"内容"`
  223. ToUser []string `description:"收信人邮箱"`
  224. }
  225. func SendEmail(req SendEmailReq) (success bool, err error) {
  226. if req.Title == "" {
  227. err = fmt.Errorf("邮件主题不可为空")
  228. return
  229. }
  230. if req.Content == "" {
  231. err = fmt.Errorf("邮件内容不可为空")
  232. return
  233. }
  234. if len(req.ToUser) <= 0 {
  235. err = fmt.Errorf("收信人不可为空")
  236. return
  237. }
  238. // 邮箱配置
  239. confMap, e := models.GetBusinessConf()
  240. if e != nil {
  241. err = fmt.Errorf("GetBusinessConf err: %s", e.Error())
  242. return
  243. }
  244. checkArr := []string{
  245. models.BusinessConfEmailServerHost, models.BusinessConfEmailServerPort,
  246. models.BusinessConfEmailSender, models.BusinessConfEmailSenderUserName,
  247. models.BusinessConfEmailSenderPassword,
  248. }
  249. for _, v := range checkArr {
  250. if confMap[v] == "" {
  251. err = fmt.Errorf("%s配置有误", v)
  252. return
  253. }
  254. }
  255. port, _ := strconv.Atoi(confMap[models.BusinessConfEmailServerPort])
  256. if port <= 0 {
  257. port = 587 // 默认587端口
  258. }
  259. m := gomail.NewMessage()
  260. m.SetHeader("From", confMap[models.BusinessConfEmailSender])
  261. m.SetHeader("To", req.ToUser...)
  262. m.SetHeader("Subject", req.Title)
  263. m.SetBody("text/html", req.Content)
  264. d := gomail.NewDialer(confMap[models.BusinessConfEmailServerHost], port, confMap[models.BusinessConfEmailSenderUserName], confMap[models.BusinessConfEmailSenderPassword])
  265. // 解决x509报错的问题。证书不通过。跳过证书验证
  266. config := &tls.Config{ServerName: confMap[models.BusinessConfEmailServerHost], InsecureSkipVerify: true}
  267. d.TLSConfig = config
  268. if e = d.DialAndSend(m); e != nil {
  269. err = fmt.Errorf("邮件发送失败, Err: %s", e.Error())
  270. return
  271. }
  272. success = true
  273. return
  274. }