fix(email):修复邮件相关功能
This commit is contained in:
1 parent
958f6c4d75
commit
1f07fae1c2
4 files changed
+34
-11
No files matched your search
@@ -4,11 +4,13 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"github.com/qianfree/team-api/internal/dao"
|
||||
"html/template"
|
||||
"net/mail"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/qianfree/team-api/internal/dao"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
@@ -23,6 +25,7 @@ type EmailConfig struct {
|
||||
Username string
|
||||
Password string
|
||||
From string
|
||||
FromName string // 发件人显示名,收件人邮件列表里看到的名字;为空时只显示邮箱地址
|
||||
UseTLS bool
|
||||
}
|
||||
|
||||
@@ -121,7 +124,17 @@ func (s *BasicEmailSender) SendTemplate(ctx context.Context, to, templateCode st
|
||||
// sendWithRetry performs the actual SMTP send.
|
||||
func (s *BasicEmailSender) sendWithRetry(ctx context.Context, msg *EmailMessage, attempt int) error {
|
||||
m := gomail.NewMessage()
|
||||
m.SetHeader("From", s.config.From)
|
||||
// 发件人显示名:SetAddressHeader 会按 RFC 5322 拼成 "aifree" <system@mail.aifree.com>,
|
||||
// 名称含中文时自动做 RFC 2047 编码;FromName 为空时退化为纯地址。
|
||||
// From 若已配成 "名称 <地址>" 形式,先拆出地址避免二次包装。
|
||||
fromAddr, fromName := s.config.From, s.config.FromName
|
||||
if parsed, err := mail.ParseAddress(fromAddr); err == nil {
|
||||
fromAddr = parsed.Address
|
||||
if fromName == "" {
|
||||
fromName = parsed.Name
|
||||
}
|
||||
}
|
||||
m.SetAddressHeader("From", fromAddr, fromName)
|
||||
m.SetHeader("To", msg.To)
|
||||
m.SetHeader("Subject", msg.Subject)
|
||||
|
||||
@@ -205,6 +218,7 @@ func EmailConfigFromOptions(ctx context.Context) (*EmailConfig, error) {
|
||||
Username: Config().GetString(ctx, "email_smtp_username"),
|
||||
Password: Config().GetString(ctx, "email_smtp_password"),
|
||||
From: Config().GetString(ctx, "email_smtp_from"),
|
||||
FromName: Config().GetString(ctx, "email_smtp_from_name"),
|
||||
UseTLS: Config().GetBool(ctx, "email_smtp_tls"),
|
||||
}
|
||||
|
||||
@@ -212,6 +226,11 @@ func EmailConfigFromOptions(ctx context.Context) (*EmailConfig, error) {
|
||||
return nil, gerror.New("email SMTP config not set (email_smtp_host, email_smtp_from)")
|
||||
}
|
||||
|
||||
// 未单独配置发件人名称时回落到站点名称,避免收件人只看到邮箱地址的本地部分
|
||||
if cfg.FromName == "" {
|
||||
cfg.FromName = Config().GetString(ctx, "site_name")
|
||||
}
|
||||
|
||||
if cfg.Port == 0 {
|
||||
cfg.Port = 587
|
||||
}
|
||||
|
||||
@@ -107,6 +107,8 @@ var Registry = []SettingDef{
|
||||
Label: "SMTP 密码", Sensitive: true},
|
||||
{Key: "email_smtp_from", Type: SettingTypeString, Default: "", Category: "email",
|
||||
Label: "发件人地址", Description: "格式: noreply@example.com"},
|
||||
{Key: "email_smtp_from_name", Type: SettingTypeString, Default: "", Category: "email",
|
||||
Label: "发件人名称", Description: "收件人看到的发件人显示名,如 aifree;留空则使用站点名称"},
|
||||
{Key: "email_smtp_tls", Type: SettingTypeBool, Default: "true", Category: "email",
|
||||
Label: "启用 TLS", Description: "587/465 端口建议开启"},
|
||||
|
||||
|
||||
@@ -95,15 +95,14 @@ func dispatchAlertNotifications(ctx context.Context, rule map[string]any, eventI
|
||||
|
||||
// sendAlertEmailToAdmins sends alert email to specified admin users.
|
||||
func sendAlertEmailToAdmins(ctx context.Context, adminIDs []int64, subject, body string) {
|
||||
// Create email sender from config
|
||||
sender := common.NewEmailSender(&common.EmailConfig{
|
||||
Host: g.Cfg().MustGet(ctx, "email.smtp.host").String(),
|
||||
Port: g.Cfg().MustGet(ctx, "email.smtp.port").Int(),
|
||||
Username: g.Cfg().MustGet(ctx, "email.smtp.username").String(),
|
||||
Password: g.Cfg().MustGet(ctx, "email.smtp.password").String(),
|
||||
From: g.Cfg().MustGet(ctx, "email.smtp.from").String(),
|
||||
UseTLS: g.Cfg().MustGet(ctx, "email.smtp.port").Int() == 587 || g.Cfg().MustGet(ctx, "email.smtp.port").Int() == 465,
|
||||
})
|
||||
// 与其余邮件链路统一走设置注册表(管理后台「邮件配置」),
|
||||
// 而非 config.yaml 的 email.smtp.*(该配置段不存在,会读出空值导致告警邮件必然发送失败)
|
||||
cfg, err := common.EmailConfigFromOptions(ctx)
|
||||
if err != nil {
|
||||
g.Log().Warningf(ctx, "send alert email: %v", err)
|
||||
return
|
||||
}
|
||||
sender := common.NewEmailSender(cfg)
|
||||
|
||||
for _, adminID := range adminIDs {
|
||||
type adminUser struct {
|
||||
|
||||
@@ -37,6 +37,9 @@ const values = useFormValues()
|
||||
<AFormItem label="发件人地址" help="格式: noreply@example.com">
|
||||
<AInput v-model="values['email_smtp_from']" placeholder="noreply@example.com" />
|
||||
</AFormItem>
|
||||
<AFormItem label="发件人名称" help="收件人看到的发件人显示名,留空则使用站点名称">
|
||||
<AInput v-model="values['email_smtp_from_name']" placeholder="aifree" />
|
||||
</AFormItem>
|
||||
<div class="switch-row">
|
||||
<span class="switch-label">启用 TLS</span>
|
||||
<span class="switch-desc">587/465 端口建议开启</span>
|
||||
|
||||
Reference in new issue
Block a user