PHP Script for SMS delivery using Clickatell

We’re using the provider Clickatell to send out SMS. To do the delivery, I wrote a PHP CLI (command line) script, which I’ll share here.  We use this script, to make Nagios (or Icinga, for that matter…) notify us via SMS about issues.

Pastebins

I also uploaded the script to pastebin.com and pastebin.ca, where you can „enjoy“ the script with „nice“ syntax highlighting😉 It’s the same script at both pastebin.

Clickatell Documentation

Required Parameters

The script REQUIRES the following parameters:

  • -t → Phone number of the recipient („to“).
    The script will strip out any non-digit characters from this parameter. So a good value might be: ‚+41 79 123 45 67‘ or ‚41791234567‘. The number MUST be specified in international format!
  • -u → Clickatell Username
  • -p → Clickatell Password
  • -i → Clickatell API ID

The script will read the message text from standard input.

Optional Parameters

Additionally, there’s a handfull of OPTIONAL parameters:

  • -@ → Scheduled Delivery Time. When should the message be sent?
    If not set, the message is sent „now“. Otherwise, it’ll be sent at (almost…) the given time. Format: Unix Timestamp (eg. 1233133393) or UTC date format (2009-01-30T14:00:00Z)
  • -f → Source Address („from“). Needs to be registered at Clickatell.
  • -c → Max. number of concatted msgs to send out. By default, only 1 160char msg is send. If set to 2 or 3, 2x or 3x (160-7) char are allowed. Can be set to a higher value than 3, but shouldn’t.
  • -b → Clickatell Callback type. See „5.2.4 Callback URL“ of the Clickatell HTTP documentation. 0 = off, 3 = intermediate & final status
  • -q → Required SMS Features. See „5.2.8 Required features“ of the documentation. needs to incl. 16 if using Alpha (Text) as a „from“ (-f) value.
  • -x → Max. Credits; how many credits is ONE SMS message allowed to consum?; should be set to 3, to allow every possible SMS

Examples

echo 'Hello World!' | clickatell.php -t '+41 79 123 45 67' -u ClickDoe -p FooBar -i 9876543
clickatell.php -t 41791234567 -u ClickDoe -p FooBar -i 9876543 -@ 2009-12-24T18:00:00Z -f Santa-Claus -b 3 -x 3 -q 16 -c 3 < /tmp/msg

The first command will send the message „Hello World!“ to +41 79 123 45 67. Clickatell username is set to ClickDoe and password is FooBar. At clickatell, a HTTP API has been registered and Clickatell assgined the number 9876543 to it.

The 2nd example reads a (possibly long) message from the file /tmp/msg. It’ll send out a maximum of 3x(16o-7) = 459 characters (because of the „-c 3“ parameter) from the beginning of the message. The message is going to be send out at Christmas eve („-@ 2009-12-24T18:00:00Z“ ). It’s made to look like it’s from Santa („-f Santa-Claus“ — „Santa-Claus“ needs to be registered at Clickatell first). One message can cost up to 3 credits („-x 3“ ) and required features is set to 16 („-q 16“ ), which means that a textual from („Santa-Claus“) can be used.

Source

As mentioned, check out pastebin.com and pastebin.ca for nicely readable versions of the script.

#! /opt/csw/php5/bin/php
<?php

/*
 * Send SMS notifications using the Clickatell HTTP API Interface
 *
 * Description of command line parameters: see further down...
 *
 * Clickatell HTTP API Documentation:
 * http://www.clickatell.com/downloads/http/Clickatell_HTTP.pdf
 * -> http://docs.google.com/viewer?url=http://www.clickatell.com/downloads/http/Clickatell_HTTP.pdf
 */

// "Enhance" the implode() function to work with associative arrays (eg. array("user" => "john"))
function implode_assoc($array, $inner_glue = '=', $outer_glue = '&') {
 $output = array();
 foreach( $array as $key => $item )
 $output[] = $key . $inner_glue . $item;

 return implode($outer_glue, $output);
}

// Parse command line parameters
$args = getopt('t:u:p:i:@:f:b:c:q:x:');
if (
 ($args == FALSE)
 OR (! isset($args["t"]))
 OR (! isset($args["u"]))
 OR (! isset($args["p"]))
 OR (! isset($args["i"]))
){
 echo "Error! Command line arguments could not be parsed!

 * The script requires the following command line parameters:
 * # -t ['to' SMS Recipient Number - \$CONTACTPAGER\$] #
 * # -u [Clickatell Username] #
 * # -p [Clickatell Password] #
 * # -i [Clickatell API ID] #
 * -@ [Scheduled Delivery Time; When should the message be sent?; Formats: Unix timestamp (1233133393) or UTC date format (2009-01-30T14:00:00Z)]
 * -f ['from' Source Address A valid international format number between 1 and 16 characters long, or an 11 character alphanumeric string.]
 * -b [Clickatell Callback type; see 5.2.4 Callback URL (callback); 0 = off, 3 = intermediate & final status]
 * -c [Max. number of concatted msgs to send out. By default (1), only 1 160char msg is send. If set to 2 or 3, 2x or 3x (160-7) char are allowed]
 * -q [Required SMS Features; see 5.2.8 Required features (req_feat); needs to incl. 16 if using Alpha From]
 * -x [Max. Credits; how many credits is ONE SMS message allowed to consum?; should be set to 3, to allow every possible SMS]

 * Parameters listed with # are REQUIRED; others are optional.

 * The script reads the SMS text from STDIN, ie. invoke it like so:
 *   printf 'Hello\\nWorld!' | " . $_SERVER['SCRIPT_NAME'] . " -u JohnDoe -p FooBar -i 9876543 ...

 * Clickatell HTTP API Documentation:
 * http://www.clickatell.com/downloads/http/Clickatell_HTTP.pdf
 * -> http://docs.google.com/viewer?url=http://www.clickatell.com/downloads/http/Clickatell_HTTP.pdf
";
 exit(1);
}

echo "Welcome - Going to send an SMS....\n";

// "Fetch" parameters from the $args array
define('CLICKATELL_USER', $args['u']);
define('CLICKATELL_PASS', $args['p']);
define('CLICKATELL_API_ID', $args['i']);

// "Sanitize" the number of the recipient - ie. drop any non-digit char
define('TO', preg_replace('/[^[:digit:]]/', '', $args["t"]));

// Set "FROM"
if (isset($args['f'])){ define('FROM', $args['f']); }

// SMS Concatenation
// Maximum number of SMS to send, which makes up 1 msg at the
// receiver. Allows to send SMS messages which are longer than
// 160char
// See 5.2.6 Concatenation (concat)
if (isset($args['c'])){ define('SMS_CONCATS', $args['c']); }

// Callback Value
// See 5.2.4 Callback URL (callback)
//
//    Callback    Message status types returned                Message status code returned
//    value
//    0        No message status returned.
//    1        Returns only intermediate statuses.            002, 003, 011
//    2        Returns only final statuses of a message.        004, 005, 006, 007, 008, 010, 012
//    3        Returns both intermediate and final statuses of a msg.    All except 001
if (isset($args['b'])){ define('CALLBACK_VALUE', $args['b']); }

// Required Features
// See 5.2.8 Required features (req_feat)
//
//    Hex    Decimal    Feature        Description
//    0x0001    1    FEAT_TEXT    Text – set by default.
//    0x0002    2    FEAT_8BIT    8-bit messaging – set by default.
//    0x0004    4    FEAT_UDH    UDH (Binary) - set by default.
//    0x0008    8    FEAT_UCS2    UCS2 / Unicode – set by default.
//    0x0010    16    FEAT_ALPHA    Alpha source address (from parameter).
//    0x0020    32    FEAT_NUMER    Numeric source address (from parameter).
//    0x0200    512    FEAT_FLASH    Flash messaging.
//    0x2000    8192    FEAT_DELIVACK    Delivery acknowledgments.
//    0x4000    16384    FEAT_CONCAT    Concatenation – set by default.
if (isset($args['q'])){ define('REQ_FEAT', $args['q']); }

// Maximum Credits
// This parameter overrides the maximum charge associated with message delivery,
// 5.2.7 Maximum credits (max_credits)
if (isset($args['x'])){ define('MAX_CREDITS', $args['x']); }

// Scheduled Time
// The purpose of this parameter is to allow you to specify when you want a message to be delivered.
// See 5.2.16 Scheduled Time
// Formats:
//     1) Unix timestamp:
//         scheduled_time:1233133393
//     2) UTC date format:
//         scheduled_time:2009-01-30T14:00:00Z
if (isset($args['@'])){ define('SCHEDULED_TIME', $args['@']); }

// Read the to-be sent message from stdin.
$text = file_get_contents('php://stdin');
// Convert UTF-8 chars -> iso-8859-1
$text = utf8_decode($text);
// Only allow $concat_count * (160-7) chars in $text
if (defined('SMS_CONCATS')){
 $text = substr($text, 0, SMS_CONCATS * (160-7));
} else {
 $text = substr($text, 0, 160);
}

// URL to prepend to all outgoing calls
define('BASEURL', "http://api.clickatell.com");

// auth call
$cmd = "auth";
$cmd_parms = array("user" => CLICKATELL_USER, "password" => CLICKATELL_PASS, "api_id" => CLICKATELL_API_ID);
$url = BASEURL . "/http/" . $cmd . "?" . implode_assoc(array_map("urlencode", $cmd_parms));
// do auth call
$ret = file($url);
// split our response. return string is on first line of the data returned
$sess = split(":", $ret[0]);

// Did we get an "OK"? If so, continue with sending the message.
if ($sess[0] == "OK") {
 $sess_id = trim($sess[1]); // remove any whitespace
 $cmd = "sendmsg";
 $cmd_parms = array("session_id" => $sess_id,
 "to" => TO,
 "text" => $text
 );
 if (defined('MAX_CREDITS')){ $cmd_parms['max_credits'] = MAX_CREDITS; }
 if (defined('FROM')){ $cmd_parms['from'] = FROM; }
 if (defined('REQ_FEAT')){ $cmd_parms['req_feat'] = REQ_FEAT; }
 if (defined('CALLBACK_VALUE')){ $cmd_parms['callback'] = CALLBACK_VALUE; }
 if (defined('SMS_CONCATS')){ $cmd_parms['concat'] = SMS_CONCATS; }
 if (defined('SCHEDULED_TIME')){ $cmd_parms['scheduled_time'] = SCHEDULED_TIME; }

 $url = BASEURL . "/http/" . $cmd . "?" . implode_assoc(array_map("urlencode", $cmd_parms));
 // echo 'url: ' . $url . "\n";
 // exit(42);
 // do sendmsg call
 $ret = file($url);
 $send = split(":",$ret[0]);
 if ($send[0] == "ID") {
 echo "success
message ID: ". $send[1] . "\n";
 exit(0);
 } else {
 echo "send message failed: " . $ret[0] . "\n";
 exit(1);
 }
} else {
 echo "Authentication failure: " . $ret[0] . "\n";
 exit(2);
}

// We cannot reach this spot!
echo "ERROR! Impossible program location!";
exit(3);
// EOF //

Enjoy!🙂

#FTW!

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s