06.03
php
saved
deizel
Note
Component and test case for sending texts via the Clickatell XMP API. View test case for usage.
Component and test case for sending texts via the Clickatell XMP API. View test case for usage.
- // app/controllers/components/sms.php
- <?php
- class SmsComponent extends Object {
- /**
- * API product ID for Clickatell XML connection
- *
- * @var string
- */
- public $api_id = '';
- /**
- * Username of Clickatell account
- *
- * @var string
- */
- public $user = '';
- /**
- * Password for Clickatell account
- *
- * @var string
- */
- public $password = '';
- /**
- * Session ID
- *
- * The session ID from the 'auth' command.
- *
- * @var string This is an MD5 hash (ie. a 32 digit hexadecimal number).
- */
- public $session_id = null;
- /**
- * Destination address
- *
- * The number of the handset to which the message must be delivered.
- * The number should be in international number format.
- *
- * @var string No '00' prefix or leading "+" symbol should be used.
- */
- public $to = null;
- /**
- * Text
- *
- * The text content of the message.
- * Note that some characters stake up two characters because of GSM encoding standards
- *
- * @var string http://support.clickatell.com/faq.php?mode=view_entry&kbid=121&kbcat=26
- */
- public $text = null;
- /**
- * Source address
- *
- * The source/sender address that the message will appear to come from also known as “Sender ID”.
- * These must be registered within your online account and approved by us before they may be used.
- * MO numbers rented from us do not require approval.
- *
- * @var string A valid international format number between 1 and 16 characters long, or an 11 character alphanumeric string.
- * @default gateway assigned number
- */
- public $from = null;
- /**
- * Enable callback
- *
- * Enables you to receive message delivery statuses via an HTTP callback which is posted to a URL of yours using the GET or POST method.
- * This is done every time a message status is updated.
- *
- * @var integer 0,1,2,3
- * @default 0
- */
- public $callback = null;
- /**
- * Delivery time
- *
- * Delays delivery of SMS to mobile device in minutes relative to the time at which the SMS was received by our gateway.
- * This should be greater than 10 minutes for best effect.
- * Smaller time frames may be delivered too soon.
- *
- * @var integer Minutes. The upper limit is 10080 minutes (7 days).
- */
- public $deliv_time = null;
- /**
- * Delivery acknowledgment
- *
- * In order to determine whether an SMS has been received by a handset or not,
- * we request delivery acknowledgement for every message we send.
- * The ability to receive reliable delivery acknowledgements varies between mobile networks.
- * Please test to a specific mobile network first,
- * before assuming that you will receive handset acknowledgments for messages that are delivered.
- * GSM handsets that are off will only be reported once a user has switched their phone back on.
- * If the validity period is exceeded, the Clickatell gateway will return a message status of 7, “Error with message”.
- * A delivery acknowledgment can be monitored via the callback URL or online reports.
- *
- * @var boolean?
- */
- public $deliv_ack = null;
- /**
- * Concatenation
- *
- * Enables you to send messages longer than a standard message.
- *
- * @var integer 1,2,3,n. The number of SMS messages a message can span. A maximum of no more than 3 is recommended.
- * @default 1
- */
- public $concat = null;
- /**
- * Maximum credits
- *
- * Overrides the maximum charge specified online in “profiles”.
- * It works within the bounds of the profiles.
- * In other words a profile must exist for the maximum credit that you set.
- *
- * @var float 0.8,1,1.5,2,2.5,3
- * @default As per profile
- */
- public $max_credits = null;
- /**
- * Required features
- *
- * Some parameters and features are not set as “required” by default, and may be dropped if the least-cost route does not support them.
- * This parameter allows you to ensure that the features set when an SMS is sent are supported by the gateway used.
- * This could increase the cost per message if a more expensive gateway is used.
- *
- * @var string TODO
- */
- public $req_feat = null;
- /**
- * Delivery queue
- *
- * Delivers the message through one of three queues assigned to each client account.
- * Messages in the highest priority queue will be delivered first.
- *
- * @var integer 1,2,3 (1 is highest priority)
- * @default 3
- */
- public $queue = null;
- /**
- * Gateway escalation
- *
- * Prompts an escalation to an alternative delivery gateway, should the message be delayed for a set length of time.
- *
- * @var integer 0 = off, 1 = Escalate immediately to an alternative route if messages are queued on the least-cost route.
- * @default 0
- */
- public $escalate = null;
- /**
- * Mobile originated
- *
- * We route via a pre-defined carrier to enable the ability for a reply to be received back.
- * This is only applicable to clients that have subscribed to a two-way messaging service.
- *
- * @var integer mo 0 = off (use our normal routing rules), 1 = enable reply
- * @default 0
- */
- public $mo = null;
- /**
- * Client message ID defined by user for message tracking.
- *
- * @var string Up to 32 alphanumeric characters. No spaces.
- */
- public $cliMsgId = null;
- /**
- * API message ID
- *
- * API message ID defined by Clickatell for message tracking.
- *
- * @var string API message ID to lookup in API call
- */
- public $apiMsgId = null;
- /**
- * Unicode message
- *
- * Two digit language code. Convert your text to Unicode [UCS-2 encoding]. See http://www.Unicode.org/.
- *
- * @var integer 0 = no Unicode, 1 = send as Unicode.
- * @default 0
- */
- public $Unicode = null;
- /**
- * Message type
- *
- * Optional parameter which must be set to send specially formatted messages; e.g. logos and ringtones.
- *
- * @var string SMS_TEXT, SMS_FLASH, SMS_NOKIA_OLOGO, SMS_NOKIA_GLOGO, SMS_NOKIA_PICTURE, SMS_NOKIA_RINGTONE, SMS_NOKIA_RTTL, SMS_NOKIA_CLEAN, SMS_NOKIA_VCARD, SMS_NOKIA_VCAL
- * @default SMS_TEXT
- */
- public $msg_type = null;
- /**
- * User data header
- *
- * Allows you to set your own message types. Do not use if you set the message type parameter.
- * When set, Clickatell assumes the data is 8 bit. See 8 bit messaging for more information.
- *
- * @var string Set UDH data manually.
- */
- public $udh = null;
- /**
- * Data
- *
- * @var string The data content of a message, if the UDH component is set manually.
- */
- public $data = null;
- /**
- * Validity period
- *
- * The validity period in minutes relative to the time at which the SMS was received by our gateway.
- * The message will not be delivered if it is still queued on our gateway after this time period.
- *
- * @var integer Set value in X minutes from 1 – 1440 minutes.
- */
- public $validity = null;
- /**
- * Sequence number
- *
- * @var string WTF is this?
- */
- public $sequence_no = null;
- /**
- * Debugging enabled?
- *
- * @var boolean
- */
- public $debug = false;
- /**
- * URL of gateway for Clickatell XML connection
- *
- * This gateway responds to case-sensitive XML submitted as an HTTP form post
- *
- * @var string
- */
- const API_XML_URL = 'http://api.clickatell.com/xml/xml/';
- /**
- * Authenticate with Clickatell API
- *
- * Session expires after 15 minutes. Use ping() to keep session ID live
- *
- * @param string $api_id API ID for Clickatell XML connection
- * @param string $user Username of Clickatell account
- * @param string $password Password for Clickatell account
- * @return mixed Array with session_id or fault, and sequence_no (if set)
- * @access public
- */
- public function auth($api_id = null, $user = null, $password = null, $sequence_no = null) {
- if ($api_id) {
- $this->api_id = $api_id;
- }
- if ($user) {
- $this->user = $user;
- }
- if ($password) {
- $this->password = $password;
- }
- if ($sequence_no) {
- $this->sequence_no = $sequence_no;
- }
- $tag = 'auth';
- 'api_id' => $this->api_id,
- 'user' => $this->user,
- 'password' => $this->password,
- 'sequence_no' => $this->sequence_no);
- return $this->__send($tag, $params);
- }
- /**
- * Ping the Clickatell API
- *
- * Prevents the session ID from expiring during periods of inactivity.
- * The session ID is set to expire after 15 minutes of inactivity.
- *
- * @param string $session_id Session ID of Clickatell API session to ping
- * @param string $sequence_no
- * @return mixed Array with ok or fault, and sequence_no (if set)
- * @access public
- */
- public function ping($session_id = null, $sequence_no = null) {
- if ($session_id) {
- $this->session_id = $session_id;
- }
- if ($sequence_no) {
- $this->sequence_no = $sequence_no;
- }
- $tag = 'ping';
- 'session_id' => $this->session_id,
- 'sequence_no' => $this->sequence_no);
- return $this->__send($tag, $params);
- }
- /**
- * Send an SMS text message
- *
- * Prevents the session ID from expiring during periods of inactivity.
- * The session ID is set to expire after 15 minutes of inactivity.
- *
- * @param string session_id Session ID of Clickatell API session to use
- * @param string to
- * @param string text
- * @return mixed Array with apiMsgId or fault, and sequence_no (if set)
- * @access public
- */
- public function sendMsg($session_id = null, $to = null, $text = null, $sequence_no = null) {
- if ($session_id) {
- $this->session_id = $session_id;
- }
- if ($to) {
- $this->to = $to;
- }
- if ($text) {
- $this->text = $text;
- }
- if ($sequence_no) {
- $this->sequence_no = $sequence_no;
- }
- $tag = 'sendMsg';
- 'session_id' => $this->session_id,
- 'to' => $this->to,
- 'text' => $this->text,
- 'callback' => $this->callback,
- 'cliMsgId' => $this->cliMsgId,
- 'concat' => $this->concat,
- 'deliv_ack' => $this->deliv_ack,
- 'deliv_time' => $this->deliv_time,
- 'from' => $this->from,
- 'msg_type' => $this->msg_type,
- 'udh' => $this->udh,
- 'Unicode' => $this->Unicode,
- 'validity' => $this->validity,
- 'req_feat' => $this->req_feat,
- 'max_credits' => $this->max_credits,
- 'queue' => $this->queue,
- 'escalate' => $this->escalate,
- 'sequence_no' => $this->sequence_no);
- return $this->__send($tag, $params);
- }
- /**
- * Query a message
- *
- * This tag returns the status of a message.
- * You can query the status with either the apimsgid or climsgid.
- * The API message ID (apimsgid) is the message ID returned by the gateway when a message has been successfully submitted.
- * If you specified your own unique client message ID (climsgid) on submission, you may query the message status using this value.
- *
- * @param string session_id Session ID of Clickatell API session to use
- * @param string apiMsgId API message ID (if passing this, don't set cliMsgId)
- * @param string cliMsgId Client message ID (if passing this, don't set apiMsgId)
- * @param string sequence_no
- * @return mixed Array with apiMsgId, status or fault, and sequence_no (if set)
- * @access public
- */
- public function queryMsg($session_id = null, $apiMsgId = null, $cliMsgId = null, $sequence_no = null) {
- if ($session_id) {
- $this->session_id = $session_id;
- }
- if ($apiMsgId) {
- $this->apiMsgId = $apiMsgId;
- }
- if ($cliMsgId) {
- $this->cliMsgId = $cliMsgId;
- }
- if ($sequence_no) {
- $this->sequence_no = $sequence_no;
- }
- $tag = 'queryMsg';
- 'session_id' => $this->session_id,
- 'apiMsgId' => $this->apiMsgId,
- 'cliMsgId' => $this->cliMsgId,
- 'sequence_no' => $this->sequence_no);
- return $this->__send($tag, $params);
- }
- /**
- * Delete/Stop message
- *
- * Enables you to stop the delivery of a particular message.
- * Can only stop messages which may be queued within Clickatell router,
- * and not messages which have already been delivered to a SMSC.
- * This command is therefore only really useful for messages with deferred delivery times.
- *
- * @param string session_id Session ID of Clickatell API session to use
- * @param string apiMsgId API message ID (if passing this, don't set cliMsgId)
- * @param string cliMsgId Client message ID (if passing this, don't set apiMsgId)
- * @param string $sequence_no
- * @return mixed Array with apiMsgId or fault, and sequence_no (if set)
- * @access public
- */
- public function delMsg($session_id = null, $apiMsgId = null, $cliMsgId = null, $sequence_no = null) {
- if ($session_id) {
- $this->session_id = $session_id;
- }
- if ($apiMsgId) {
- $this->apiMsgId = $apiMsgId;
- }
- if ($cliMsgId) {
- $this->cliMsgId = $cliMsgId;
- }
- if ($sequence_no) {
- $this->sequence_no = $sequence_no;
- }
- $tag = 'delMsg';
- 'session_id' => $this->session_id,
- 'apiMsgId' => $this->apiMsgId,
- 'cliMsgId' => $this->cliMsgId,
- 'sequence_no' => $this->sequence_no);
- return $this->__send($tag, $params);
- }
- /**
- * Query balance
- *
- * This will return the number of credits available on this particular account.
- * The account balance is returned as a floating point value.
- *
- * @param string session_id Session ID of Clickatell API session to use
- * @param string $sequence_no
- * @return mixed Array with ok or fault, and sequence_no (if set)
- * @access public
- */
- public function getBalance($session_id = null, $sequence_no = null) {
- if ($session_id) {
- $this->session_id = $session_id;
- }
- if ($sequence_no) {
- $this->sequence_no = $sequence_no;
- }
- $tag = 'getBalance';
- 'session_id' => $this->session_id,
- 'sequence_no' => $this->sequence_no);
- return $this->__send($tag, $params);
- }
- /**
- * Coverage query
- *
- * This command enables you to check our coverage of a network or number,
- * without sending a message to that number.
- * This call should NOT be used before sending each message.
- *
- * @param string session_id Session ID of Clickatell API session to use
- * @param string to MSISDN of number to check coverage for
- * @param string $sequence_no
- * @return mixed Array with ok or fault, charge and sequence_no (if set)
- * @access public
- */
- public function routeCoverage($session_id = null, $to = null, $sequence_no = null) {
- if ($session_id) {
- $this->session_id = $session_id;
- }
- if ($to) {
- $this->to = $to;
- }
- if ($sequence_no) {
- $this->sequence_no = $sequence_no;
- }
- $tag = 'routeCoverage';
- 'session_id' => $this->session_id,
- 'msisdn' => $this->to,
- 'sequence_no' => $this->sequence_no);
- return $this->__send($tag, $params);
- }
- /**
- * Get message status from status number
- *
- * Use this to get a human readable status message
- *
- * @param string status_no Error code returned by API
- * @return mixed Array with description and detail
- * @access public
- */
- public function getError($error_code) {
- $status_detail = '';
- switch ($error_code) {
- case 001:
- $status_description = 'Authentication failed';
- break;
- case 002:
- $status_description = 'Unknown username or password';
- break;
- case 003:
- $status_description = 'Session ID expired';
- break;
- case 004:
- $status_description = 'Account frozen';
- break;
- case 005:
- $status_description = 'Missing session ID';
- break;
- case 007:
- $status_description = 'IP Lockdown violation';
- $status_detail = 'You have locked down the API instance to a specific IP address and then sent from an IP address different to the one you set.';
- break;
- case 101:
- $status_description = 'Invalid or missing parameters';
- break;
- case 102:
- $status_description = 'Invalid user data header';
- break;
- case 103:
- $status_description = 'Unknown API message ID';
- break;
- case 104:
- $status_description = 'Unknown client message ID';
- break;
- case 105:
- $status_description = 'Invalid destination address';
- break;
- case 106:
- $status_description = 'Invalid source address';
- break;
- case 107:
- $status_description = 'Empty message';
- break;
- case 108:
- $status_description = 'Invalid or missing API ID';
- break;
- case 109:
- $status_description = 'Missing message ID';
- $status_detail = 'This can be either a client message ID or API message ID. For example when using the del_msg command.';
- break;
- case 110:
- $status_description = 'Error with email message';
- break;
- case 111:
- $status_description = 'Invalid protocol';
- break;
- case 112:
- $status_description = 'Invalid message type';
- break;
- case 113:
- $status_description = 'Maximum message parts exceeded';
- $status_detail = 'The text message component of the message is greater than the permitted 160 characters (70 Unicode characters). Select concat equal to 1,2,3-N to overcome this by splitting the message across multiple messages.';
- break;
- case 114:
- $status_description = 'Cannot route message';
- $status_detail = 'This implies that the gateway is not currently routing messages to this network prefix. Please email support@clickatell.com with the mobile number in question.';
- break;
- case 115:
- $status_description = 'Message expired';
- break;
- case 116:
- $status_description = 'Invalid Unicode data';
- break;
- case 120:
- $status_description = 'Invalid delivery time';
- break;
- case 121:
- $status_description = 'Destination mobile number blocked';
- $status_detail = 'This number is not allowed to receive messages from us and has been put on our block list.';
- break;
- case 122:
- $status_description = 'Destination mobile opted out';
- break;
- case 201:
- $status_description = 'Invalid batch ID';
- break;
- case 202:
- $status_description = 'No batch template';
- break;
- case 301:
- $status_description = 'No credit left';
- break;
- case 302:
- $status_description = 'Max allowed credit';
- break;
- default:
- $status_description = 'Unknown status';
- $status_detail = 'This status number is unknown';
- break;
- }
- }
- /**
- * Get message status from status number
- *
- * Use this to get a human readable status message
- *
- * @param string status_no Status returned by queryMsg()
- * @return mixed Array with description and detail
- * @access public
- */
- public function getMessageStatus($status_no) {
- switch ($status_no) {
- case 1:
- $status_description = 'Message unknown';
- $status_detail = 'The message ID is incorrect or reporting is delayed.';
- break;
- case 2:
- $status_description = 'Message queued';
- $status_detail = 'The message could not be delivered and has been queued for attempted redelivery.';
- break;
- case 3:
- $status_description = 'Delivered to gateway';
- $status_detail = 'Delivered to the upstream gateway or network (delivered to the recipient).';
- break;
- case 4:
- $status_description = 'Received by recipient';
- $status_detail = 'Confirmation of receipt on the handset of the recipient.';
- break;
- case 5:
- $status_description = 'Error with message';
- $status_detail = 'There was an error with the message, probably caused by the content of the message itself.';
- break;
- case 6:
- $status_description = 'User cancelled message delivery';
- $status_detail = 'The message was terminated by an internal mechanism.';
- break;
- case 7:
- $status_description = 'Error delivering message';
- $status_detail = 'An error occurred delivering the message to the handset.';
- break;
- case 8:
- $status_description = 'OK';
- $status_detail = 'Message received by gateway.';
- break;
- case 9:
- $status_description = 'Routing error';
- $status_detail = 'The routing gateway or network has had an error routing the message.';
- break;
- case 10:
- $status_description = 'Message expired';
- $status_detail = 'Message has expired before we were able to deliver it to the upstream gateway. No charge applies.';
- break;
- case 11:
- $status_description = 'Message queued for later delivery';
- $status_detail = 'Message has been queued at the gateway for delivery at a later time (delayed delivery).';
- break;
- case 12:
- $status_description = 'Out of credit';
- $status_detail = 'The message cannot be delivered due to a lack of funds in account. Please wait for us to re-purchase credits.';
- break;
- default:
- $status_description = 'Unknown status';
- $status_detail = 'This status number is unknown';
- break;
- }
- }
- /**
- * Send an XML request to Clickatell API and extract response
- *
- * @param string tag Name of the API function (tag) to call
- * @param object params Associative array of each parameter and value for call
- * @return object Associative array holding the response values from the API call
- * @access private
- */
- private function __send($tag, $params) {
- $xmlRequest = $this->__createXML($tag, $params);
- $xmlResponse = $this->__postXML($xmlRequest);
- $response = $this->__getResponseFromXML($tag, $xmlResponse);
- return $response;
- }
- /**
- * Create well-formed XML request for use with Clickatell API
- *
- * @param string tag Name of the API function (tag) to call
- * @param object params Associative array of each parameter and value for call
- * @return string Well-formed XML request
- * @access private
- */
- private function __createXML($tag, $params) {
- $xml = new SimpleXMLElement('<clickAPI></clickAPI>');
- $tag = $xml->addChild($tag);
- foreach ($params as $key => $value) {
- if ($value) {
- $tag->addChild($key, $value);
- }
- }
- $xmlRequest = $xml->asXML();
- if ($this->debug) {
- pr('<xmp>' . $xmlRequest . '</xmp>');
- }
- return $xmlRequest;
- }
- /**
- * Post the XML request to the Clickatell API gateway
- *
- * @param string Well-formed XML request for Clickatell's API gateway
- * @return string Well-formed XML response from Clickatell's API gateway
- * @access private
- */
- private function __postXML($xmlRequest) {
- $ch = curl_init();
- CURLOPT_POSTFIELDS => 'data=' . $xmlRequest,
- //CURLOPT_PROXY => '128.127.111.111',
- //CURLOPT_PROXYPORT => '8080',
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_URL => self::API_XML_URL);
- curl_setopt_array($ch, $options);
- $xmlResponse = curl_exec($ch);
- curl_close($ch);
- if ($this->debug) {
- echo 'XML response';
- pr('<xmp>' . $xmlResponse . '</xmp>');
- }
- return $xmlResponse;
- } else {
- }
- }
- /**
- * Extract serialized response from Clickatell XML response
- *
- * @param string tag Name of the API function (tag) to call
- * @param string xmlResponse Well-formed XML response from Clickatell's API gateway
- * @return object Associative array holding the response values from the API call
- * @access private
- */
- private function __getResponseFromXML($tag, $xmlResponse) {
- $xml = new SimpleXMLElement($xmlResponse);
- return $xml->{$tag . 'Resp'};
- }
- }
- ?>
- // app/tests/cases/components/sms.test.php
- <?php
- App::import('Component', 'Sms');
- class SmsTestController extends Controller {
- public $name = 'SmsTest';
- public $uses = null;
- }
- class SmsTest extends CakeTestCase {
- public $name = 'Sms';
- private $testNum = '1234567890';
- function setUp() {
- $this->Controller =& new SmsTestController();
- @$this->Controller->_initComponents();
- //$this->Controller->Sms->startup($this->Controller);
- ClassRegistry::addObject('view', new View($this->Controller));
- $this->Controller->Sms->debug = true;
- }
- function testAuth() {
- echo '<h3>auth()</h3>';
- $response = $this->Controller->Sms->auth();
- $this->session_id = $response->session_id;
- }
- function testPing() {
- echo '<h3>ping()</h3>';
- $response = $this->Controller->Sms->ping($this->session_id);
- $this->assertTrue($response->ok);
- }
- // this should only cost money if the telephone number is recognized..
- /*
- function testSendMsg() {
- echo '<h3>sendMsg()</h3>';
- $response = $this->Controller->Sms->sendMsg($this->session_id, $this->testNum, 'This is a test SMS.');
- $this->assertTrue(isset($response->apiMsgId));
- $this->assertTrue($response->apiMsgId);
- }
- */
- function testQueryMsg() {
- echo '<h3>queryMsg()</h3>';
- $response = $this->Controller->Sms->queryMsg($this->session_id, '265895850416d42561e745ba62e3fed0');
- //$this->assertTrue(isset($response->apiMsgId));
- //$this->assertTrue($response->apiMsgId);
- }
- function testGetBalance() {
- echo '<h3>getBalance()</h3>';
- $response = $this->Controller->Sms->getBalance($this->session_id);
- $this->assertTrue($response->ok);
- }