1
- // Package sendgrid provides a simple interface to interact with the Twilio SendGrid API
2
1
package sendgrid
3
2
4
3
import (
5
- "errors"
6
- "net/http"
7
- "strconv"
8
- "time"
9
-
10
- "github.com/sendgrid/rest" // depends on version 2.2.0
11
- "github.com/sendgrid/sendgrid-go/helpers/mail"
12
- )
13
-
14
- // Version is this client library's current version
15
- const (
16
- Version = "3.5.4"
17
- rateLimitRetry = 5
18
- rateLimitSleep = 1100
4
+ "github.com/sendgrid/rest"
19
5
)
20
6
21
- // Client is the Twilio SendGrid Go client
22
- type Client struct {
23
- // rest.Request
24
- rest.Request
25
- }
26
-
27
- // options for requestNew
28
- type options struct {
7
+ // sendGridOptions for CreateRequest
8
+ type sendGridOptions struct {
29
9
Key string
30
10
Endpoint string
31
11
Host string
32
12
Subuser string
33
13
}
34
14
35
- func (o * options ) baseURL () string {
36
- return o .Host + o .Endpoint
37
- }
38
-
39
15
// GetRequest
40
16
// @return [Request] a default request object
41
17
func GetRequest (key , endpoint , host string ) rest.Request {
42
- return requestNew ( options {key , endpoint , host , "" })
18
+ return createSendGridRequest ( sendGridOptions {key , endpoint , host , "" })
43
19
}
44
20
45
21
// GetRequestSubuser like GetRequest but with On-Behalf of Subuser
46
22
// @return [Request] a default request object
47
23
func GetRequestSubuser (key , endpoint , host , subuser string ) rest.Request {
48
- return requestNew ( options {key , endpoint , host , subuser })
24
+ return createSendGridRequest ( sendGridOptions {key , endpoint , host , subuser })
49
25
}
50
26
51
- // requestNew create Request
27
+ // createSendGridRequest create Request
52
28
// @return [Request] a default request object
53
- func requestNew (options options ) rest.Request {
54
- if options .Host == "" {
55
- options .Host = "https://api.sendgrid.com"
29
+ func createSendGridRequest (sgOptions sendGridOptions ) rest.Request {
30
+ options := options {
31
+ "Bearer " + sgOptions .Key ,
32
+ sgOptions .Endpoint ,
33
+ sgOptions .Host ,
34
+ sgOptions .Subuser ,
56
35
}
57
36
58
- requestHeaders := map [string ]string {
59
- "Authorization" : "Bearer " + options .Key ,
60
- "User-Agent" : "sendgrid/" + Version + ";go" ,
61
- "Accept" : "application/json" ,
62
- }
63
-
64
- if len (options .Subuser ) != 0 {
65
- requestHeaders ["On-Behalf-Of" ] = options .Subuser
66
- }
67
-
68
- return rest.Request {
69
- BaseURL : options .baseURL (),
70
- Headers : requestHeaders ,
37
+ if options .Host == "" {
38
+ options .Host = "https://api.sendgrid.com"
71
39
}
72
- }
73
40
74
- // Send sends an email through Twilio SendGrid
75
- func (cl * Client ) Send (email * mail.SGMailV3 ) (* rest.Response , error ) {
76
- cl .Body = mail .GetRequestBody (email )
77
- return MakeRequest (cl .Request )
41
+ return requestNew (options )
78
42
}
79
43
80
44
// NewSendClient constructs a new Twilio SendGrid client given an API key
@@ -91,74 +55,3 @@ func NewSendClientSubuser(key, subuser string) *Client {
91
55
request .Method = "POST"
92
56
return & Client {request }
93
57
}
94
-
95
- // DefaultClient is used if no custom HTTP client is defined
96
- var DefaultClient = rest .DefaultClient
97
-
98
- // API sets up the request to the Twilio SendGrid API, this is main interface.
99
- // Please use the MakeRequest or MakeRequestAsync functions instead.
100
- // (deprecated)
101
- func API (request rest.Request ) (* rest.Response , error ) {
102
- return MakeRequest (request )
103
- }
104
-
105
- // MakeRequest attempts a Twilio SendGrid request synchronously.
106
- func MakeRequest (request rest.Request ) (* rest.Response , error ) {
107
- return DefaultClient .Send (request )
108
- }
109
-
110
- // MakeRequestRetry a synchronous request, but retry in the event of a rate
111
- // limited response.
112
- func MakeRequestRetry (request rest.Request ) (* rest.Response , error ) {
113
- retry := 0
114
- var response * rest.Response
115
- var err error
116
-
117
- for {
118
- response , err = MakeRequest (request )
119
- if err != nil {
120
- return nil , err
121
- }
122
-
123
- if response .StatusCode != http .StatusTooManyRequests {
124
- return response , nil
125
- }
126
-
127
- if retry > rateLimitRetry {
128
- return nil , errors .New ("Rate limit retry exceeded" )
129
- }
130
- retry ++
131
-
132
- resetTime := time .Now ().Add (rateLimitSleep * time .Millisecond )
133
-
134
- reset , ok := response .Headers ["X-RateLimit-Reset" ]
135
- if ok && len (reset ) > 0 {
136
- t , err := strconv .Atoi (reset [0 ])
137
- if err == nil {
138
- resetTime = time .Unix (int64 (t ), 0 )
139
- }
140
- }
141
- time .Sleep (resetTime .Sub (time .Now ()))
142
- }
143
- }
144
-
145
- // MakeRequestAsync attempts a request asynchronously in a new go
146
- // routine. This function returns two channels: responses
147
- // and errors. This function will retry in the case of a
148
- // rate limit.
149
- func MakeRequestAsync (request rest.Request ) (chan * rest.Response , chan error ) {
150
- r := make (chan * rest.Response )
151
- e := make (chan error )
152
-
153
- go func () {
154
- response , err := MakeRequestRetry (request )
155
- if err != nil {
156
- e <- err
157
- }
158
- if response != nil {
159
- r <- response
160
- }
161
- }()
162
-
163
- return r , e
164
- }
0 commit comments