switch to plain net/smtp
This commit is contained in:
114
mailer.go
114
mailer.go
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user