package services import ( "crypto/tls" "eta/eta_api/models" "eta/eta_api/utils" "fmt" "gopkg.in/gomail.v2" "strconv" "strings" ) func SendEmailToCompany() { // 获取收件人列表 emailCond := " AND enabled = 1 AND status in (1,2) " //emailCond := "" emailPars := make([]interface{}, 0) emails, e := models.GetEnglishReportEmailList(emailCond, emailPars, "") if e != nil { fmt.Println("获取收件人列表失败, Err: " + e.Error()) return } if len(emails) == 0 { fmt.Println("收件人列表为空") return } // TODO:这是HTML模板内容 template := `<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <div> <p>Hello,</p> <p></p> <p> We are pleased to invite you to the launch of our <span style="font-weight: 700;">Mon. Date with HI</span> , a weekly event where we share timely updates and expert analysis on Global Macro, Base Metal, Ferrous Metal, and Energy markets.</p> <h3 style="font-weight: 700;">Event Details:</h3> <ul> <li>Date: August 26th</li> <li>Time: 5:00 PM (Shanghai/Singapore) | 10:00 AM (London)</li> <li>Platform: Zoom (the same link will be used for all future sessions)</li> </ul> <h3 style="font-weight: 700;">Join Zoom Meeting:</h3> <a href="https://us06web.zoom.us/j/84723517075?pwd=3GHNOCHq6sAgBGXsA7qtX9r1PuA1uK.1" target="_blank">https://us06web.zoom.us/j/84723517075?pwd=3GHNOCHq6sAgBGXsA7qtX9r1PuA1uK.1</a> <p> <span style="font-weight: 700;">Meeting ID:</span> <span>847 2351 7075</span> </p> <p> <span style="font-weight: 700;">Passcode:</span> <span>564439</span> </p> <p style="font-weight: 700;">Theme for Today’s Session: Diverging Expectations between Market and Policymakers</p> <p>Our analysts will discuss the impact of the current macro environment on commodity markets, exploring both short-term challenges and longer-term outlooks.<br>This series will be a recurring event every Monday at the same time. </p> <h3 style="font-weight: 700;">Please note:</h3> <ul> <li>This event will be conducted in listen-only mode. However, participants are encouraged to ask questions via the chat function during the Q&A segments.</li> <li>For privacy concerns, you may change your display name upon joining the event.</li> </ul> <p></p> <p>We look forward to your participation.</p> <p></p> <p>Best regards,<br>Horizon Insights</p> <img style="max-width: 375px;width: 100%;" src="https://hzstatic.hzinsights.com/static/images/202408/20240826/z0qJ4cpM5mIaHrHv0BaMsNXYkLKa.jpg" alt=""> </div> </body> </html>` // 推送信息 sendData := make([]*EnglishReportSendEmailRequest, 0) for i := range emails { r := new(EnglishReportSendEmailRequest) r.EmailId = emails[i].Id r.Email = strings.Replace(emails[i].Email, " ", "", -1) r.Subject = "Invitation to Weekly Call with Horizon Insights Analysts: Mon. Date with HI" // TODO:这是主题 r.FromAlias = "Horizon FICC" // TODO:这是推送人(中文) r.HtmlBody = template sendData = append(sendData, r) } if len(sendData) == 0 { fmt.Println("无邮件可推送") return } // 请求阿里云接口批量推送 aliEmail := new(AliyunEmail) resultList, e := aliEmail.BatchSendEmail(sendData) if e != nil { fmt.Println("批量推送失败, Err: " + e.Error()) return } for _, r := range resultList { utils.FileLog.Info("email: %s, ok: %v, res: %s", r.Email, r.Ok, r.ResultData) if r.Ok { fmt.Println("发送成功") } else { fmt.Println("发送失败:" + r.ResultData) } } } type SendEmailReq struct { Title string `description:"标题"` Content string `description:"内容"` ToUser []string `description:"收信人邮箱"` } func SendEmail(req SendEmailReq) (success bool, err error) { if req.Title == "" { err = fmt.Errorf("邮件主题不可为空") return } if req.Content == "" { err = fmt.Errorf("邮件内容不可为空") return } if len(req.ToUser) <= 0 { err = fmt.Errorf("收信人不可为空") return } // 邮箱配置 confMap, e := models.GetBusinessConf() if e != nil { err = fmt.Errorf("GetBusinessConf err: %s", e.Error()) return } checkArr := []string{ models.BusinessConfEmailServerHost, models.BusinessConfEmailServerPort, models.BusinessConfEmailSender, models.BusinessConfEmailSenderUserName, models.BusinessConfEmailSenderPassword, } for _, v := range checkArr { if confMap[v] == "" { err = fmt.Errorf("%s配置有误", v) return } } port, _ := strconv.Atoi(confMap[models.BusinessConfEmailServerPort]) if port <= 0 { port = 587 // 默认587端口 } m := gomail.NewMessage() m.SetHeader("From", confMap[models.BusinessConfEmailSender]) m.SetHeader("To", req.ToUser...) m.SetHeader("Subject", req.Title) m.SetBody("text/html", req.Content) d := gomail.NewDialer(confMap[models.BusinessConfEmailServerHost], port, confMap[models.BusinessConfEmailSenderUserName], confMap[models.BusinessConfEmailSenderPassword]) // 解决x509报错的问题。证书不通过。跳过证书验证 config := &tls.Config{ServerName: confMap[models.BusinessConfEmailServerHost], InsecureSkipVerify: true} d.TLSConfig = config if e = d.DialAndSend(m); e != nil { err = fmt.Errorf("邮件发送失败, Err: %s", e.Error()) return } success = true return }