mirror of
https://github.com/Awuqing/BackupX.git
synced 2026-09-05 07:26:43 +08:00
first commit
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
package notify
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/smtp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type EmailNotifier struct{}
|
||||
|
||||
func NewEmailNotifier() *EmailNotifier { return &EmailNotifier{} }
|
||||
func (n *EmailNotifier) Type() string { return "email" }
|
||||
func (n *EmailNotifier) SensitiveFields() []string { return []string{"password"} }
|
||||
|
||||
func (n *EmailNotifier) Validate(config map[string]any) error {
|
||||
host := strings.TrimSpace(asString(config["host"]))
|
||||
port := asInt(config["port"])
|
||||
from := strings.TrimSpace(asString(config["from"]))
|
||||
to := strings.TrimSpace(asString(config["to"]))
|
||||
if host == "" || port <= 0 || from == "" || to == "" {
|
||||
return fmt.Errorf("email host/port/from/to are required")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *EmailNotifier) Send(_ context.Context, config map[string]any, message Message) error {
|
||||
if err := n.Validate(config); err != nil {
|
||||
return err
|
||||
}
|
||||
host := strings.TrimSpace(asString(config["host"]))
|
||||
port := asInt(config["port"])
|
||||
username := strings.TrimSpace(asString(config["username"]))
|
||||
password := strings.TrimSpace(asString(config["password"]))
|
||||
from := strings.TrimSpace(asString(config["from"]))
|
||||
toList := splitCommaValues(asString(config["to"]))
|
||||
address := host + ":" + strconv.Itoa(port)
|
||||
headers := []string{"From: " + from, "To: " + strings.Join(toList, ", "), "Subject: " + message.Title, "MIME-Version: 1.0", "Content-Type: text/plain; charset=UTF-8", "", message.Body}
|
||||
var auth smtp.Auth
|
||||
if username != "" {
|
||||
auth = smtp.PlainAuth("", username, password, host)
|
||||
}
|
||||
|
||||
rawMessage := []byte(strings.Join(headers, "\r\n"))
|
||||
|
||||
if port == 465 {
|
||||
tlsConfig := &tls.Config{ServerName: host}
|
||||
conn, err := tls.Dial("tcp", address, tlsConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("dial tls for smtp port 465 failed: %w", err)
|
||||
}
|
||||
client, err := smtp.NewClient(conn, host)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create smtp client over tls failed: %w", err)
|
||||
}
|
||||
defer client.Close()
|
||||
if auth != nil {
|
||||
if ok, _ := client.Extension("AUTH"); ok {
|
||||
if err = client.Auth(auth); err != nil {
|
||||
return fmt.Errorf("smtp auth failed: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if err = client.Mail(from); err != nil {
|
||||
return fmt.Errorf("smtp mail from failed: %w", err)
|
||||
}
|
||||
for _, toAddr := range toList {
|
||||
if err = client.Rcpt(toAddr); err != nil {
|
||||
return fmt.Errorf("smtp rcpt failed for %s: %w", toAddr, err)
|
||||
}
|
||||
}
|
||||
writer, err := client.Data()
|
||||
if err != nil {
|
||||
return fmt.Errorf("smtp data failed: %w", err)
|
||||
}
|
||||
if _, err = writer.Write(rawMessage); err != nil {
|
||||
return fmt.Errorf("smtp write message failed: %w", err)
|
||||
}
|
||||
if err = writer.Close(); err != nil {
|
||||
return fmt.Errorf("smtp data close failed: %w", err)
|
||||
}
|
||||
return client.Quit()
|
||||
}
|
||||
|
||||
return smtp.SendMail(address, auth, from, toList, rawMessage)
|
||||
}
|
||||
Reference in New Issue
Block a user