switch to plain net/smtp

This commit is contained in:
2025-02-11 07:40:35 +01:00
parent ef6b8aaa24
commit 3c2744fb32
3 changed files with 44 additions and 131 deletions

114
mailer.go
View File

@@ -4,18 +4,15 @@ import (
"bytes"
"fmt"
"html/template"
"net/smtp"
"github.com/spf13/viper"
"github.com/wneessen/go-mail"
)
type Mailer struct {
TemplatesDir string
TemplatesConfig *viper.Viper
SMTPConfig
}
type SMTPConfig struct {
From string
Host string
Port int
@@ -23,98 +20,71 @@ type SMTPConfig struct {
Password string
}
type Option func(*mail.Msg, []mail.Option) ([]mail.Option, error)
func NewMailer(templates_dir string, tplcfg *viper.Viper, smtpconfig *viper.Viper) (*Mailer, error) {
var (
from = smtpconfig.GetString("from")
host = smtpconfig.GetString("host")
port = smtpconfig.GetInt("port")
username = smtpconfig.GetString("username")
password = smtpconfig.GetString("password")
)
return &Mailer{
TemplatesDir: templates_dir,
TemplatesConfig: tplcfg,
SMTPConfig: SMTPConfig{
From: smtpconfig.GetString("from"),
Host: smtpconfig.GetString("host"),
Port: smtpconfig.GetInt("port"),
Username: smtpconfig.GetString("username"),
Password: smtpconfig.GetString("password"),
},
From: from,
Host: host,
Port: port,
Username: username,
Password: password,
}, nil
}
func (m *Mailer) Send(emailcfg string, to string, data any, opts ...Option) error {
func (m *Mailer) Send(emailcfg string, to string, data any) error {
cfg := m.TemplatesConfig.Sub(emailcfg)
subject := cfg.GetString("subject")
files := cfg.GetStringSlice("files")
auth := smtp.PlainAuth("", m.Username, m.Password, m.Host)
var body bytes.Buffer
mimeHeaders := "MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n"
body.Write([]byte(fmt.Sprintf("Subject: %s \n%s\n\n", subject, mimeHeaders)))
if err := executeTemplate(&body, files, data, m.TemplatesDir); err != nil {
return fmt.Errorf("failed executing email template : %w", err)
}
smtpserver := fmt.Sprintf("%s:%d", m.Host, m.Port)
err := smtp.SendMail(smtpserver, auth, m.From, []string{to}, body.Bytes())
if err != nil {
return fmt.Errorf("isser sending email: %w", err)
}
return nil
}
func executeTemplate(body *bytes.Buffer, files []string, data any, templatesdir string) error {
prefixed_files := []string{}
for _, f := range files {
prefixed_files = append(prefixed_files, m.TemplatesDir+f)
prefixed_files = append(prefixed_files, templatesdir+f)
}
t := template.New("email").Funcs(
template.FuncMap{
"unescapeHTML": UnescapeHTML,
},
)
t = template.Must(t.ParseFiles(prefixed_files...))
buf := new(bytes.Buffer)
if err := t.ExecuteTemplate(buf, "main", data); err != nil {
if err := t.ExecuteTemplate(body, "main", data); err != nil {
return fmt.Errorf("failed execute mail template : %w", err)
}
body := buf.String()
message := mail.NewMsg()
fromAddress := m.SMTPConfig.From
if fromAddress == "" {
fromAddress = m.SMTPConfig.Username
}
fmt.Println("From : ", fromAddress)
if err := message.From(m.SMTPConfig.From); err != nil {
return fmt.Errorf("failed to set From header : %w", err)
}
if err := message.To(to); err != nil {
return fmt.Errorf("failed to set To header : %w", err)
}
message.Subject(cfg.GetString("subject"))
message.SetBodyString(mail.TypeTextHTML, body)
dialOptions := []mail.Option{
mail.WithSMTPAuth(mail.SMTPAuthAutoDiscover),
mail.WithTLSPolicy(mail.TLSOpportunistic),
// mail.WithSMTPAuth(mail.SMTPAuthNoAuth),
mail.WithUsername(m.SMTPConfig.Username),
mail.WithPassword(m.SMTPConfig.Password),
mail.WithPort(m.SMTPConfig.Port),
}
fmt.Println(dialOptions)
for _, opt := range opts {
no, err := opt(message, dialOptions)
if err != nil {
return fmt.Errorf("failed to set option : %w", err)
}
dialOptions = no
}
fmt.Println(dialOptions)
client, err := mail.NewClient(m.SMTPConfig.Host, dialOptions...)
if err != nil {
return fmt.Errorf("failed to create mail client : %w", err)
}
if err := client.DialAndSend(message); err != nil {
return fmt.Errorf("failed to send message : %w", err)
}
return nil
}
func WithReplyTo(email string) Option {
return func(m *mail.Msg, opts []mail.Option) ([]mail.Option, error) {
return opts, m.ReplyTo(email)
}
}
func UnescapeHTML(s string) template.HTML {
return template.HTML(s)
}