The free and open source SMS gateway for Android

Instructions

  • SMSsync uses the HTTP and HTTPS protocols for communication.
    To start the SMSsync Gateway, you'll need to specify a Sync URL. This URL is where all incoming SMS will be transmitted to. Remember to enter the full URL including the filename. A typical example will be http://somedomain.com/index.php
  • For security you can specify a secret key to be sent to the Sync URL. If the secret key doesn't match on the server, the Sync URL can ignore the transmission.
  • Additionally, you can specify keywords with which to filter incoming SMS. Only matching messages will be forwarded to the SMSsync Gateway URL.
  • SMSsync uses the following variables to transmit the incoming SMS via the POST method:
    • from -- the number that sent the SMS
    • message -- the SMS sent
    • message_id -- the unique ID of the SMS
    • sent_to -- the phone number registered on the SIM card otherwise it's the value set on the app as device ID
    • secret -- the secret key set on the app
    • device_id -- the unique id set on the device to be used by the server to identify which device is communicating with it. Note: supported from v2.6.1 and above
    • sent_timestamp -- the timestamp the SMS was sent. In the UNIX timestamp format

In order for SMSsync to ensure perfect transmission, the Sync URL must return a JSON-formatted status message, as shown below.

Succeeded

{
    "payload":
    {
        "success": true,
        "error": null
    }
}


Failed
{
    "payload":
    {
        "success": false,
        "error": "error message from the server"
    }
}

 

Response from server

SMSsync allows either an auto-response message to be configured on the app itself, or to be retrieved from the server. When the app makes an HTTP Post request to sync the incoming SMS to the configured URL, the server can respond with JSON-encoded messages alongside the success message. The app then sends these messages by SMS to the specified users phone.

This makes it possible to have an instant response via SMS when an HTTP Post request is made. To leverage this feature, a JSON formatted string like the one below needs to be returned by the configured URL in response to the app's HTTP Post request.

In the app itself, ensure *Get Reply from Server* is checked to enable this feature.

Response JSON data from the Sync URL

{
    "payload": {
        "success": "true",
        "task": "send",
        "messages": [
            {
                "to": "+000-000-0000",
                "message": "the message goes here",
                "uuid": "042b3515-ef6b-f424-c4qd"
            },
            {
                "to": "+000-000-0000",
                "message": "the message goes here",
                "uuid": "026b3515-ef6b-f424-c4qd"
            },
            {
                "to": "+000-000-0000",
                "message": "the message goes here",
                "uuid": "096b3515-ef6b-f424-c4qd"
            }
        ]
    }
}

 

Task

SMSsync supports execution of tasks defined on the server. Currently it supports sending of messages sent from the Sync URL as SMS. This feature is targeted towards developers. The app can be configured to poll the server for new tasks at a given frequency. The server then needs to respond to HTTP GET requests with ?task=send (for example http://callback_url/smssync?task=send). The format of this response is shown below.



Response JSON data from the Sync URL

{
    "payload": {
        "task": "send",
        "secret": "secret_key",
        "messages": [
            {
                "to": "+000-000-0000",
                "message": "the message goes here",
                "uuid": "042bf515-eq6b-f424-c4pz"
            },
            {
                "to": "+000-000-0000",
                "message": "the message goes here",
                "uuid": "022b3515-ef6b-f424-c4ws"
            },
            {
                "to": "+000-000-0000",
                "message": "the message goes here",
                "uuid": "042b3515-ef6b-f424-c4qd"
            }
        ]
    }
}


Notes:
  • The secret key provided by the server must match the secret key configured within SMSsync, otherwise SMSsync will not execute the task.
  • To ensure the message is sent to the correct recipient, add the country code to the phone number. Eg. +254700709142. Without this, the message is sent to the number in the country where the phone is.
  • The web service should check the value of the secret key passed with each task request that SMSsync makes to it for messages to send and respond appropriately to ensure that not any instance of SMSsync can communicate with it.
Message Results API

Message Results API is a way to get SMS status delivery report back to the server so the server knows that messages have been successfully sent to their respective recipients or not.

This feature is supported on v2.7 and above. To make use of this feature, you have to enable the Message Results API and SMS Delivery Report from the Settings screen.

SMSsync will periodically send a Task request to the server for messages to send as SMS. Note: The server needs to include a unique ID for the messages in the JSON response as "uuid":"unique_id" key. See below for a sample JSON response from the server

GET /smssync?task=send HTTP/1.1
Host: testserver.local

HTTP/1.1 200 OK
Server: nginx/1.5.2
Content-Type: application/json; charset=utf-8
{
    "payload": {
        "task": "send",
        "secret": "secret_key",
        "messages": [
            {
                "to": "+000-000-0000",
                "message": "the message goes here"
                "uuid": "aada21b0-0615-4957-bcb3"
            },
            {
                "to": "+000-000-0000",
                "message": "the message goes here"
                "uuid": "1ba368bd-c467-4374-bf28"
            },
            {
                "to": "+000-000-0000",
                "message": "the message goes here"
                "uuid": "95df126b-ee80-4175-a6fb"
            }
        ]
    }
}
Once SMSsync receives messages to be sent as SMS it will make a POST ?task=sent request with the message UUIDs as below to the server to acknowledge that it has received the messages and has queued them up for processing.
POST /smssync?task=sent HTTP/1.1
Host: testserver.local

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
    "queued_messages": [
        "aada21b0-0615-4957-bcb3",
        "1ba368bd-c467-4374-bf28",
        "95df126b-ee80-4175-a6fb"
    ]
}

Next, the server needs to process the JSON response sent by SMSsync. It needs to remove all the message UUIDs sent by SMSsync from the subsequent outgoing messages list so SMSsync avoids processing those again. Once the server receives the UUIDs of the queued up messages, it needs to send a response back to SMSsync as JSON response with the received messages UUIDs as JSON array. If there are no received messages UUIDs, it needs to send back an empty JSON array to SMSsync

POST /smssync?task=sent HTTP/1.1
Host: testserver.local

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
    "message_uuids": [
        "aada21b0-0615-4957-bcb3",
        "1ba368bd-c467-4374-bf28",
        "95df126b-ee80-4175-a6fb"
    ]
}

To send SMS status delivery report back to the server, SMSsync will make a GET ?task=result to the server and should receive a list of message UUIDs that are waiting to receive delivery reports. The server should send the JSON response below

GET /smssync?task=result HTTP/1.1
Host: testserver.local

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
    "message_uuids": [
        "aada21b0-0615-4957-bcb3",
        "1ba368bd-c467-4374-bf28",
        "95df126b-ee80-4175-a6fb"
    ]
}

Then SMSsync will send delivery reports for the message uuids above as a POST requestPOST ?task=result with the JSON response below

POST /smssync?task=result HTTP/1.1
Host: testserver.local
Content-Type: application/json; charset=utf-8

{
    "message_results": [
        {
            "uuid": "052bf515-ef6b-f424-c4ee",
            "sent_result_code": 0,
            "sent_result_message": "SMSSync Message Sent"
            "delivered_result_code": -1,
            "delivered_result_message": ""
        },
        {
            "uuid": "aada21b0-0615-4957-bcb3",
            "sent_result_code": 0,
            "sent_result_message": "SMSSync Message Sent",
            "delivered_result_code": 0,
            "delivered_result_message": "SMS Delivered"
        },
        {
            "uuid": "1ba368bd-c467-4374-bf28",
            "sent_result_code": 1,
            "sent_result_message": "Failed to send SMS - Maybe insufficient air time on the phone.",
            "delivered_result_code": -1,
            "delivered_result_message": ""
        },
        {
            "uuid": "95df126b-ee80-4175-a6fb",
            "sent_result_code": 4,
            "sent_result_message": "No service",
            "delivered_result_code": -1,
            "delivered_result_message": ""
        }
    ]
}

A sample web service

This is a sample PHP script to demonstrate how to write a webservice to successfully communicate with SMSsync.

/**
 * Gets the messages(SMSs) sent by SMSsync as a POST request.
 *
 */
function get_message()
{
    $error = NULL;
    // Set success to false as the default success status
    $success = false;

    /**
     *  Get the phone number that sent the SMS.
     */
    if (isset($_POST['from']))
    {
        $from = $_POST['from'];
    }
    else
    {
        $error = 'The from variable was not set';
    }

    /**
     * Get the SMS aka the message sent.
     */
    if (isset($_POST['message']))
    {
        $message = $_POST['message'];
    }
    else
    {
        $error = 'The message variable was not set';
    }

    /**
     * Get the secret key set on SMSsync side
     * for matching on the server side.
     */
    if (isset($_POST['secret']))
    {
        $secret = $_POST['secret'];
    }


    /**
     * Get the timestamp of the SMS
     */
    if(isset($_POST['sent_timestamp']))
    {
        $sent_timestamp = $_POST['sent_timestamp'];
    }

    /**
     * Get the phone number of the device SMSsync is
     * installed on.
     */
    if (isset($_POST['sent_to']))
    {
        $sent_to = $_POST['sent_to'];
    }

    /**
     * Get the unique message id
     */
    if (isset($_POST['message_id']))
    {
        $message_id = $_POST['message_id'];
    }

    /**
     * Get device ID
     */
    if (isset($_POST['device_id']))
    {
        $device_id = $_POST['device_id'];
    }

    /**
     * Now we have retrieved the data sent over by SMSsync
     * via HTTP. Next thing to do is to do something with
     * the data. Either echo it or write it to a file or even
     * store it in a database. This is entirely up to you.
     * After, return a JSON string back to SMSsync to know
     * if the web service received the message successfully or not.
     *
     * In this demo, we are just going to save the data
     * received into a text file.
     *
     */
    if ((strlen($from) > 0) AND (strlen($message) > 0) AND
        (strlen($sent_timestamp) > 0 )
        AND (strlen($message_id) > 0))
    {
        /* The screte key set here is 123456. Make sure you enter
         * that on SMSsync.
         */
        if ( ( $secret == '123456'))
        {
            $success = true;
        } else
        {
            $error = "The secret value sent from the device does not match the one on the server";
        }
        // now let's write the info sent by SMSsync
        //to a file called test.txt
        $string = "From: ".$from."\n";
        $string .= "Message: ".$message."\n";
        $string .= "Timestamp: ".$sent_timestamp."\n";
        $string .= "Messages Id:" .$message_id."\n";
        $string .= "Sent to: ".$sent_to."\n";
        $string .= "Device ID: ".$device_id."\n\n\n";

        write_message_to_file($string);
    }
    /**
     * Comment the code below out if you want to send an instant
     * reply as SMS to the user.
     *
     * This feature requires the "Get reply from server" checked on SMSsync.
     */
     send_instant_message($from);

    /**
      * Now send a JSON formatted string to SMSsync to
      * acknowledge that the web service received the message
      */
     $response = json_encode([
        "payload"=> [
            "success"=>$success,
                "error" => $error
            ]
        ]);

     //send_response($response);
}

/**
 * Writes the received responses to a file. This acts as a database.
 */
function write_message_to_file($message)
{
    $myFile = "test.txt";
    $fh = fopen($myFile, 'a') or die("can't open file");
    @fwrite($fh, $message);
    @fclose($fh);
}

/**
 * Implements the task feature. Sends messages to SMSsync to be sent as
 * SMS to users.
 */
function send_task()
{
    /**
     * Comment the code below out if you want to send an instant
     * reply as SMS to the user.
     *
     * This feature requires the "Get reply from server" checked on SMSsync.
     */
    if (isset($_GET['task']) AND $_GET['task'] === 'send')
    {
        $m = "Sample Task Message";
        $f = "+819029842384";
        $s = "true";
        $reply[0] = [
            "to" => $f,
            "message" => $m,
            "uuid" => "1ba368bd-c467-4374-bf28"
        ];

        // Send JSON response back to SMSsync
        $response = json_encode(
            ["payload"=>[
                "success"=>$s,
                "task"=>"send",
                "secret" => "123456",
                "messages"=>array_values($reply)]
            ]);

        send_response($response);
    }
}

/**
 * This sends an instant response when the server receive messages(SMSs) from
 * SMSsync. This requires the settings "Get Reply from Server" enabled on
 * SMSsync.
 */
function send_instant_message($to)
{

    $m = "Your message has been received";
    $f = "09029842384";
    $s = true;

    $reply[0] = [
        "to" => $to,
        "message" => $m,
        "uuid" => "1ba368bd-c467-4374-bf28"
    ];

    // Send JSON response back to SMSsync
    $response = json_encode(
        ["payload"=>[
            "success"=>$s,
            "task"=>"send",
            "secret" => "123456",
            "messages"=>array_values($reply)]
        ]);

    send_response($response);
}

function send_response($response)
{
    // Avoid caching
    header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
    header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
    header("Content-type: application/json; charset=utf-8");

    echo $response;
}

function get_sent_message_uuids()
{

    $data = file_get_contents('php://input');

    $queued_messages = file_get_contents('php://input');

    // Writing this to a file for demo purposes.
    // In production, you will have to process the JSON string
    // and remove the messages from the database or where ever the
    // messages are stored so the next Task run, the server won't add
    // these messages.
    write_message_to_file($queued_messages."\n\n");

    send_message_uuids_waiting_for_a_delivery_report($queued_messages);

}

/**
 * Sends message UUIDS to SMSsync for their sms delivery status report.
 * When SMSsync send messages from the server as SMS to phone numbers, SMSsync
 * can send back status delivery report for these messages.
 */
function send_message_uuids_waiting_for_a_delivery_report($queued_messages)
{
    // Send back the received messages UUIDs back to SMSsync
    $json_obj = json_decode($queued_messages);

    $response = json_encode(
    [
        "message_uuids"=>$json_obj->queued_messages
    ]);

    send_response($response);
}

function send_messages_uuids_for_sms_delivery_report()
{
    $response = json_encode(
    [
        "message_uuids" => ['1ba368bd-c467-4374-bf28']
    ]);

    send_response($response);

}

/**
 * Get status delivery report on sent messages
 *
 */
function get_sms_delivery_report()
{
    if($_GET['task'] === 'result' AND $_GET['secret']=== '123456')
    {
        $message_results = file_get_contents('php://input');
        write_message_to_file("message ".$message_results."\n\n");
    }
}

// Execute functions above
if($_SERVER['REQUEST_METHOD'] === 'POST')
{
    if(isset($_GET['task']) AND $_GET['task'] === 'result'){
        get_sms_delivery_report();
    }
    else if( isset($_GET['task']) && $_GET['task'] === 'sent')
    {
        get_sent_message_uuids();
    }
    else
    {
        get_message();
    }
}
else
{
    send_task();
    send_messages_uuids_for_sms_delivery_report();
}

Assuming you've the above code saved in a file called demo.php and is located at your web server's document root, you can issue the command below to test.

    $ curl -D - -X POST http://localhost/demo.php \
        -F "from=09048370465" \
        -F "message=sample text message" \
        -F "secret=123456"

The server should return a JSON response indicating a success:true or success:false

For a complete web service application, look at Ushahidi's SMSsync plugin which utilizes most of SMSsync's features.

There is also SMSsync webservice for Django that implements most of the features. You can download it from GitHub.com. Thanks to Caine Wanjau

 

Alerts

As of v2.7 and above, you should be able to query for the status of the device running SMSsync with query codes. For example, if you want to know if the device can still reach the web server, just text @20 to the device and you should receive a text message back with the status of the server.

Below are the query codes supported at the moment.
Query code @xx Query + Query response - Query response
@10 Is cell reception ok cell reception ok The phone sends no response.
@20 Is server ok server responded with status code.Eg. server responded with 200 status code Cannot reach server.
@30 Battery level Battery level is Eg. battery level is 10% The phone sends no response.
@40 Get all statuses All the query's positive responses All the query's negative responses