appidea-mailer/modules/mailer/mailer.go

164 lines
3.7 KiB
Go

package mailer
import (
"bytes"
"encoding/json"
"fmt"
"html/template"
"io/ioutil"
"net/smtp"
"strings"
"git.umbach.dev/app-idea/mailer/modules/config"
log "github.com/sirupsen/logrus"
)
var auth smtp.Auth
var cfg = &config.Cfg
func InitMailer() {
auth = smtp.PlainAuth("", cfg.Mail.User, cfg.Mail.Password, cfg.Mail.Host)
readTemplatesConfig()
loadTemplateFiles()
}
type Mail struct {
To []string
Subject string
TemplateId int
LanguageId int
BodyData interface{}
}
func NewMail(to []string, templateId int, languageId int, bodyData interface{}) {
log.Infoln("new mail", templateId, bodyData)
mail := Mail{
To: to,
Subject: "",
TemplateId: templateId,
LanguageId: languageId,
BodyData: bodyData,
}
body, err := mail.RenderTemplate()
log.Infoln("get body")
if err != nil {
log.Fatalln("error parsing", err)
}
mail.Send(body)
}
func (m *Mail) Send(body string) {
msg := "From: " + cfg.Mail.From + "\n" +
"To: " + strings.Join(m.To, ",") + "\n" +
"Subject: " + m.Subject + "\n" +
"MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n" +
body
err := smtp.SendMail(cfg.Mail.Host+":"+cfg.Mail.Port, auth, cfg.Mail.From, m.To, []byte(msg))
if err != nil {
log.Warnln("smtp error:", err)
} else {
log.Debugln("send mail")
}
}
type Templates struct {
Templates []Template `json:"templates"`
}
type Template struct {
Id int `json:"_id"`
FileName string `json:"fileName"`
Body string
Languages []Languages `json:"languages"`
}
type Languages struct {
Id int `json:"_id"`
Subject string `json:"subject"`
Texts map[string]interface{} `json:"texts"`
}
var templates Templates
func readTemplatesConfig() {
byteValue, err := ioutil.ReadFile(cfg.Templates.ConfigPath)
if err != nil {
log.Fatal(err)
}
err = json.Unmarshal(byteValue, &templates)
if err != nil {
log.Fatal("Failed to unmarshal templates config", err)
}
log.Debug("Checking the order of the ids in the template json file ...")
for t := 0; t < len(templates.Templates); t++ {
if templates.Templates[t].Id != t {
log.Fatalln("Id", templates.Templates[t].Id, "should be templateId", t)
}
for l := 0; l < len(templates.Templates[t].Languages); l++ {
if templates.Templates[t].Languages[l].Id != l {
log.Fatal("TemplateId: ", t, " -> Id", templates.Templates[t].Languages[l].Id, "should be languageId", l)
}
}
}
log.Debug("Template Ids all correct")
}
func loadTemplateFiles() {
log.Debugln("Starting the import of template files and their intermediate storage ...")
for i := 0; i < len(templates.Templates); i++ {
t := &templates.Templates[i]
data, err := ioutil.ReadFile(cfg.Templates.FolderPath + t.FileName + ".html")
if err != nil {
log.Fatalln("Failed to read template file -> id:", templates.Templates[i].Id, "name:", templates.Templates[i].FileName, "err:", err)
}
t.Body = string(data)
}
log.Debugln("Importing of template files finish")
}
func (m *Mail) RenderTemplate() (string, error) {
// define subject from config
m.Subject = templates.Templates[m.TemplateId].Languages[m.LanguageId].Subject
body := templates.Templates[m.TemplateId].Body
// replace body %values% with values in templates config
for key, value := range templates.Templates[m.TemplateId].Languages[m.LanguageId].Texts {
strKey := fmt.Sprintf("%v", key)
strValue := fmt.Sprintf("%v", value)
log.Infoln("a", strKey, strValue)
body = strings.Replace(body, "%"+strKey+"%", strValue, -1)
}
t := template.Must(template.New("").Parse(body))
buf := new(bytes.Buffer)
if err := t.Execute(buf, m.BodyData); err != nil {
log.Fatalln("Error executing body data", err)
}
return buf.String(), nil
}