emailing/mailer.go

93 lines
2.2 KiB
Go

package emailing
import (
"bytes"
"fmt"
"html/template"
"net/smtp"
"github.com/spf13/viper"
)
type Mailer struct {
TemplatesDir string
TemplatesConfig *viper.Viper
From string
Host string
Port int
Username string
Password string
}
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,
From: from,
Host: host,
Port: port,
Username: username,
Password: password,
}, nil
}
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("From: %s\nTo: %s\n", m.From, to)))
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)
fmt.Println(body.String())
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, templatesdir+f)
}
t := template.New("email").Funcs(
template.FuncMap{
"unescapeHTML": UnescapeHTML,
},
)
t = template.Must(t.ParseFiles(prefixed_files...))
if err := t.ExecuteTemplate(body, "main", data); err != nil {
return fmt.Errorf("failed execute mail template : %w", err)
}
return nil
}
func UnescapeHTML(s string) template.HTML {
return template.HTML(s)
}