You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

116 lines
3.0 KiB

// 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 <https://www.gnu.org/licenses/>.
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)
}