-
Notifications
You must be signed in to change notification settings - Fork 0
/
mail.go
127 lines (102 loc) · 2.97 KB
/
mail.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package mail
import (
"bytes"
"errors"
"io"
"net/http"
"text/template"
)
// Mailer can be implemented for various services.
type Mailer interface {
// Send sends an email.
Send(*Mail) error
// Ping pings the address.
Ping() error
}
// TemplateMailer is a representation of mailer which compiles templates to email body (HTML and plain text).
type TemplateMailer interface {
Send(template *Template, config *Config) error
}
// HTTPClient is an interface for just the Post-method of *http.Mailer for easy mocking.
type HTTPClient interface {
// Post issues a POST to the specified URL.
Post(url string, contentType string, payload io.Reader) (*http.Response, error)
}
// Config is a configurable part of an email.
type Config struct {
// From is the name and email where this email is sent from.
From *Address
// To holds one or more recipients.
To []Address
// Subject holds the email subject.
Subject string
// Headers are standard email headers.
Headers map[string]interface{}
// Options can be a custom interface provided by the mailer implementation.
Options interface{}
}
// Mail is a mail you can send.
type Mail struct {
Config
// HTML will be displayed as html in the email.
HTML string
// Text will be displayed as plain text in the email.
Text string
}
// Address is an email/name combination.
type Address struct {
Name string
Email string
}
// Template holds all info needed for templates to compile to an email body.
type Template struct {
Data map[string]interface{}
TextPath string
HTMLPath string
}
// StandardTemplateMailer is a standard (default) implementation of template mailer interface.
type StandardTemplateMailer struct {
mailer Mailer
template *template.Template
}
// NewStandardTemplateMailer creates a new StandardTemplateMailer mailer.
func NewStandardTemplateMailer(mailer Mailer, templatePath string) (*StandardTemplateMailer, error) {
tpl, err := template.ParseGlob(templatePath)
if err != nil {
return nil, err
}
return &StandardTemplateMailer{
mailer: mailer,
template: tpl,
}, nil
}
// MustNewStandardTemplateMailer returns a new StandardTemplateMailer mailer or panics.
func MustNewStandardTemplateMailer(mailer Mailer, templatePath string) *StandardTemplateMailer {
tpl, err := NewStandardTemplateMailer(mailer, templatePath)
if err != nil {
panic(err)
}
return tpl
}
// Send sends an email.
func (m *StandardTemplateMailer) Send(template *Template, config *Config) error {
if config == nil {
return errors.New("config parameter is required")
}
if template == nil {
return errors.New("template parameter is required")
}
textBuf := &bytes.Buffer{}
if err := m.template.ExecuteTemplate(textBuf, template.TextPath, template.Data); err != nil {
return err
}
htmlBuf := &bytes.Buffer{}
if err := m.template.ExecuteTemplate(htmlBuf, template.HTMLPath, template.Data); err != nil {
return err
}
return m.mailer.Send(&Mail{
Config: *config,
HTML: htmlBuf.String(),
Text: textBuf.String(),
})
}