package mail import ( "crypto/tls" "fmt" "net" "net/smtp" "os" "strings" ) type Config struct { Host string Port string Secure bool User string Password string From string } func LoadConfigFromEnv() Config { return Config{ Host: strings.TrimSpace(os.Getenv("MAIL_HOST")), Port: strings.TrimSpace(os.Getenv("MAIL_PORT")), Secure: strings.EqualFold(os.Getenv("MAIL_SECURE"), "true"), User: strings.TrimSpace(os.Getenv("MAIL_AUTH_USER")), Password: strings.Trim(strings.TrimSpace(os.Getenv("MAIL_AUTH_PASS")), `"`), From: strings.TrimSpace(os.Getenv("MAIL_FROM")), } } func (c Config) Enabled() bool { return c.Host != "" && c.Port != "" && c.User != "" && c.Password != "" } func (c Config) fromAddr() string { if c.From != "" { return c.From } return c.User } func (c Config) Send(to, subject, body string) error { if !c.Enabled() { return fmt.Errorf("mail chưa cấu hình (MAIL_HOST, MAIL_AUTH_USER, MAIL_AUTH_PASS)") } msg := strings.Join([]string{ "From: Simple Care <" + c.fromAddr() + ">", "To: " + to, "Subject: " + subject, "MIME-Version: 1.0", "Content-Type: text/html; charset=UTF-8", "", body, }, "\r\n") addr := net.JoinHostPort(c.Host, c.Port) auth := smtp.PlainAuth("", c.User, c.Password, c.Host) if c.Secure { tlsConfig := &tls.Config{ServerName: c.Host} conn, err := tls.Dial("tcp", addr, tlsConfig) if err != nil { return err } client, err := smtp.NewClient(conn, c.Host) if err != nil { return err } defer client.Close() if err := client.Auth(auth); err != nil { return err } if err := client.Mail(c.fromAddr()); err != nil { return err } if err := client.Rcpt(to); err != nil { return err } w, err := client.Data() if err != nil { return err } if _, err := w.Write([]byte(msg)); err != nil { return err } return w.Close() } return smtp.SendMail(addr, auth, c.fromAddr(), []string{to}, []byte(msg)) }