Files
rikkei_simple_care/server/internal/mail/mail.go
2026-06-30 10:39:29 +07:00

92 lines
1.9 KiB
Go

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))
}