mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Email: add reply-to and direct attachment (#18715)
* Add support for `Reply-To` header * Allow direct attachment Don't have tests yet, but they will follow
This commit is contained in:
parent
e5e7bd3153
commit
c5bca40566
@ -5,15 +5,25 @@ import "errors"
|
||||
var ErrInvalidEmailCode = errors.New("Invalid or expired email code")
|
||||
var ErrSmtpNotEnabled = errors.New("SMTP not configured, check your grafana.ini config file's [smtp] section")
|
||||
|
||||
type SendEmailCommand struct {
|
||||
To []string
|
||||
Template string
|
||||
Subject string
|
||||
Data map[string]interface{}
|
||||
Info string
|
||||
EmbededFiles []string
|
||||
// SendEmailAttachFile is a definition of the attached files without path
|
||||
type SendEmailAttachFile struct {
|
||||
Name string
|
||||
Content []byte
|
||||
}
|
||||
|
||||
// SendEmailCommand is command for sending emails
|
||||
type SendEmailCommand struct {
|
||||
To []string
|
||||
Template string
|
||||
Subject string
|
||||
Data map[string]interface{}
|
||||
Info string
|
||||
ReplyTo []string
|
||||
EmbededFiles []string
|
||||
AttachedFiles []*SendEmailAttachFile
|
||||
}
|
||||
|
||||
// SendEmailCommandSync is command for sending emails in sync
|
||||
type SendEmailCommandSync struct {
|
||||
SendEmailCommand
|
||||
}
|
||||
|
@ -5,13 +5,22 @@ import (
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
// AttachedFile is struct representating email attached files
|
||||
type AttachedFile struct {
|
||||
Name string
|
||||
Content []byte
|
||||
}
|
||||
|
||||
// Message is representation of the email message
|
||||
type Message struct {
|
||||
To []string
|
||||
From string
|
||||
Subject string
|
||||
Body string
|
||||
Info string
|
||||
EmbededFiles []string
|
||||
To []string
|
||||
From string
|
||||
Subject string
|
||||
Body string
|
||||
Info string
|
||||
ReplyTo []string
|
||||
EmbededFiles []string
|
||||
AttachedFiles []*AttachedFile
|
||||
}
|
||||
|
||||
func setDefaultTemplateData(data map[string]interface{}, u *m.User) {
|
||||
|
@ -9,13 +9,15 @@ import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
gomail "gopkg.in/mail.v2"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util/errutil"
|
||||
gomail "gopkg.in/mail.v2"
|
||||
)
|
||||
|
||||
func (ns *NotificationService) send(msg *Message) (int, error) {
|
||||
@ -30,8 +32,11 @@ func (ns *NotificationService) send(msg *Message) (int, error) {
|
||||
m.SetHeader("From", msg.From)
|
||||
m.SetHeader("To", address)
|
||||
m.SetHeader("Subject", msg.Subject)
|
||||
for _, file := range msg.EmbededFiles {
|
||||
m.Embed(file)
|
||||
|
||||
ns.setFiles(m, msg)
|
||||
|
||||
for _, replyTo := range msg.ReplyTo {
|
||||
m.SetAddressHeader("Reply-To", replyTo, "")
|
||||
}
|
||||
|
||||
m.SetBody("text/html", msg.Body)
|
||||
@ -48,6 +53,23 @@ func (ns *NotificationService) send(msg *Message) (int, error) {
|
||||
return num, err
|
||||
}
|
||||
|
||||
// setFiles attaches files in various forms
|
||||
func (ns *NotificationService) setFiles(
|
||||
m *gomail.Message,
|
||||
msg *Message,
|
||||
) {
|
||||
for _, file := range msg.EmbededFiles {
|
||||
m.Embed(file)
|
||||
}
|
||||
|
||||
for _, file := range msg.AttachedFiles {
|
||||
m.Attach(file.Name, gomail.SetCopyFunc(func(writer io.Writer) error {
|
||||
_, err := writer.Write(file.Content)
|
||||
return err
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
func (ns *NotificationService) createDialer() (*gomail.Dialer, error) {
|
||||
host, port, err := net.SplitHostPort(ns.Cfg.Smtp.Host)
|
||||
|
||||
@ -127,10 +149,27 @@ func (ns *NotificationService) buildEmailMessage(cmd *models.SendEmailCommand) (
|
||||
}
|
||||
|
||||
return &Message{
|
||||
To: cmd.To,
|
||||
From: fmt.Sprintf("%s <%s>", ns.Cfg.Smtp.FromName, ns.Cfg.Smtp.FromAddress),
|
||||
Subject: subject,
|
||||
Body: buffer.String(),
|
||||
EmbededFiles: cmd.EmbededFiles,
|
||||
To: cmd.To,
|
||||
From: fmt.Sprintf("%s <%s>", ns.Cfg.Smtp.FromName, ns.Cfg.Smtp.FromAddress),
|
||||
Subject: subject,
|
||||
Body: buffer.String(),
|
||||
EmbededFiles: cmd.EmbededFiles,
|
||||
AttachedFiles: buildAttachedFiles(cmd.AttachedFiles),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// buildAttachedFiles build attached files
|
||||
func buildAttachedFiles(
|
||||
attached []*models.SendEmailAttachFile,
|
||||
) []*AttachedFile {
|
||||
result := make([]*AttachedFile, 0)
|
||||
|
||||
for _, file := range attached {
|
||||
result = append(result, &AttachedFile{
|
||||
Name: file.Name,
|
||||
Content: file.Content,
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user