package notify import ( "fmt" "net/smtp" "strings" ) // smtpNotifier 实现了 Notifier 接口,用于通过 SMTP 发送邮件通知。 type smtpNotifier struct { host string // SMTP 服务器地址 port int // SMTP 服务器端口 username string // 发件人邮箱地址 password string // 发件人邮箱授权码 sender string // 发件人名称或地址,显示在邮件的 \"From\" 字段 } // NewSMTPNotifier 创建一个新的 smtpNotifier 实例。 // 调用者需要注入 SMTP 相关的配置。 func NewSMTPNotifier(host string, port int, username, password, sender string) Notifier { return &smtpNotifier{ host: host, port: port, username: username, password: password, sender: sender, } } // Send 使用 net/smtp 包发送一封邮件。 func (s *smtpNotifier) Send(content AlarmContent, toAddr string) error { // 1. 设置认证信息 auth := smtp.PlainAuth("", s.username, s.password, s.host) // 2. 构建邮件内容 // 邮件头 subject := content.Title contentType := "Content-Type: text/plain; charset=UTF-8" fromHeader := fmt.Sprintf("From: %s", s.sender) toHeader := fmt.Sprintf("To: %s", toAddr) subjectHeader := fmt.Sprintf("Subject: %s", subject) // 邮件正文 body := fmt.Sprintf("级别: %s\n时间: %s\n\n%s", content.Level.String(), content.Timestamp.Format(DefaultTimeFormat), content.Message, ) // 拼接完整的邮件报文 msg := strings.Join([]string{ fromHeader, toHeader, subjectHeader, contentType, "", // 邮件头和正文之间的空行 body, }, "\r\n") // 3. 发送邮件 addr := fmt.Sprintf("%s:%d", s.host, s.port) err := smtp.SendMail(addr, auth, s.username, []string{toAddr}, []byte(msg)) if err != nil { return fmt.Errorf("发送邮件失败: %w", err) } return nil } // Type 返回通知器的类型 func (s *smtpNotifier) Type() NotifierType { return NotifierTypeSMTP }