// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn . //go:build plus package tasks import ( "fmt" teaconst "github.com/TeaOSLab/EdgeAPI/internal/const" "github.com/TeaOSLab/EdgeAPI/internal/db/models" "github.com/TeaOSLab/EdgeAPI/internal/goman" "github.com/TeaOSLab/EdgeAPI/internal/remotelogs" "github.com/TeaOSLab/EdgeAPI/internal/senders/mediasenders" "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/logs" "github.com/iwind/TeaGo/types" "net/mail" "strings" "time" ) func init() { dbs.OnReadyDone(func() { goman.New(func() { NewUserEmailNotificationTask(30 * time.Second).Start() }) }) } type UserEmailNotificationTask struct { BaseTask duration time.Duration } func NewUserEmailNotificationTask(duration time.Duration) *UserEmailNotificationTask { return &UserEmailNotificationTask{ duration: duration, } } func (this *UserEmailNotificationTask) Start() { var ticker = time.NewTicker(this.duration) for range ticker.C { err := this.Loop() if err != nil { remotelogs.Error("UserEmailNotificationTask", err.Error()) } } } func (this *UserEmailNotificationTask) Loop() error { if !this.IsPrimaryNode() { return nil } var tx *dbs.Tx // 删除过期的通知 err := models.SharedUserEmailNotificationDAO.DeleteExpiredNotifications(tx, 2) if err != nil { return err } // 通知邮件设置 senderConfig, err := models.SharedSysSettingDAO.ReadUserSenderConfig(tx) if err != nil { return err } var notifyEmail = senderConfig.NotifyEmail if notifyEmail == nil { return nil } if !notifyEmail.IsOn { return nil } // 准备邮件中的参数 productName, err := models.SharedSysSettingDAO.ReadProductName(tx) if err != nil { return err } if len(productName) == 0 { productName = teaconst.ProductNameZH } userNodeAddr, err := models.SharedUserNodeDAO.FindUserNodeAccessAddr(tx) if err != nil { return err } // 查询待发送 notifications, err := models.SharedUserEmailNotificationDAO.ListSendingNotifications(tx, 100) if err != nil { return err } if len(notifications) == 0 { return nil } var mailInfos = []*mediasenders.MailInfo{} var notificationIds = []int64{} for _, notification := range notifications { _, err = mail.ParseAddress(notification.Email) if err != nil { // 直接删除 err = models.SharedUserEmailNotificationDAO.DeleteNotification(tx, int64(notification.Id)) if err != nil { return err } continue } // 标题和内容 var subject = strings.ReplaceAll(notification.Subject, "${product.name}", productName) var body = notification.Body body = strings.ReplaceAll(body, "${product.name}", productName) body = strings.ReplaceAll(body, "${url.home}", userNodeAddr) mailInfos = append(mailInfos, &mediasenders.MailInfo{ To: notification.Email, Subject: subject, Body: body, }) if Tea.IsTesting() { logs.Println("sending notification mail to :", notification.Email) } notificationIds = append(notificationIds, int64(notification.Id)) } if len(mailInfos) == 0 { return nil } // 发送 var mailSender = mediasenders.NewEmailMedia() mailSender.Protocol = notifyEmail.Protocol mailSender.SMTP = notifyEmail.SMTPHost + ":" + types.String(notifyEmail.SMTPPort) mailSender.Username = notifyEmail.Username mailSender.Password = notifyEmail.Password mailSender.From = notifyEmail.FromEmail mailSender.FromName = notifyEmail.FromName err = mailSender.SendMails(mailInfos, productName) if err != nil { return fmt.Errorf("send notification mail failed: %w", err) } // 设置为已发送 for _, notificationId := range notificationIds { err = models.SharedUserEmailNotificationDAO.DeleteNotification(tx, notificationId) if err != nil { return err } } return nil }