email.go 22 KB

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