Skip to content

Commit 79a1921

Browse files
committed
Email: tls support
Signed-off-by: Vishal Rana <[email protected]>
1 parent f72d3c8 commit 79a1921

File tree

1 file changed

+64
-31
lines changed

1 file changed

+64
-31
lines changed

email/email.go

Lines changed: 64 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,54 @@ package email
22

33
import (
44
"bytes"
5+
"crypto/tls"
56
"fmt"
67
"html/template"
78
"net/mail"
89
"net/smtp"
910

11+
"net"
12+
13+
"time"
14+
1015
"github.com/labstack/gommon/random"
1116
)
1217

1318
type (
1419
Email struct {
1520
Auth smtp.Auth
21+
Header map[string]string
1622
Template *template.Template
1723
smtpAddress string
1824
}
1925

2026
Message struct {
21-
From string
22-
To string
23-
CC string
24-
Subject string
25-
Text string
26-
HTML string
27-
TemplateName string
28-
TemplateData interface{}
29-
Inlines []*File
30-
Attachments []*File
27+
ID string `json:"id"`
28+
From string `json:"from"`
29+
To string `json:"to"`
30+
CC string `json:"cc"`
31+
Subject string `json:"subject"`
32+
Text string `json:"text"`
33+
HTML string `json:"html"`
34+
TemplateName string `json:"template_name"`
35+
TemplateData interface{} `json:"template_data"`
36+
Inlines []*File `json:"inlines"`
37+
Attachments []*File `json:"attachments"`
3138
buffer *bytes.Buffer
3239
boundary string
3340
}
3441

3542
File struct {
36-
Name string
37-
Type string
38-
Content string
43+
Name string `json:"name"`
44+
Type string `json:"type"`
45+
Content string `json:"content"`
3946
}
4047
)
4148

4249
func New(smtpAddress string) *Email {
4350
return &Email{
4451
smtpAddress: smtpAddress,
52+
Header: map[string]string{},
4553
}
4654
}
4755

@@ -62,20 +70,33 @@ func (m *Message) writeFile(f *File, disposition string) {
6270
m.buffer.WriteString(f.Content + "\r\n")
6371
}
6472

65-
func (e *Email) Send(m *Message) error {
73+
func (e *Email) Send(m *Message) (err error) {
74+
// Message header
6675
m.buffer = new(bytes.Buffer)
6776
m.boundary = random.String(16)
6877
m.buffer.WriteString("MIME-Version: 1.0\r\n")
69-
m.buffer.WriteString(fmt.Sprintf("CC: %s\r\n", m.CC))
70-
m.buffer.WriteString(fmt.Sprintf("Subject: %s\r\n", m.Subject))
78+
m.buffer.WriteString(fmt.Sprintf("Message-Id: %s\r\n", m.ID))
79+
m.buffer.WriteString(fmt.Sprintf("Date: %s\r\n", time.Now().Format(time.RFC1123Z)))
80+
m.buffer.WriteString(fmt.Sprintf("From: %s\r\n", m.From))
81+
m.buffer.WriteString(fmt.Sprintf("To: %s\r\n", m.From))
82+
if m.CC != "" {
83+
m.buffer.WriteString(fmt.Sprintf("CC: %s\r\n", m.CC))
84+
}
85+
if m.Subject != "" {
86+
m.buffer.WriteString(fmt.Sprintf("Subject: %s\r\n", m.Subject))
87+
}
88+
// Extra
89+
for k, v := range e.Header {
90+
m.buffer.WriteString(fmt.Sprintf("%s: %s\r\n", k, v))
91+
}
7192
m.buffer.WriteString(fmt.Sprintf("Content-Type: multipart/mixed; boundary=%s\r\n", m.boundary))
7293
m.buffer.WriteString("\r\n")
7394

7495
// Message body
7596
if m.TemplateName != "" {
7697
buf := new(bytes.Buffer)
77-
if err := e.Template.ExecuteTemplate(buf, m.TemplateName, m.TemplateData); err != nil {
78-
return err
98+
if err = e.Template.ExecuteTemplate(buf, m.TemplateName, m.TemplateData); err != nil {
99+
return
79100
}
80101
m.writeText(buf.String(), "text/html")
81102
} else if m.Text != "" {
@@ -96,39 +117,51 @@ func (e *Email) Send(m *Message) error {
96117
m.buffer.WriteString("\r\n")
97118
m.buffer.WriteString("--" + m.boundary + "--")
98119

99-
// Send message
120+
// Dial
100121
c, err := smtp.Dial(e.smtpAddress)
101-
if e.Auth != nil {
102-
// Authenticate
103-
if err := c.Auth(e.Auth); err != nil {
122+
if err != nil {
123+
return
124+
}
125+
defer c.Close()
126+
127+
// Check if TLS is required
128+
if ok, _ := c.Extension("STARTTLS"); ok {
129+
host, _, _ := net.SplitHostPort(e.smtpAddress)
130+
config := &tls.Config{ServerName: host}
131+
if err = c.StartTLS(config); err != nil {
104132
return err
105133
}
106134
}
107-
if err != nil {
108-
return err
135+
136+
// Authenticate
137+
if e.Auth != nil {
138+
if err = c.Auth(e.Auth); err != nil {
139+
return
140+
}
109141
}
110-
defer c.Close()
142+
143+
// Send message
111144
from, err := mail.ParseAddress(m.From)
112145
if err != nil {
113-
return err
146+
return
114147
}
115148
if err = c.Mail(from.Address); err != nil {
116-
return err
149+
return
117150
}
118151
to, err := mail.ParseAddressList(m.To)
119152
if err != nil {
120-
return err
153+
return
121154
}
122155
for _, a := range to {
123156
if err = c.Rcpt(a.Address); err != nil {
124-
return err
157+
return
125158
}
126159
}
127160
wc, err := c.Data()
128161
if err != nil {
129-
return err
162+
return
130163
}
131164
defer wc.Close()
132165
_, err = m.buffer.WriteTo(wc)
133-
return err
166+
return
134167
}

0 commit comments

Comments
 (0)