sms_twilio.module in Twilio SMS Integration 7.2
Same filename and directory in other branches
Adds support for sending SMS messages using the Twilio gateway.
File
sms_twilio.moduleView source
<?php
use Twilio\Rest\Client;
use Twilio\Security\RequestValidator;
/**
* @file
* Adds support for sending SMS messages using the Twilio gateway.
*/
/**
* Implements 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',
),
);
}
function sms_twilio_init() {
}
/**
* 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' => !empty($configuration['sms_twilio_api_sid']) ? $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' => !empty($configuration['sms_twilio_api_auth_token']) ? $configuration['sms_twilio_api_auth_token'] : '',
);
$form['sms_twilio_number'] = array(
'#type' => 'textfield',
'#title' => t('Number / Message Service ID'),
'#description' => t('A <a href="https://www.twilio.com/user/account/phone-numbers" target="_new">phone number</a> from your Twilio account. You may also use a <a href="https://www.twilio.com/console/sms/services" target="_new">Message Service SID</a> for Copilot.'),
'#size' => 40,
'#maxlength' => 255,
'#default_value' => !empty($configuration['sms_twilio_number']) ? $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_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
if (isset($options['country'])) {
$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, NULL);
}
/**
* 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'];
}
// Set our AccountSid and AuthToken
$AccountSid = $config['sms_twilio_api_sid'];
$AuthToken = $config['sms_twilio_api_auth_token'];
// Include the PHP TwilioRest library
require_once DRUPAL_ROOT . '/' . $config['sms_twilio_path'] . '/autoload.php';
// Instantiate a new Twilio Rest Client
$client = new Client($AccountSid, $AuthToken);
switch ($command) {
case 'sendmsg':
$payload = array(
'body' => $data['message'],
);
if (strlen($config['sms_twilio_number']) == 34 && substr($config['sms_twilio_number'], 0, 2) == 'MG') {
$payload['messagingServiceSid'] = $config['sms_twilio_number'];
}
else {
$payload['from'] = $config['sms_twilio_number'];
}
$response = $client->messages
->create($data['number'], $payload);
break;
}
watchdog('sms_twilio', print_r($response, TRUE));
// Check for HTTP errors
if ($response->errorCode != '') {
$result = array(
'status' => FALSE,
'message' => t('An error occurred during the HTTP request: @error_code: @error. Please see <a href="@twilio_url">the Twilio docs</a> for more information', array(
'@error_code' => $response->errorCode,
'@error' => $response->errorMessage,
'@twilio_url' => 'https://www.twilio.com/docs/api/rest/message#error-values',
)),
);
watchdog('sms_twilio', $result['message']);
}
else {
$result = array(
'status' => TRUE,
'data' => t('Message sent to @number', array(
'@number' => $data['number'],
)),
);
}
return $result;
}
/**
* Implements 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() {
if (sms_twilio_validate_incoming_request_parameters()) {
if (sms_twilio_validate_incoming()) {
watchdog('sms_twilio', 'Handling incoming sms from ' . check_plain($_REQUEST['From']) . ': ' . check_plain($_REQUEST['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(check_plain($_REQUEST['From']), check_plain($_REQUEST['Body']), $opts);
}
else {
watchdog('sms_twilio', 'Incoming sms from @from has a bad Twilio signature - dropping!', array(
'@from' => check_plain($_REQUEST['From']),
), WATCHDOG_WARNING);
}
}
else {
watchdog('sms_twilio', 'Invalid parameters received.');
}
}
/**
* Validate incoming messages using Twilio SDK security methods
*
* @see http://www.twilio.com/docs/security
*
* @todo Need better way to test, as a service such as ngrok won't work without
* specifying in $url. Perhaps allow a configurable debugging setup which
* accepts an alternative URL.
*/
function sms_twilio_validate_incoming() {
global $base_url;
$url = $base_url . $_SERVER['REQUEST_URI'];
$gateway = sms_gateways('gateway', 'twilio');
$config = $gateway['configuration'];
if (!class_exists('RequestValidator')) {
require_once DRUPAL_ROOT . '/' . $config['sms_twilio_path'] . '/autoload.php';
}
$signature = $_SERVER["HTTP_X_TWILIO_SIGNATURE"];
$token = $config['sms_twilio_api_auth_token'];
$validator = new RequestValidator($token);
return $validator
->validate($signature, $url, $_REQUEST);
}
/**
* Validate incoming request has necessary parameters
*/
function sms_twilio_validate_incoming_request_parameters() {
return isset($_REQUEST['From']) && isset($_REQUEST['To']) && isset($_REQUEST['FromCountry']) && isset($_REQUEST['FromCity']) && isset($_REQUEST['FromState']) && isset($_REQUEST['FromZip']);
}
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_gateway_info | Implements hook_gateway_info(). |
sms_twilio_incoming | Informs the SMS Framework of the incoming SMS |
sms_twilio_init | |
sms_twilio_menu | Implements hook_menu(). |
sms_twilio_send | Callback for sending messages. |
sms_twilio_send_form | Returns custom additions to be added to the send forms |
sms_twilio_validate_incoming | Validate incoming messages using Twilio SDK security methods |
sms_twilio_validate_incoming_request_parameters | Validate incoming request has necessary parameters |