Files
goodBaby/drivers/email/tool.go
T

117 lines
3.0 KiB
Go

package email
import (
"context"
"encoding/json"
"fmt"
"log"
"time"
"github.com/cenkalti/backoff/v5"
"github.com/ssdomei232/goodBaby/configs"
"github.com/ssdomei232/goodBaby/handler/db"
"github.com/ssdomei232/goodBaby/model"
"github.com/wneessen/go-mail"
)
// 从 Rule 中获取 EmailAccount 配置
func GetEmailAccountFromRule(rule *model.Rule) (*EmailAccountConfig, error) {
gormDB, err := db.GetGormDB()
if err != nil {
return nil, err
}
// 1. 通过 account_id 获取到对应的 account 配置
var emailAccount model.Account
result := gormDB.Where("id = ?", rule.AccountID).First(&emailAccount)
if result.Error != nil {
return nil, result.Error
}
// 2. 通过 account 配置中的 config 字段获取到 EmailAccount
var emailAccountConfig EmailAccountConfig
err = json.Unmarshal([]byte(emailAccount.Config), &emailAccountConfig)
if err != nil {
return nil, err
}
return &emailAccountConfig, nil
}
// 从 Rule 中获取 EmailRule 配置
func GetEmailRuleFromRule(rule *model.Rule) (*EmailRule, error) {
var emailRule EmailRule
err := json.Unmarshal([]byte(rule.ConfigJson), &emailRule)
if err != nil {
return nil, err
}
return &emailRule, nil
}
func sendMailMsgWithRetry(rule *model.Rule, address string) {
config, err := configs.GetConfig()
if err != nil {
log.Printf("获取配置失败: %v", err)
return
}
var timeout time.Duration = time.Duration(config.TimeoutDurationHours) * time.Hour
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
operation := func() (string, error) {
err := sendMailMsg(address, rule)
return "", err
}
_, err = backoff.Retry(ctx, operation, backoff.WithBackOff(backoff.NewExponentialBackOff()))
if err != nil {
log.Printf("发送邮件失败: %v", err)
}
}
func sendMailMsg(address string, rule *model.Rule) error {
emailAccountConfig, err := GetEmailAccountFromRule(rule)
if err != nil {
log.Printf("获取邮件账户配置失败: %v", err)
return fmt.Errorf("获取邮件账户配置失败: %v", err)
}
emailRule, err := GetEmailRuleFromRule(rule)
if err != nil {
log.Printf("获取邮件规则配置失败: %v", err)
return fmt.Errorf("获取邮件规则配置失败: %v", err)
}
client, err := mail.NewClient(
emailAccountConfig.SMTPServer,
mail.WithPort(emailAccountConfig.Port),
mail.WithSSL(),
mail.WithUsername(emailAccountConfig.Username),
mail.WithPassword(emailAccountConfig.Password),
mail.WithSMTPAuth(mail.SMTPAuthPlain),
)
if err != nil {
return fmt.Errorf("创建邮件客户端失败: %v", err)
}
// 创建邮件
message := mail.NewMsg()
if err := message.From(emailAccountConfig.Username); err != nil {
return fmt.Errorf("设置发件人失败: %v", err)
}
if err := message.To(address); err != nil {
return fmt.Errorf("设置收件人失败: %v", err)
}
message.Subject(emailRule.Title)
message.SetBodyString(mail.TypeTextPlain, emailRule.Msg)
// 发送邮件
if err := client.DialAndSend(message); err != nil {
return fmt.Errorf("发送邮件失败: %v", err)
}
return nil
}