-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTwilio.agent.lib.nut
161 lines (144 loc) · 5.85 KB
/
Twilio.agent.lib.nut
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
/*
The MIT License (MIT)
Copyright (c) 2014-19 Electric Imp, Inc.
Copyright (c) 2020-23 KORE Wireless
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
class Twilio {
static VERSION = "2.0.0";
static BASE_URL = "https://api.twilio.com/2010-04-01/Accounts/";
/*
* Private properties - do not access directly
*
*/
_accountSid = null;
_authToken = null;
_phoneNumber = null;
/*
* The constructor simply records the user's Twilio access credentals
*
* @constructor
*
*/
constructor(accountSid = null, authToken = null, phoneNumber = null) {
// Check supplied parameters
if (!_paramCheck(accountSid)) _bail("Twilio account SID");
if (!_paramCheck(authToken)) _bail("Twilio account auth token");
if (!_paramCheck(phoneNumber)) _bail("Twilio phone number");
// Set private properties
_accountSid = accountSid;
_authToken = authToken;
_phoneNumber = phoneNumber;
}
/*
* Send an SMS message via Twilio.
*
* @param {string} to - The target mobile phone number in E.164 format
* @param {string} message - The body of the message to send
* @param {function} callback - An optional function called when the message has been transmitted. Default: null
*
* @returns {table} The HTTPResponse table if no callback is specified, otherwise null
*
*/
function send(to, message, callback = null) {
// Assemble the request to Twilio
local url = BASE_URL + _accountSid + "/Messages";
local auth = http.base64encode(_accountSid + ":" + _authToken);
local headers = {"Authorization": "Basic " + auth};
local body = {"From": _phoneNumber, "To": to, "Body": message};
local request = http.post(url, headers, http.urlencode(body));
// Issue the request, synchronously or asynchronously
if (callback == null) return request.sendsync();
request.sendasync(callback);
}
/*
* Respond to a notification from Twilio that an SMS message was received.
* This is triggered by a webhook set on the Twilio dashboard
*
* @param {HTTPResponse} response - The system-assembled HTTPResponse to the original webhook-issued HTTPRequest
* @param {string} message - The body of the message to return via Twilio to the SMS source
*
*/
function respond(response, message) {
// Assemble the data to be sent back with the response
local data = {"Response": {"Message": message}};
if (message == null) data = { Response = "" }
local body = xmlEncode(data);
response.header("Content-Type", "text/xml");
response.send(200, body);
}
/*
* Encode a response body in the XML format Twilio expects (TWiML)
*
* @param {any} data - The body data
* @param {string} version - The XML version. Default: "1.0"
* @param {string} encoding - The XML file text encoding. Default: "UTF-8"
*
* @returns {string} The XML-encoded data
*/
function xmlEncode(data, version = "1.0", encoding = "UTF-8") {
return format("<?xml version=\"%s\" encoding=\"%s\" ?>%s", version, encoding, _recursiveEncode(data));
}
/******************** PRIVATE FUNCTIONS (DO NOT CALL) ********************/
/*
* Recursively convert Squirrel data structures into an XML string
*
* @param {any} data - The Squirrel data
*
* @returns {string} The SML data
*
* @private
*/
function _recursiveEncode(data) {
local s = "";
foreach(k, v in data) {
if (typeof(v) == "table" || typeof(v) == "array") {
s += format("<%s>%s</%s>", k.tostring(), _recursiveEncode(v), k.tostring());
} else if (v == null) {
s += format("<%s />", k.tostring());
} else {
s += format("<%s>%s</%s>", k.tostring(), v.tostring(), k.tostring());
}
}
return s;
}
/*
* Check the supplied constructor argument is of the correct type and not null
*
* @param {string} param - The constructor argument
*
* @returns {boolean} True if the argument is valid, otherwise false
*
* @private
*/
function _paramCheck(param) {
// Make sure the supplied
if (param == null || typeof param != "string" || param.len() == 0) return false;
return true;
}
/*
* Construct and throw an error if a method is supplied an invalid argument
*
* @param {string} reason - The reason for the error
* @param {string} method - The Twilio library method in which the error took place.
*
* @private
*/
function _bail(reason, method = "") {
throw "Twilio" + (method.len() > 0 ? "." + method : "") + "() requires a valid " + reason;
}
}