sms_txtlocal.module in SMS Framework 6
Txtlocal gateway module for Drupal SMS Framework. Outbound+Inbound
For inbound messaging you must configure Txtlocal to send messages to:
- http(s)://yourhost.example.com/sms/txtlocal/receiver
For receipts to work you must configure Txtlocal to send receipts to:
- http(s)://yourhost.example.com/sms/txtlocal/receipt
It is recommended that Clean URLs are on if you are using WAP PUSH, receipt functions or anything else that will handle a URL.
The send callback in this module supports several options, including message sender. Please see sms_txtlocal_send()
@package sms @subpackage sms_txtlocal
File
modules/sms_txtlocal/sms_txtlocal.moduleView source
<?php
/**
* @file
* Txtlocal gateway module for Drupal SMS Framework. Outbound+Inbound
*
* For inbound messaging you must configure Txtlocal to send messages to:
* - http(s)://yourhost.example.com/sms/txtlocal/receiver
*
* For receipts to work you must configure Txtlocal to send receipts to:
* - http(s)://yourhost.example.com/sms/txtlocal/receipt
*
* It is recommended that Clean URLs are on if you are using WAP PUSH, receipt
* functions or anything else that will handle a URL.
*
* The send callback in this module supports several options, including message
* sender. Please see sms_txtlocal_send()
*
* @package sms
* @subpackage sms_txtlocal
*/
/**
* Implement hook_gateway_info()
*
* @return
* SMS Framework gateway info array
*
* @ingroup hooks
*/
function sms_txtlocal_gateway_info() {
return array(
'txtlocal' => array(
'name' => 'Txtlocal',
'send' => 'sms_txtlocal_send',
'send form' => 'sms_txtlocal_send_form',
'configure form' => 'sms_txtlocal_admin_form',
'message_status_codes' => 'sms_txtlocal_message_status_codes',
),
);
}
/**
* Implement hook_menu()
*
* @return
* Drupal menu item array
*
* @ingroup hooks
*/
function sms_txtlocal_menu() {
$items = array();
$items['sms/txtlocal/receiver'] = array(
'title' => 'Txtlocal SMS message receiver',
'page callback' => 'sms_txtlocal_receive_message',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['sms/txtlocal/receipt'] = array(
'title' => 'Txtlocal SMS receipt receiver',
'page callback' => 'sms_txtlocal_receive_receipt',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Configuration form for gateway module
*
* @param $configuration
*
* @return
* Drupal form array
*/
function sms_txtlocal_admin_form($configuration) {
$form['sms_txtlocal_balance'] = array(
'#type' => 'item',
'#title' => t('Current balance'),
'#value' => sms_txtlocal_balance(),
);
$form['sms_txtlocal_user'] = array(
'#type' => 'textfield',
'#title' => t('Username'),
'#description' => t('The username of your Txtlocal account.'),
'#size' => 40,
'#maxlength' => 255,
'#default_value' => $configuration['sms_txtlocal_user'],
);
$form['sms_txtlocal_password'] = array(
'#type' => 'textfield',
'#title' => t('Password'),
'#description' => t('The current password on your Txtlocal account.'),
'#size' => 30,
'#maxlength' => 64,
'#default_value' => $configuration['sms_txtlocal_password'],
);
$form['sms_txtlocal_defaultsender'] = array(
'#type' => 'textfield',
'#title' => t('Default sender of SMS messages'),
'#description' => t('Required min=3 max=11 chars. May be an MSISDN or text. Will be used only if the SMS send call does not specify a sender.'),
'#size' => 11,
'#maxlength' => 11,
'#default_value' => $configuration['sms_txtlocal_defaultsender'] ? $configuration['sms_txtlocal_defaultsender'] : 'anonymous',
);
$form['sms_txtlocal_receipts'] = array(
'#type' => 'checkbox',
'#title' => t('Request message delivery receipts'),
'#description' => t('Click to enable receipt requests when messages are sent.'),
'#default_value' => $configuration['sms_txtlocal_receipts'] ? $configuration['sms_txtlocal_receipts'] : FALSE,
);
$form['sms_txtlocal_ssl'] = array(
'#type' => 'checkbox',
'#title' => t('Use SSL encyption'),
'#description' => t('SSL is recommended so you should at least try this. Requires that PHP has enabled OpenSSL support.'),
'#default_value' => $configuration['sms_txtlocal_ssl'] ? $configuration['sms_txtlocal_ssl'] : FALSE,
);
$form['sms_txtlocal_test'] = array(
'#type' => 'checkbox',
'#title' => t('Test mode'),
'#description' => t('If set, txtlocal will not actually perform actions and will not deduct credit.'),
'#default_value' => $configuration['sms_txtlocal_test'] ? $configuration['sms_txtlocal_test'] : FALSE,
);
return $form;
}
/**
* Validates the submission of the configuration form.
*
* @param $form
* @param $form_state
*/
function sms_txtlocal_admin_form_validate($form, &$form_state) {
if (empty($form_state['values']['sms_txtlocal_user'])) {
form_set_error('', t('You must specify a username.'));
}
if (empty($form_state['values']['sms_txtlocal_password'])) {
form_set_error('', t('You must specify a password.'));
}
if (strlen($form_state['values']['sms_txtlocal_defaultsender']) < 3) {
form_set_error('', t('The default sender must be at least 3 characters.'));
}
}
/**
* Returns custom additions to be added to the send forms
*
* @return
* Drupal form array
*/
function sms_txtlocal_send_form() {
$form = array();
return $form;
}
/**
* Callback for sending messages.
*
* Options for this send function: see also sms_txtlocal_command()
* - sender - The sender of the message. MSISDN or text string. Min=3, max=11 chars.
* - reference - Message reference tag (to appear on any receipt).
* - delaymins - Minutes to delay message send.
* - url - Full URL for a WAP PUSH message.
*
* @param $number
* MSISDN of message recipient. Expected to include the country code prefix.
* @param $message
* Message body text.
* @param $options
* Options array from SMS Framework.
*
* @return
* Response from sms_txtlocal_command()
*/
function sms_txtlocal_send($number, $message, $options) {
return sms_txtlocal_command('sendmsg', array(
'number' => $number,
'message' => $message,
'options' => $options,
));
}
/**
* Get account balance
*
* @return
* Balance text
*/
function sms_txtlocal_balance() {
$result = sms_txtlocal_command('getbalance');
return $result['gateway_status_text'];
}
/**
* Executes a command using the Txtlocal API
*
* data array fields:
* - number - MSISDN of message recipient. Purely numeric and must begin with intl prefix, eg. 4477121231234. May be a comma-separated list.
* - message - Message text. Max 612 chars (4x SMS). Use %n for newline.
* - sender - Optional: Sender ID may be an MSISDN or a string. Min=3, max=11 chars.
* - url - Optional: May be used to send a WAP PUSH. 'url' param for txtlocal.
* - reference - Optional: Reference tag to apply to message. Will appear on any receipt. 'custom' param for txtlocal.
* - delaymins - Optional: Delay message sending by N minutes. Formatted into a future timestamp for 'shed' param in txtlocal.
*
* @param $command
* One of 'sendmsg' or 'getbalance'.
* @param $data
* All data required to perform the command.
* @param $config
* Configuration parameters.
*
* @return
* Whether the command succeeded or not.
*/
function sms_txtlocal_command($command = 'sendmsg', $data = array(), $config = NULL) {
$gateway = sms_gateways('gateway', 'txtlocal');
// Get config
if ($config == NULL) {
$config = $gateway['configuration'];
}
// SSL
if ($config['sms_txtlocal_ssl'] === 1) {
$scheme = 'https';
}
else {
$scheme = 'http';
}
// Test mode
if ($config['sms_txtlocal_test']) {
$test = '1';
}
else {
$test = '0';
}
// Preparing the URLs
$url = $scheme . "://www.txtlocal.com/";
$url_send = $url . "sendsmspost.php";
$url_balance = $url . "getcredits.php";
switch ($command) {
case 'sendmsg':
// Txtlocal requires us to specify a sender
if (isset($data) && array_key_exists('options', $data) && array_key_exists('sender', $data['options'])) {
$sender = $data['options']['sender'];
}
else {
$sender = $config['sms_txtlocal_defaultsender'];
}
// Prepare required arguments
$post_data = array(
'uname' => $config['sms_txtlocal_user'],
'pword' => $config['sms_txtlocal_password'],
'message' => $data['message'],
'from' => $sender,
'selectednums' => $data['number'],
'info' => '1',
// We need this debug on to realise errors from txtlocal.
'test' => $test,
);
// Request delivery receipts
if ($config['sms_txtlocal_receipts']) {
$post_data['rcpurl'] = url('sms/txtlocal/receipt', array(
'absolute' => TRUE,
));
}
// Add any optional arguments
if (isset($data) && array_key_exists('options', $data)) {
if (array_key_exists('url', $data['options'])) {
$post_data['url'] = $data['options']['url'];
}
if (array_key_exists('reference', $data['options'])) {
$post_data['custom'] = $data['options']['reference'];
}
if (array_key_exists('delaymins', $data['options']) && $data['options']['delaymins'] > 5) {
$delay_until = gmmktime() + $data['options']['delaymins'] * 60;
$post_data['shed'] = date('Y-m-d-G-i-s', $delay_until);
}
}
// Run the command
// I tried to use http_build_query() here, but it kept adding '&' as
// '&' which killed the query.
foreach ($post_data as $key => $value) {
$content .= $key . "=" . $value . "&";
}
$headers = array(
'Content-Type' => 'application/x-www-form-urlencoded',
);
$http_result = drupal_http_request($url_send, $headers, 'POST', $content);
break;
case 'getbalance':
$post_data = array(
'uname' => $config['sms_txtlocal_user'],
'pword' => $config['sms_txtlocal_password'],
);
// I tried to use http_build_query() here, but it kept adding '&' as
// '&' which killed the query.
foreach ($post_data as $key => $value) {
$content .= $key . "=" . $value . "&";
}
$headers = array(
'Content-Type' => 'application/x-www-form-urlencoded',
);
$http_result = drupal_http_request($url_balance, $headers, 'POST', $content);
break;
}
// Check for HTTP errors
if ($http_result->error) {
return array(
'status' => FALSE,
'message' => t('An error occured during the HTTP request: @error', array(
'@error' => $http_result->error,
)),
);
}
if ($http_result->data) {
// Check for txtlocal errors
if (strpos($http_result->data, 'ERROR') !== FALSE) {
// There was an error
$result = array(
'status' => FALSE,
'status_code' => SMS_GW_ERR_OTHER,
// todo Try to map error codes
'gateway_status_code' => '',
// todo Try to map error codes
'gateway_status_text' => $http_result->data,
);
}
else {
// Prepare a good response array
$result = array(
'status' => TRUE,
'status_code' => SMS_GW_OK,
'gateway_status_code' => '',
// todo Try to map error codes
'gateway_status_text' => $http_result->data,
);
}
}
return $result;
}
/**
* Receive an SMS message and pass it into the SMS Framework
*/
function sms_txtlocal_receive_message() {
$number = $_REQUEST['sender'];
$message = $_REQUEST['content'];
$options = array();
// Define raw gateway response parameters
$options['gateway_params'] = array();
if (array_key_exists('inNumber', $_REQUEST) && !empty($_REQUEST['inNumber'])) {
$options['gateway_params']['inNumber'] = $_REQUEST['inNumber'];
}
// Define message receiver if possible
if (array_key_exists('inNumber', $_REQUEST) && !empty($_REQUEST['inNumber'])) {
$options['receiver'] = $_REQUEST['inNumber'];
}
sms_incoming($number, $message, $options);
}
/**
* Receive a message send receipt from txtlocal
*
* Will generate an $options array with the following variables:
* - reference - A message reference code, if set on message send.
* - gateway_status - A txtlocal message status code.
* - gateway_status_text - A text string associated with the gateway_status.
* - customID - Same as reference. txtlocal param: 'customID'
*
* See http://www.txtlocal.co.uk/sms-gateway-demo.php
*/
function sms_txtlocal_receive_receipt() {
if ($config['sms_txtlocal_receipts']) {
$number = array_key_exists('number', $_REQUEST) ? $_REQUEST['number'] : NULL;
$reference = array_key_exists('customID', $_REQUEST) ? $_REQUEST['customID'] : NULL;
$gw_msg_status_code = array_key_exists('status', $_REQUEST) ? $_REQUEST['status'] : NULL;
$options = array();
// Define raw gateway receipt call parameters
$options['gateway_params'] = array();
if (array_key_exists('number', $_REQUEST) && !empty($_REQUEST['number'])) {
$options['gateway_params']['number'] = $_REQUEST['number'];
}
if (array_key_exists('customID', $_REQUEST) && !empty($_REQUEST['customID'])) {
$options['gateway_params']['customID'] = $_REQUEST['customID'];
}
// Define message receiver and reference in options array
$options['reference'] = $reference;
// Get framework message status code and Clickatell status text
$status = sms_txtlocal_map_message_status_code($gw_msg_status_code);
$gw_msg_status_codes = sms_txtlocal_message_status_codes();
$gw_msg_status_text = $gw_msg_status_codes[$gw_msg_status_code];
// Define gateway-specific status (code) and text (success/error message)
$options['gateway_message_status'] = $gw_msg_status_code;
$options['gateway_message_status_text'] = $gw_msg_status_text;
// Invoke the SMS Framework receipt handler
sms_receipt($number, $reference, $status, $options);
}
}
/**
* Map a Txtlocal message status code to an SMS Framework message status code
*
* @return
* SMS Framework message status code.
*/
function sms_txtlocal_map_message_status_code($code) {
switch ($code) {
case 'D':
return SMS_MSG_STATUS_DELIVERED;
case 'I':
return SMS_MSG_STATUS_ERROR;
case 'U':
return SMS_MSG_STATUS_EXPIRED;
}
}
/**
* Returns an array of message status codes and strings that are generated by the txtlocal gateway
*
* @return array Associative array of message status codes and text strings.
*/
function sms_txtlocal_message_status_codes() {
return array(
'D' => 'Delivered',
'I' => 'Invalid',
'U' => 'Undelivered after 72 hours',
);
}
Functions
Name | Description |
---|---|
sms_txtlocal_admin_form | Configuration form for gateway module |
sms_txtlocal_admin_form_validate | Validates the submission of the configuration form. |
sms_txtlocal_balance | Get account balance |
sms_txtlocal_command | Executes a command using the Txtlocal API |
sms_txtlocal_gateway_info | Implement hook_gateway_info() |
sms_txtlocal_map_message_status_code | Map a Txtlocal message status code to an SMS Framework message status code |
sms_txtlocal_menu | Implement hook_menu() |
sms_txtlocal_message_status_codes | Returns an array of message status codes and strings that are generated by the txtlocal gateway |
sms_txtlocal_receive_message | Receive an SMS message and pass it into the SMS Framework |
sms_txtlocal_receive_receipt | Receive a message send receipt from txtlocal |
sms_txtlocal_send | Callback for sending messages. |
sms_txtlocal_send_form | Returns custom additions to be added to the send forms |