separate message from mailer

This commit is contained in:
dhax 2017-10-10 01:47:44 +02:00
parent 989f03040a
commit da481e9933
2 changed files with 51 additions and 46 deletions

View file

@ -14,13 +14,16 @@ type ContentLoginToken struct {
// LoginToken creates and sends a login token email with provided template content. // LoginToken creates and sends a login token email with provided template content.
func (m *Mailer) LoginToken(name, address string, content ContentLoginToken) error { func (m *Mailer) LoginToken(name, address string, content ContentLoginToken) error {
msg := &message{ msg := &message{
from: NewEmail(m.fromName, m.from), from: m.from,
to: NewEmail(name, address), to: NewEmail(name, address),
subject: "Login Token", subject: "Login Token",
template: "loginToken", template: "loginToken",
content: content, content: content,
} }
err := m.Send(msg) if err := msg.parse(); err != nil {
return err return err
} }
return m.Send(msg)
}

View file

@ -19,19 +19,18 @@ import (
var ( var (
debug bool debug bool
templates *template.Template
) )
// Mailer is a SMTP mailer. // Mailer is a SMTP mailer.
type Mailer struct { type Mailer struct {
client *gomail.Dialer client *gomail.Dialer
templates *template.Template from Email
from, fromName string
} }
// NewMailer returns a configured SMTP Mailer. // NewMailer returns a configured SMTP Mailer.
func NewMailer() (*Mailer, error) { func NewMailer() (*Mailer, error) {
templates, err := parseTemplates() if err := parseTemplates(); err != nil {
if err != nil {
return nil, err return nil, err
} }
@ -49,9 +48,7 @@ func NewMailer() (*Mailer, error) {
s := &Mailer{ s := &Mailer{
client: gomail.NewPlainDialer(smtp.Host, smtp.Port, smtp.User, smtp.Password), client: gomail.NewPlainDialer(smtp.Host, smtp.Port, smtp.User, smtp.Password),
templates: templates, from: NewEmail(viper.GetString("email_from_name"), viper.GetString("email_from_address")),
from: viper.GetString("email_from_address"),
fromName: viper.GetString("email_from_name"),
} }
if smtp.Host == "" { if smtp.Host == "" {
@ -61,36 +58,19 @@ func NewMailer() (*Mailer, error) {
} }
d, err := s.client.Dial() d, err := s.client.Dial()
if err != nil { if err == nil {
return nil, err
} else {
d.Close() d.Close()
}
return s, nil return s, nil
} }
return nil, err
}
// Send parses the corrsponding template and sends the mail via smtp. // Send sends the mail via smtp.
func (m *Mailer) Send(mail *message) error { func (m *Mailer) Send(mail *message) error {
buf := new(bytes.Buffer)
if err := m.templates.ExecuteTemplate(buf, mail.template, mail.content); err != nil {
return err
}
prem := premailer.NewPremailerFromString(buf.String(), premailer.NewOptions())
html, err := prem.Transform()
if err != nil {
return err
}
text, err := html2text.FromString(html, html2text.Options{PrettyTables: true})
if err != nil {
return err
}
if debug { if debug {
log.Println("To:", mail.to.Address) log.Println("To:", mail.to.Address)
log.Println("Subject:", mail.subject) log.Println("Subject:", mail.subject)
log.Println(text) log.Println(mail.text)
return nil return nil
} }
@ -98,8 +78,8 @@ func (m *Mailer) Send(mail *message) error {
msg.SetAddressHeader("From", mail.from.Address, mail.from.Name) msg.SetAddressHeader("From", mail.from.Address, mail.from.Name)
msg.SetAddressHeader("To", mail.to.Address, mail.to.Name) msg.SetAddressHeader("To", mail.to.Address, mail.to.Name)
msg.SetHeader("Subject", mail.subject) msg.SetHeader("Subject", mail.subject)
msg.SetBody("text/plain", text) msg.SetBody("text/plain", mail.text)
msg.AddAlternative("text/html", html) msg.AddAlternative("text/html", mail.html)
if err := m.client.DialAndSend(msg); err != nil { if err := m.client.DialAndSend(msg); err != nil {
return err return err
@ -109,11 +89,34 @@ func (m *Mailer) Send(mail *message) error {
// message struct holds all parts of a specific email message. // message struct holds all parts of a specific email message.
type message struct { type message struct {
from *Email from Email
to *Email to Email
subject string subject string
template string template string
content interface{} content interface{}
html string
text string
}
// parse parses the corrsponding template and content
func (m *message) parse() error {
buf := new(bytes.Buffer)
if err := templates.ExecuteTemplate(buf, m.template, m.content); err != nil {
return err
}
prem := premailer.NewPremailerFromString(buf.String(), premailer.NewOptions())
html, err := prem.Transform()
if err != nil {
return err
}
m.html = html
text, err := html2text.FromString(html, html2text.Options{PrettyTables: true})
if err != nil {
return err
}
m.text = text
return nil
} }
// Email struct holds email address and recipient name. // Email struct holds email address and recipient name.
@ -123,23 +126,22 @@ type Email struct {
} }
// NewEmail returns an email address. // NewEmail returns an email address.
func NewEmail(name string, address string) *Email { func NewEmail(name string, address string) Email {
return &Email{ return Email{
Name: name, Name: name,
Address: address, Address: address,
} }
} }
func parseTemplates() (*template.Template, error) { func parseTemplates() error {
tmpl := template.New("").Funcs(fMap) templates = template.New("").Funcs(fMap)
err := filepath.Walk("./templates", func(path string, info os.FileInfo, err error) error { return filepath.Walk("./templates", func(path string, info os.FileInfo, err error) error {
if strings.Contains(path, ".html") { if strings.Contains(path, ".html") {
_, err = tmpl.ParseFiles(path) _, err = templates.ParseFiles(path)
return err return err
} }
return err return err
}) })
return tmpl, err
} }
var fMap = template.FuncMap{ var fMap = template.FuncMap{