// Vikunja is a todo-list application to facilitate your life. // Copyright 2018 Vikunja and contributors. All rights reserved. // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . package mail import ( "bytes" "code.vikunja.io/api/pkg/utils" "github.com/labstack/gommon/log" "github.com/spf13/viper" "gopkg.in/gomail.v2" "text/template" ) // Opts holds infos for a mail type Opts struct { To string Subject string Message string HTMLMessage string ContentType ContentType Boundary string Headers []*header } // ContentType represents mail content types type ContentType int // Enumerate all the team rights const ( ContentTypePlain ContentType = iota ContentTypeHTML ContentTypeMultipart ) type header struct { Field string Content string } // SendMail puts a mail in the queue func SendMail(opts *Opts) { m := gomail.NewMessage() m.SetHeader("From", viper.GetString("mailer.fromemail")) m.SetHeader("To", opts.To) m.SetHeader("Subject", opts.Subject) for _, h := range opts.Headers { m.SetHeader(h.Field, h.Content) } switch opts.ContentType { case ContentTypePlain: m.SetBody("text/plain", opts.Message) case ContentTypeHTML: m.SetBody("text/html", opts.Message) case ContentTypeMultipart: m.SetBody("text/plain", opts.Message) m.AddAlternative("text/html", opts.HTMLMessage) } Queue <- m } // Template holds a pointer about a template type Template struct { Templates *template.Template } // SendMailWithTemplate parses a template and sends it via mail func SendMailWithTemplate(to, subject, tpl string, data map[string]interface{}) { var htmlContent bytes.Buffer var plainContent bytes.Buffer t := &Template{ Templates: template.Must(template.ParseGlob(viper.GetString("service.rootpath") + "/templates/mail/*.tmpl")), } boundary := "np" + utils.MakeRandomString(13) data["Boundary"] = boundary data["FrontendURL"] = viper.GetString("service.frontendurl") if err := t.Templates.ExecuteTemplate(&htmlContent, tpl+".html.tmpl", data); err != nil { log.Error(3, "Template: %v", err) return } if err := t.Templates.ExecuteTemplate(&plainContent, tpl+".plain.tmpl", data); err != nil { log.Error(3, "Template: %v", err) return } opts := &Opts{ To: to, Subject: subject, Message: plainContent.String(), HTMLMessage: htmlContent.String(), ContentType: ContentTypeMultipart, Boundary: boundary, } SendMail(opts) }