appcore/email/transport_smtp.go

92 lines
1.8 KiB
Go
Raw Permalink Normal View History

2025-06-16 22:19:00 +05:30
// Copyright 2024 Patial Tech (Ankit Patial).
2025-06-16 22:26:47 +05:30
//
// This file is part of code.patial.tech/go/appcore, which is MIT licensed.
// See http://opensource.org/licenses/MIT
2025-06-16 22:19:00 +05:30
package email
import (
"fmt"
"log/slog"
"strings"
"code.patial.tech/go/appcore/email/gomail"
"code.patial.tech/go/appcore/uid"
)
// SMTP mailer
type SMTP struct {
Host string
Port int
Username string
Password string
// Domain name for smtp
Domain string
}
func (t SMTP) Send(msg *Message) error {
slog.Info("sending mail", slog.String("smtp", t.Host))
// validate msg
if err := msg.Validate(); err != nil {
return err
}
toCount := len(msg.To)
m := gomail.NewMessage()
if msg.ID != "" {
m.SetHeader("Message-ID", fmt.Sprintf("<%s>", msg.ID))
} else {
uid, err := uid.NewUUID()
if err != nil {
return err
}
id := strings.Replace(uid, "-", "", -1)
msgID := fmt.Sprintf("<autogen-%s@%s>", id, t.Domain)
m.SetHeader("Message-ID", msgID)
}
m.SetHeader("From", msg.From)
// TO
to := make([]string, toCount)
for i, address := range msg.To {
to[i] = address.String()
}
m.SetHeader("To", to...)
// subject
m.SetHeader("Subject", msg.Subject)
// CC
ccCount := len(msg.Cc)
if ccCount > 0 {
cc := make([]string, ccCount)
for i, address := range msg.Cc {
cc[i] = address.String()
}
m.SetHeader("Cc", cc...)
}
// BCC
bccCount := len(msg.Bcc)
if bccCount > 0 {
bcc := make([]string, bccCount)
for i, address := range msg.Bcc {
bcc[i] = address.String()
}
m.SetHeader("Bcc", bcc...)
}
m.SetBody("text/html", msg.HtmlBody)
slog.Info("dialing...", slog.String("host", t.Host), slog.Int("port", t.Port))
d := gomail.NewDialer(t.Host, t.Port, t.Username, t.Password)
if err := d.DialAndSend(m); err != nil {
return err
}
slog.Info("sent email %s" + msg.Subject)
return nil
}