1
0
mirror of https://github.com/pocketbase/pocketbase.git synced 2025-01-10 00:43:36 +02:00
pocketbase/tools/mailer/smtp.go

111 lines
2.2 KiB
Go

package mailer
import (
"fmt"
"net/smtp"
"strings"
"github.com/domodwyer/mailyak/v3"
"github.com/pocketbase/pocketbase/tools/security"
)
var _ Mailer = (*SmtpClient)(nil)
// NewSmtpClient creates new `SmtpClient` with the provided configuration.
func NewSmtpClient(
host string,
port int,
username string,
password string,
tls bool,
) *SmtpClient {
return &SmtpClient{
host: host,
port: port,
username: username,
password: password,
tls: tls,
}
}
// SmtpClient defines a SMTP mail client structure that implements
// `mailer.Mailer` interface.
type SmtpClient struct {
host string
port int
username string
password string
tls bool
}
// Send implements `mailer.Mailer` interface.
func (c *SmtpClient) Send(m *Message) error {
var smtpAuth smtp.Auth
if c.username != "" || c.password != "" {
smtpAuth = smtp.PlainAuth("", c.username, c.password, c.host)
}
// create mail instance
var yak *mailyak.MailYak
if c.tls {
var tlsErr error
yak, tlsErr = mailyak.NewWithTLS(fmt.Sprintf("%s:%d", c.host, c.port), smtpAuth, nil)
if tlsErr != nil {
return tlsErr
}
} else {
yak = mailyak.New(fmt.Sprintf("%s:%d", c.host, c.port), smtpAuth)
}
if m.From.Name != "" {
yak.FromName(m.From.Name)
}
yak.From(m.From.Address)
yak.To(m.To.Address)
yak.Subject(m.Subject)
yak.HTML().Set(m.HTML)
if m.Text == "" {
// try to generate a plain text version of the HTML
if plain, err := html2Text(m.HTML); err == nil {
yak.Plain().Set(plain)
}
} else {
yak.Plain().Set(m.Text)
}
if len(m.Bcc) > 0 {
yak.Bcc(m.Bcc...)
}
if len(m.Cc) > 0 {
yak.Cc(m.Cc...)
}
// add attachements (if any)
for name, data := range m.Attachments {
yak.Attach(name, data)
}
// add custom headers (if any)
var hasMessageId bool
for k, v := range m.Headers {
if strings.EqualFold(k, "Message-ID") {
hasMessageId = true
}
yak.AddHeader(k, v)
}
if !hasMessageId {
// add a default message id if missing
fromParts := strings.Split(m.From.Address, "@")
if len(fromParts) == 2 {
yak.AddHeader("Message-ID", fmt.Sprintf("<%s@%s>",
security.PseudorandomString(15),
fromParts[1],
))
}
}
return yak.Send()
}