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 }