package service import ( "bytes" "crypto/tls" "fmt" ht "html/template" "strings" "time" "github.com/wneessen/go-mail" "be.ems/src/framework/config" "be.ems/src/framework/logger" "be.ems/src/framework/utils/date" "be.ems/src/framework/utils/parse" neDataModel "be.ems/src/modules/network_data/model" ) // EmailAlarm 发告警邮件 func EmailAlarm(a neDataModel.Alarm, neIP string) error { emailList := fmt.Sprint(config.Get("alarm.alarmEmailForward.emailList")) if len(emailList) == 0 { return fmt.Errorf("email list is empty") } // 模板 htmlBodyTemplate := ` Alarm information
Sequence: {{.AlarmSeq}}
NE Name: {{.NeName}}
NE IP: {{.NeIp}}
Title: {{.AlarmTitle}}
Severity: {{.OrigSeverity}}
Event Time: {{.AlarmTime}}
Alarm Status: {{.AlarmStatus}}
Automatic sent by OMC, please do not reply! ` htmlTpl, err := ht.New("htmltpl").Parse(htmlBodyTemplate) if err != nil { return fmt.Errorf("EmailAlarm Parse alarmId:%s fail %s", a.AlarmId, err.Error()) } // 参数值 data := map[string]any{ "AlarmSeq": a.AlarmSeq, "NeName": a.NeName, "NeIp": neIP, "AlarmTitle": a.AlarmTitle, "OrigSeverity": a.OrigSeverity, "AlarmTime": date.ParseDateToStr(a.EventTime, time.RFC3339), "AlarmStatus": a.AlarmStatus, } buffer := bytes.NewBuffer(nil) if err := htmlTpl.Execute(buffer, data); err != nil { return fmt.Errorf("EmailAlarm Execute alarmId:%s fail %s", a.AlarmId, err.Error()) } htmlStr := buffer.String() // 发送邮件 err = EmailSendHTML(htmlStr, strings.Split(emailList, ",")) if err != nil { return fmt.Errorf("EmailAlarm alarmId:%s fail %s", a.AlarmId, err.Error()) } return err } // EmailSendHTML 发送HTML邮件 func EmailSendHTML(htmlStr string, toEmailArr []string) error { // QQ 邮箱: // SMTP 服务器地址:smtp.qq.com(SSL协议端口:465/994 | 非SSL协议端口:25) // 163 邮箱: // SMTP 服务器地址:smtp.163.com(端口:25) // host := "mail.agrandtech.com" // port := 25 // userName := "smtpext@agrandtech.com" // password := "1000smtp@omc!" emailConf := config.Get("alarm.alarmEmailForward").(map[string]any) enable := parse.Boolean(emailConf["enable"]) if !enable { return fmt.Errorf("email notification not enable") } title := fmt.Sprint(emailConf["title"]) smtp := fmt.Sprint(emailConf["smtp"]) port := parse.Number(emailConf["port"]) user := fmt.Sprint(emailConf["user"]) password := fmt.Sprint(emailConf["password"]) message := mail.NewMsg() // 发件人 if err := message.From(user); err != nil { return fmt.Errorf("failed to set From address: %s", err) } // 收件人 hasTo := false for _, v := range toEmailArr { if err := message.AddTo(v); err != nil { logger.Errorf("failed to set To address: %v %s", v, err) continue } hasTo = true } if !hasTo { return fmt.Errorf("failed to set To address not has") } // 邮件主题 message.Subject(title) // 邮件HTML内容 message.SetBodyString(mail.TypeTextHTML, htmlStr) // 连接到邮件SMTP服务器 client, err := mail.NewClient(smtp, mail.WithSMTPAuth(mail.SMTPAuthAutoDiscover), mail.WithUsername(user), mail.WithPort(int(port)), mail.WithPassword(password), mail.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}), ) if err != nil { return fmt.Errorf("failed to create mail client: %s", err) } // 发送 if err := client.DialAndSend(message); err != nil { return fmt.Errorf("failed to send mail: %s", err) } return nil }