-
Notifications
You must be signed in to change notification settings - Fork 0
/
mailer.go
116 lines (98 loc) · 2.43 KB
/
mailer.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
package mailer
import (
"crypto/tls"
"fmt"
"net/smtp"
)
// Config represents smtp configuration
type Config struct {
Host string
Port int
User string
Pass string
}
// Mailer is an interface with a Send method, that dispatches a single Mail
type Mailer interface {
Send(*Mail) error
}
// NewMailer returns a new Mailer using provided configuration
func NewMailer(config Config, ssl bool) Mailer {
var mailer Mailer
if ssl {
smtpssl := new(SMTPSLL)
smtpssl.Config = config
mailer = smtpssl
} else {
smtp := new(SMTP)
smtp.Config = config
mailer = smtp
}
return mailer
}
// SMTP client session object. If a server advertise STARTTLS, it
// will encrypt all further communication after initial handshake
type SMTP struct {
Config
}
// Send an email and waits for the process to end, giving proper error feedback
func (m *SMTP) Send(mail *Mail) (err error) {
server := fmt.Sprintf("%s:%d", m.Host, m.Port)
var auth smtp.Auth
// Set up authentication information.
if m.User != "" && m.Pass != "" {
auth = smtp.PlainAuth("", m.User, m.Pass, m.Host)
}
// Connect to the server, authenticate, set the sender and recipient,
// and send the email all in one step.
err = smtp.SendMail(server, auth, mail.From, mail.To, mail.Raw())
return
}
// SMTPSLL client session object for situations where SSL is required from
// the beginning of the connection and using STARTTLS is not appropriate
type SMTPSLL struct {
Config
}
// Send an email and waits for the process to end, giving proper error feedback
func (m *SMTPSLL) Send(mail *Mail) (err error) {
// TLS config
tlsconfig := &tls.Config{
InsecureSkipVerify: true,
ServerName: m.Host,
}
// Call tls.Dial instead of smtp.Dial for smtp servers running on 465
// that require an ssl connection from the very beginning (no starttls)
server := fmt.Sprintf("%s:%d", m.Host, m.Port)
conn, err := tls.Dial("tcp", server, tlsconfig)
if err != nil {
return
}
defer conn.Close()
c, err := smtp.NewClient(conn, m.Host)
if err != nil {
return
}
defer c.Quit()
// Set up authentication information.
auth := smtp.PlainAuth("", m.User, m.Pass, m.Host)
if err = c.Auth(auth); err != nil {
return
}
// Set sender and recipents
if err = c.Mail(mail.From); err != nil {
return
}
for _, rcpt := range mail.To {
c.Rcpt(rcpt)
}
// Data
w, err := c.Data()
if err != nil {
return
}
defer w.Close()
_, err = w.Write(mail.Raw())
if err != nil {
return
}
return nil
}