93 lines
2.2 KiB
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)
|
|
}
|