forked from sendgrid/sendgrid-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sendgrid.go
140 lines (122 loc) · 3.16 KB
/
sendgrid.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
128
129
130
131
132
133
134
135
136
137
138
139
140
// Package sendgrid provides a simple interface to interact with the SendGrid API
package sendgrid
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
"time"
)
const Version = "2.0.0"
// SGClient will contain the credentials and default values
type SGClient struct {
apiUser string
apiPwd string
APIMail string
timeout time.Duration
Client *http.Client
}
// NewSendGridClient will return a new SGClient. Used for username and password
func NewSendGridClient(apiUser, apiKey string) *SGClient {
apiMail := "https://api.sendgrid.com/api/mail.send.json?"
Client := &SGClient{
apiUser: apiUser,
apiPwd: apiKey,
APIMail: apiMail,
timeout: 5 * time.Second,
}
return Client
}
// NewSendGridClient will return a new SGClient. Used for api key
func NewSendGridClientWithApiKey(apiKey string) *SGClient {
apiMail := "https://api.sendgrid.com/api/mail.send.json?"
Client := &SGClient{
apiPwd: apiKey,
APIMail: apiMail,
}
return Client
}
func (sg *SGClient) buildURL(m *SGMail) (url.Values, error) {
values := url.Values{}
if sg.apiUser != "" {
values.Set("api_user", sg.apiUser)
values.Set("api_key", sg.apiPwd)
}
values.Set("subject", m.Subject)
values.Set("html", m.HTML)
values.Set("text", m.Text)
values.Set("from", m.From)
values.Set("replyto", m.ReplyTo)
apiHeaders, err := m.SMTPAPIHeader.JSONString()
if err != nil {
return nil, fmt.Errorf("sendgrid.go: error:%v", err)
}
values.Set("x-smtpapi", apiHeaders)
headers, err := m.HeadersString()
if err != nil {
return nil, fmt.Errorf("sendgrid.go: error: %v", err)
}
values.Set("headers", headers)
if len(m.FromName) != 0 {
values.Set("fromname", m.FromName)
}
for i := 0; i < len(m.To); i++ {
values.Add("to[]", m.To[i])
}
for i := 0; i < len(m.Cc); i++ {
values.Add("cc[]", m.Cc[i])
}
for i := 0; i < len(m.Bcc); i++ {
values.Add("bcc[]", m.Bcc[i])
}
for i := 0; i < len(m.ToName); i++ {
values.Add("toname[]", m.ToName[i])
}
for k, v := range m.Files {
values.Set("files["+k+"]", v)
}
for k, v := range m.Content {
values.Set("content["+k+"]", v)
}
return values, nil
}
// SetTimeout will set the timeout value for the http
// client connection. Default is 5 seconds
func (sg *SGClient) SetTimeout(timeout time.Duration) {
sg.timeout = timeout
}
// Send will send mail using SG web API
func (sg *SGClient) Send(m *SGMail) error {
if sg.Client == nil {
sg.Client = &http.Client{
Transport: http.DefaultTransport,
Timeout: sg.timeout,
}
}
var e error
values, e := sg.buildURL(m)
if e != nil {
return e
}
req, e := http.NewRequest("POST", sg.APIMail, strings.NewReader(values.Encode()))
if e != nil {
return e
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("User-Agent", "sendgrid/"+Version+";go")
// Using API key
if sg.apiUser == "" {
req.Header.Set("Authorization", "Bearer "+sg.apiPwd)
}
res, e := sg.Client.Do(req)
if e != nil {
return fmt.Errorf("sendgrid.go: error:%v; response:%v", e, res)
}
defer res.Body.Close()
if res.StatusCode == http.StatusOK {
return nil
}
body, _ := ioutil.ReadAll(res.Body)
return fmt.Errorf("sendgrid.go: code:%d error:%v body:%s", res.StatusCode, e, body)
}