sms_twilio.module in Twilio SMS Integration 6
Same filename and directory in other branches
Adds support for sending SMS messages using the Twilio gateway.
File
sms_twilio.moduleView source
<?php
/**
* @file
* Adds support for sending SMS messages using the Twilio gateway.
*/
/**
* Implementation of hook_gateway_info().
*/
function sms_twilio_gateway_info() {
return array(
'twilio' => array(
'name' => 'Twilio',
'configure form' => 'sms_twilio_admin_form',
'receive' => TRUE,
'send' => 'sms_twilio_send',
'send form' => 'sms_twilio_send_form',
),
);
}
/**
* Admin/settings form.
*/
function sms_twilio_admin_form($configuration) {
$form['sms_twilio_api_sid'] = array(
'#type' => 'textfield',
'#title' => t('Account SID'),
'#description' => t('Twilio Account SID - the 34 character string beginning with AC'),
'#size' => 40,
'#maxlength' => 255,
'#default_value' => $configuration['sms_twilio_api_sid'],
);
$form['sms_twilio_api_auth_token'] = array(
'#type' => 'textfield',
'#title' => t('API ID'),
'#description' => t('Twilio auth token - <a href="https://www.twilio.com/user/account">available on your dashboard</a>'),
'#size' => 40,
'#maxlength' => 255,
'#default_value' => $configuration['sms_twilio_api_auth_token'],
);
$form['sms_twilio_number'] = array(
'#type' => 'textfield',
'#title' => t('Number'),
'#description' => t('A <a href="https://www.twilio.com/user/account/phone-numbers" target="_new">phone number</a> from your Twilio account'),
'#size' => 40,
'#maxlength' => 255,
'#default_value' => $configuration['sms_twilio_number'],
);
$form['sms_twilio_path'] = array(
'#type' => 'textfield',
'#title' => t('Twilio library path'),
'#description' => t('The path to the twilio library'),
'#size' => 40,
'#maxlength' => 255,
'#default_value' => !empty($configuration['sms_twilio_path']) ? $configuration['sms_twilio_path'] : 'sites/all/libraries/twilio',
);
return $form;
}
/**
* Validates the submission of the configuration form.
*/
function sms_twilio_admin_form_validate($form, &$form_state) {
}
/**
* Returns custom additions to be added to the send forms
*/
function sms_twilio_send_form() {
$form['country'] = array(
'#type' => 'select',
'#title' => t('Country'),
'#multiple' => FALSE,
'#options' => sms_twilio_country_codes(),
'#default_value' => -1,
);
return $form;
}
/**
* Callback for sending messages.
*/
function sms_twilio_send($number, $message, $options) {
$number = preg_replace("/[^0-9]/", '', $number);
$number = trim($number);
$number = ltrim($number, '0');
// Remove leading zeros
$index = strpos($number, $options['country']);
if ($index === FALSE || $index > 0) {
$number = $options['country'] . $number;
}
return sms_twilio_command('sendmsg', array(
'number' => $number,
'message' => $message,
), NULL, $account);
}
/**
* Executes a command using the Twilio API
*/
function sms_twilio_command($command = 'auth', $data = array(), $config = NULL, $account = '') {
if (!isset($config)) {
$gateway = sms_gateways('gateway', 'twilio');
$config = $gateway['configuration'];
}
// Include the PHP TwilioRest library
require_once $config['sms_twilio_path'] . '/twilio.php';
// Twilio REST API version
$ApiVersion = "2008-08-01";
// Set our AccountSid and AuthToken
$AccountSid = $config['sms_twilio_api_sid'];
$AuthToken = $config['sms_twilio_api_auth_token'];
// Instantiate a new Twilio Rest Client
$client = new TwilioRestClient($AccountSid, $AuthToken);
switch ($command) {
case 'sendmsg':
// Check if the message requires unicode handling
$response = $client
->request("/{$ApiVersion}/Accounts/{$AccountSid}/SMS/Messages", "POST", array(
"To" => $data['number'],
"From" => $config['sms_twilio_number'],
"Body" => $data['message'],
));
break;
}
watchdog('sms_twilio', print_r($response, TRUE));
// Check for HTTP errors
if ($response->IsError) {
$result = array(
'status' => FALSE,
'message' => t('An error occured during the HTTP request: @error', array(
'@error' => $response->ErrorMessage,
)),
);
}
else {
$result = array(
'status' => TRUE,
'data' => t('Message sent to @number', array(
'@number' => $data['number'],
)),
);
}
return $result;
}
/**
* @todo: this should be in the sms framework rather then each gateway needing
* to re-define this list.
*/
function sms_twilio_country_codes() {
return array(
93 => "Afghanistan",
355 => "Albania",
213 => "Algeria",
376 => "Andorra",
244 => "Angola",
1264 => "Anguilla",
1268 => "Antigua & Barbuda",
54 => "Argentina",
374 => "Armenia",
297 => "Aruba",
61 => "Australia",
43 => "Austria",
994 => "Azerbaijan",
1242 => "Bahamas",
973 => "Bahrain",
880 => "Bangladesh",
1246 => "Barbados",
375 => "Belarus",
32 => "Belgium",
501 => "Belize",
229 => "Benin",
1441 => "Bermuda",
975 => "Bhutan",
591 => "Bolivia",
387 => "Bosnia-Herzegovina",
267 => "Botswana",
55 => "Brazil",
1284 => "British Virgin Islands",
673 => "Brunei",
359 => "Bulgaria",
226 => "Burkina Faso",
257 => "Burundi",
855 => "Cambodia",
237 => "Cameroon",
34 => "Canary Islands",
238 => "Cape Verde",
1345 => "Cayman Islands",
236 => "Central African Republic",
235 => "Chad",
56 => "Chile",
86 => "China",
57 => "Colombia",
269 => "Comoros",
242 => "Congo",
243 => "Democratic Republic Congo",
682 => "Cook Islands",
385 => "Croatia",
53 => "Cuba",
357 => "Cyprus",
420 => "Czech Republic",
45 => "Denmark",
253 => "Djibouti",
1767 => "Dominica",
670 => "East Timor",
593 => "Ecuador",
20 => "Egypt",
503 => "El Salvador",
240 => "Equatorial Guinea",
372 => "Estonia",
251 => "Ethiopia",
500 => "Falkland Islands",
298 => "Faroe Islands",
679 => "Fiji",
358 => "Finland",
33 => "France",
594 => "French Guiana",
689 => "French Polynesia",
241 => "Gabon",
220 => "Gambia",
995 => "Georgia",
49 => "Germany",
233 => "Ghana",
350 => "Gibraltar",
881 => "Global Mobile Satellite",
30 => "Greece",
299 => "Greenland",
1473 => "Grenada",
590 => "Guadeloupe",
1671 => "Guam",
502 => "Guatemala",
224 => "Guinea",
592 => "Guyana",
509 => "Haiti",
504 => "Honduras",
852 => "HongKong",
36 => "Hungary",
354 => "Iceland",
91 => "India",
62 => "Indonesia",
98 => "Iran",
964 => "Iraq",
353 => "Ireland",
972 => "Israel",
39 => "Italy / Vatican City State",
225 => "Ivory Coast",
1876 => "Jamaica",
81 => "Japan",
962 => "Jordan",
254 => "Kenya",
82 => "Korea (South)",
965 => "Kuwait",
996 => "Kyrgyzstan",
856 => "Lao",
371 => "Latvia",
961 => "Lebanon",
266 => "Lesotho",
231 => "Liberia",
218 => "Libya",
423 => "Liechtenstein",
370 => "Lithuania",
352 => "Luxembourg",
853 => "Macau",
389 => "Macedonia",
261 => "Madagascar",
265 => "Malawi",
60 => "Malaysia",
960 => "Maldives",
223 => "Mali",
356 => "Malta",
596 => "Martinique",
222 => "Mauritania",
230 => "Mauritius",
269 => "Mayotte Island (Comoros)",
52 => "Mexico",
373 => "Moldova",
377 => "Monaco (Kosovo)",
976 => "Mongolia",
382 => "Montenegro",
1664 => "Montserrat",
212 => "Morocco",
258 => "Mozambique",
95 => "Myanmar",
264 => "Namibia",
977 => "Nepal",
31 => "Netherlands",
599 => "Netherlands Antilles",
687 => "New Caledonia",
64 => "New Zealand",
505 => "Nicaragua",
227 => "Niger",
234 => "Nigeria",
47 => "Norway",
968 => "Oman",
92 => "Pakistan",
970 => "Palestine (+970)",
9725 => "Palestine (+9725)",
507 => "Panama",
675 => "Papua New Guinea",
595 => "Paraguay",
51 => "Peru",
63 => "Philippines",
48 => "Poland",
351 => "Portugal",
974 => "Qatar",
262 => "Reunion",
40 => "Romania",
7 => "Russia / Kazakhstan",
250 => "Rwanda",
1670 => "Saipan",
1684 => "Samoa (American)",
685 => "Samoa (Western)",
378 => "San Marino",
882 => "Satellite-Thuraya",
966 => "Saudi Arabia",
221 => "Senegal",
381 => "Serbia",
248 => "Seychelles",
232 => "Sierra Leone",
65 => "Singapore",
421 => "Slovakia",
386 => "Slovenia",
252 => "Somalia",
27 => "South Africa",
34 => "Spain",
94 => "Sri Lanka",
1869 => "St. Kitts And Nevis",
1758 => "St. Lucia",
1784 => "St. Vincent",
249 => "Sudan",
597 => "Suriname",
268 => "Swaziland",
46 => "Sweden",
41 => "Switzerland",
963 => "Syria",
886 => "Taiwan",
992 => "Tajikistan",
255 => "Tanzania",
66 => "Thailand",
228 => "Togo",
676 => "Tonga Islands",
1868 => "Trinidad and Tobago",
216 => "Tunisia",
90 => "Turkey",
993 => "Turkmenistan",
1649 => "Turks and Caicos Islands",
256 => "Uganda",
44 => "UK / Isle of Man / Jersey / Guernsey",
380 => "Ukraine",
971 => "United Arab Emirates",
598 => "Uruguay",
1 => "USA / Canada / Dominican Rep. / Puerto Rico",
998 => "Uzbekistan",
678 => "Vanuatu",
58 => "Venezuela",
84 => "Vietnam",
967 => "Yemen",
260 => "Zambia",
255 => "Zanzibar",
263 => "Zimbabwe",
'' => "-- No country --",
);
}
/**
* Implementation of hook_menu().
*
* Twilio will POST to this path when an SMS is received
*/
function sms_twilio_menu() {
$items = array();
$items['sms/twilio/incoming'] = array(
'title' => 'Incoming Twilio SMS',
'page callback' => 'sms_twilio_incoming',
'access callback' => TRUE,
'menu_name' => 'SMS',
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Informs the SMS Framework of the incoming SMS
*/
function sms_twilio_incoming() {
global $base_url;
if (isset($_REQUEST['From']) and isset($_REQUEST['To']) and isset($_REQUEST['FromCountry']) and isset($_REQUEST['FromCity']) and isset($_REQUEST['FromState']) and isset($_REQUEST['FromZip'])) {
// Details on validating the Twilio signature: http://www.twilio.com/docs/security
$gateway = sms_gateways('gateway', 'twilio');
$config = $gateway['configuration'];
$string_to_sign = $base_url . "/sms/twilio/incoming";
ksort($_POST);
foreach ($_POST as $key => $value) {
$string_to_sign .= $key . $value;
}
$sig = base64_encode(hash_hmac("sha1", $string_to_sign, $config['sms_twilio_api_auth_token'], true));
$from = $_REQUEST['From'];
$body = $_REQUEST['Body'];
if (strcmp($_SERVER["HTTP_X_TWILIO_SIGNATURE"], $sig) != 0) {
watchdog('sms_twilio', 'Incoming sms from @from has a bad Twilio signature - dropping!', array(
'@from' => $from,
), WATCHDOG_WARNING);
}
else {
// watchdog('sms_twilio', 'Handling incoming sms from '.$from.': '.$body);
$opts = array();
$opts['to'] = $_REQUEST['To'];
$opts['fromcountry'] = $_REQUEST['FromCountry'];
$opts['fromcity'] = $_REQUEST['FromCity'];
$opts['fromstate'] = $_REQUEST['FromState'];
$opts['fromzip'] = $_REQUEST['FromZip'];
sms_incoming($from, $body, $opts);
}
}
}
Functions
Name | Description |
---|---|
sms_twilio_admin_form | Admin/settings form. |
sms_twilio_admin_form_validate | Validates the submission of the configuration form. |
sms_twilio_command | Executes a command using the Twilio API |
sms_twilio_country_codes | @todo: this should be in the sms framework rather then each gateway needing to re-define this list. |
sms_twilio_gateway_info | Implementation of hook_gateway_info(). |
sms_twilio_incoming | Informs the SMS Framework of the incoming SMS |
sms_twilio_menu | Implementation of hook_menu(). |
sms_twilio_send | Callback for sending messages. |
sms_twilio_send_form | Returns custom additions to be added to the send forms |