package notification import ( "context" "errors" "fmt" "net/mail" "strings" "time" ) // SendTestMail 发送测试邮件,验证发信通道配置与网络连通性。 func (s *Service) SendTestMail(ctx context.Context, targetRecipient string) error { if s == nil || (!s.config.HTTPEnabled && !s.config.SMTPEnabled) { return errors.New("发信服务未启用或未正确配置") } targetRecipient = strings.TrimSpace(targetRecipient) if targetRecipient == "" { if len(s.config.Recipients) > 0 { targetRecipient = s.config.Recipients[0] } } if targetRecipient == "" { return errors.New("收件人邮箱不能为空") } parsed, err := mail.ParseAddress(targetRecipient) if err != nil || parsed.Address != targetRecipient { return errors.New("测试邮件收件人地址格式无效") } fromName, from, err := s.config.SenderIdentity() if err != nil { return err } nowStr := time.Now().Format("2006-01-02 15:04:05") hostInfo := s.config.SMTPHost if s.config.SMTPPort > 0 { hostInfo = fmt.Sprintf("%s:%d", hostInfo, s.config.SMTPPort) } text := fmt.Sprintf("Scert 邮件通知通道测试成功\n\n发信测试已完成,您的邮件通知配置有效且能正常送达。\n发信主机:%s\n发信账号:%s\n测试时间:%s\n\n此邮件为系统自动测试邮件,无需回复。", hostInfo, s.config.SMTPUsername, nowStr) var htmlBuilder strings.Builder beginHTMLMail(&htmlBuilder, "邮件通道测试成功") htmlBuilder.WriteString(`
测试通过
`) htmlBuilder.WriteString(`

发信通道联通成功

`) htmlBuilder.WriteString(`

您的 Scert 邮件通知配置已通过在线发信验证,可正常发送通知邮件。

`) htmlBuilder.WriteString(``) writeHTMLField(&htmlBuilder, "SMTP 主机", hostInfo) if s.config.SMTPUsername != "" { writeHTMLField(&htmlBuilder, "发信账号", s.config.SMTPUsername) } writeHTMLField(&htmlBuilder, "连接模式", s.config.SMTPMode) writeHTMLField(&htmlBuilder, "目标收件人", targetRecipient) writeHTMLField(&htmlBuilder, "验证时间", nowStr) htmlBuilder.WriteString(`
`) htmlBuilder.WriteString(`
系统已确认该发信通道有效,您可以放心保存当前系统邮件通知设置。
`) endHTMLMail(&htmlBuilder) payload := mailPayload{ From: address{Name: fromName, Email: from}, To: []address{{Email: targetRecipient}}, Subject: "[Scert] 邮件通知配置测试成功", Text: text, HTML: htmlBuilder.String(), CC: []address{}, BCC: []address{}, Attrs: []any{}, } if s.config.UsesSmailSystemAccount() { if !s.config.SMTPEnabled { return errors.New("Smail 系统通知账号必须启用 SMTP 通道") } if err := s.sendSMTPWithRetry(ctx, payload); err != nil { return fmt.Errorf("SMTP 测试邮件发送失败:%w", err) } return nil } if s.config.HTTPEnabled { if err := s.sendHTTPPayload(ctx, payload); err == nil { return nil } } if s.config.SMTPEnabled { if err := s.sendSMTPWithRetry(ctx, payload); err != nil { return fmt.Errorf("SMTP 测试邮件发送失败:%w", err) } return nil } return errors.New("测试邮件发送失败,请检查通道设置及网络连通性") }