forked from sfreiberg/gotwilio
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gotwilio.go
161 lines (137 loc) · 4.32 KB
/
gotwilio.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Package gotwilio is a library for interacting with http://www.twilio.com/ API.
package gotwilio
import (
"encoding/json"
"fmt"
"context"
"net/http"
"net/url"
"path"
"strings"
"time"
)
const (
baseURL = "https://api.twilio.com/2010-04-01"
videoURL = "https://video.twilio.com"
lookupURL = "https://lookups.twilio.com/v1" // https://www.twilio.com/docs/lookup/api
priceURL = "https://pricing.twilio.com/v1"
clientTimeout = time.Second * 30
)
// The default http.Client that is used if none is specified
var defaultClient = &http.Client{
Timeout: time.Second * 30,
}
// Twilio stores basic information important for connecting to the
// twilio.com REST api such as AccountSid and AuthToken.
type Twilio struct {
AccountSid string
AuthToken string
BaseUrl string
VideoUrl string
LookupURL string
PriceUrl string
HTTPClient *http.Client
APIKeySid string
APIKeySecret string
}
// Exception is a representation of a twilio exception.
type Exception struct {
Status int `json:"status"` // HTTP specific error code
Message string `json:"message"` // HTTP error message
Code ExceptionCode `json:"code"` // Twilio specific error code
MoreInfo string `json:"more_info"` // Additional info from Twilio
}
// Print the RESTException in a human-readable form.
func (r Exception) Error() string {
var errorCode ExceptionCode
var status int
if r.Code != errorCode {
return fmt.Sprintf("Code %d: %s", r.Code, r.Message)
} else if r.Status != status {
return fmt.Sprintf("Status %d: %s", r.Status, r.Message)
}
return r.Message
}
// Create a new Twilio struct.
func NewTwilioClient(accountSid, authToken string) *Twilio {
return NewTwilioClientCustomHTTP(accountSid, authToken, nil)
}
// Create a new Twilio client, optionally using a custom http.Client
func NewTwilioClientCustomHTTP(accountSid, authToken string, HTTPClient *http.Client) *Twilio {
if HTTPClient == nil {
HTTPClient = defaultClient
}
return &Twilio{
AccountSid: accountSid,
AuthToken: authToken,
BaseUrl: baseURL,
VideoUrl: videoURL,
LookupURL: lookupURL,
PriceUrl: priceURL,
HTTPClient: HTTPClient,
}
}
func (twilio *Twilio) WithAPIKey(apiKeySid string, apiKeySecret string) *Twilio {
twilio.APIKeySid = apiKeySid
twilio.APIKeySecret = apiKeySecret
return twilio
}
func (twilio *Twilio) getJSON(url string, result interface{}) error {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return fmt.Errorf("failed to create request: %v", err)
}
req.SetBasicAuth(twilio.getBasicAuthCredentials())
resp, err := twilio.do(req)
if err != nil {
return fmt.Errorf("failed to submit HTTP request: %v", err)
}
if resp.StatusCode != 200 {
re := Exception{}
json.NewDecoder(resp.Body).Decode(&re)
return re
}
return json.NewDecoder(resp.Body).Decode(&result)
}
func (twilio *Twilio) getBasicAuthCredentials() (string, string) {
if twilio.APIKeySid != "" {
return twilio.APIKeySid, twilio.APIKeySecret
}
return twilio.AccountSid, twilio.AuthToken
}
func (twilio *Twilio) post(ctx context.Context, formValues url.Values, twilioUrl string) (*http.Response, error) {
req, err := http.NewRequestWithContext(ctx, "POST", twilioUrl, strings.NewReader(formValues.Encode()))
if err != nil {
return nil, err
}
req.SetBasicAuth(twilio.getBasicAuthCredentials())
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
return twilio.do(req)
}
func (twilio *Twilio) get(ctx context.Context, twilioUrl string) (*http.Response, error) {
req, err := http.NewRequestWithContext(ctx, "GET", twilioUrl, nil)
if err != nil {
return nil, err
}
req.SetBasicAuth(twilio.getBasicAuthCredentials())
return twilio.do(req)
}
func (twilio *Twilio) delete(ctx context.Context, twilioUrl string) (*http.Response, error) {
req, err := http.NewRequestWithContext(ctx, "DELETE", twilioUrl, nil)
if err != nil {
return nil, err
}
req.SetBasicAuth(twilio.getBasicAuthCredentials())
return twilio.do(req)
}
func (twilio *Twilio) do(req *http.Request) (*http.Response, error) {
client := twilio.HTTPClient
if client == nil {
client = defaultClient
}
return client.Do(req)
}
// Build path to a resource within the Twilio account
func (twilio *Twilio) buildUrl(resourcePath string) string {
return twilio.BaseUrl + "/" + path.Join("Accounts", twilio.AccountSid, resourcePath)
}