Dedicated two way SMS

Overview

Dedicated two way SMS service is the most comprehensive way to send and receive SMS on Airsob. We provide you with your own dedicated mobile number with which you can send and receive SMS. Sending SMS is still as easy as doing a HTTP GET request to our server with the message you want to send and the number you want to send it to. And if anyone sends an SMS to your dedicated mobile number, it will be forwarded to your app. It costs N20,000 to setup with a N5,000 monthly subscription fee.

Setting up the Service

Before you can use the Dedicated two way SMS service, you need to first setup the service. To do so, follow the instructions below:

  1. Create an Airsob account.
  2. In your dashboard, click on Create new Service.
  3. In type of service, select Dedicated two way SMS.
  4. Enter a name for the service (this is simply to help you identify the service on your dashboard).
  5. Give a brief description of your project (explain what kind of project this SMS service will be used for. If your project can be found online, include a website link. If your project is not online, include link to a screenshot or give a detailed description of the project. Please note that Airsob can only be used for user-specific product/service, where you communicate with one user at a time, so it cannot be used for bulk SMS. For instance, you won’t be able to send up to 10 or more identical or similar messages within a minute on Airsob).
  6. Indicate how you want your service to access the airtime on your account (specify whether you want your service to only have access to a limited airtime you allocate to it or you want it to have unlimited access to all the airtime on your account.)
  7. Specify a delivery report email (if you’ll like us to send you an email to let you know the status of the SMS you sent after it has been completely processed, you can provide us with an email address here. This is optional. However, if you do choose to receive the email, you can also specify whether you want to receive it every time your message has been completely processed or only when there was a failed message in the batch).
  8. Select what you want us to do if you get an incoming SMS (your options include sending the SMS as an email to a specified email address or sending it as an SMS to a specified phone number or triggering a script. You can select more than one. However, if you do select to send it as an SMS, you’ll be charged for the SMS. Also, whether or not you select an action, you will still be able to view the SMS in the inbox folder on your dashboard. However, if you selected an action, after performing the action, the message will appear as Read in your inbox folder. If you don’t select any incoming SMS action, it will appear as Unread).
  9. Enter a Customer Support phone number (this is a number your users can use to reach you if they have any problem with your service. You will have to verify the phone number so we know it’s actually yours.)
  10. Click Create Service.

After you click Create Service, the SMS service will be created in Testing mode and you will be provided with a Service ID and a Service Key which are the last two parameters you need to start sending SMS. You can start sending SMS immediately, however, you can only send it with our shared mobile number as your dedicated number would not have not been issued at this time. Furthermore, we strongly advise you only use it for testing purpose at this time because the service will contain some restrictions in testing mode.

After we review and approve the service, we’ll send you an email so you can proceed to pay the N15,000 setup cost and get your dedicated mobile number. Approval usually takes less than 24 hours depending on how well you described the project the SMS service will be used for. Set up time after setup cost is paid usually takes less than 3 days.

Sending SMS

To send an SMS, simply make a HTTP GET request to https://api.airsob.com/sms/ with the following parameters:

  1. message: (string) (required) the message you want to send. Maximum of 925 characters (i.e. 6 SMS parts).
  2. number: (string) (required) the number you want to send the SMS to. Separate multiple numbers with commas: maximum of 5 numbers. Only Nigerian based mobile numbers will be accepted.
  3. service_id: (integer) (required) your Service ID.
  4. signature: (string) (required) a HMAC-SHA256 hex digest of your message, number and service_id. For example, if your message is “This is a demo” and your number is “07012345678,2348012345678,080234hhjjsoo12” and your service_id is “1234”, create a concatenated string of your message:number:service_id which will be “This is a demo:07012345678,2348012345678,080234hhjjsoo12:1234”. Then do a HMAC-SHA256 hash of the concatenated string with your Service key to get your signature. See sample codes below.
  5. callback_url: (string) (optional) the URL to the script you want us to trigger when your message status changes.
  6. callback_frequency: (string) (optional) how frequent you want us to trigger the callback_url. Your options include Instant (if you want us to trigger the script immediately the message status changes) or Complete (if you want us to trigger the script only once, when the message has been completely processed). Default: Complete.
  7. format: (string) (optional) the format you want the SMS information to be returned in. Your options are json, xml, txt. Default: json.

A sample request to send an SMS will look like something below:

Java Python PHP Perl Ruby

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;

String message = "This is a demo";
String number = "07012345678,2348012345678,080234hhjjsoo12";
String service_id = 1234;
String format = "json";
String service_key = "B123bgGHU2342aB2GGfesyHUTJuyhTGR";
String data = String.join(":", message, number, service_id ); // In Java 8 (or newer), you can use String.join() method to create the concatenated string
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(service_key.getBytes(), "HmacSHA256");
sha256_HMAC.init(secretKey);
byte[] check = sha256_HMAC.doFinal(data.getBytes());
String signature = Hex.encodeHexString(check);
HttpClient httpclient = new HttpClient();
HttpMethod method = new GetMethod("https://api.airsob.com/sms/");
NameValuePair[] valuePair = new NameValuePair[] {
   new NameValuePair("message",message),
   new NameValuePair("number",number),
   new NameValuePair("service_id",service_id),
   new NameValuePair("signature",signature),
   new NameValuePair("format",format)
};
method.setQueryString(valuePair);
try {
   httpclient.executeMethod(method);
} catch (HttpException e) {
   e.printStackTrace();
} catch (IOException e) {
   e.printStackTrace();
}
String response = null;
try {
   response = method.getResponseBodyAsString();
} catch (IOException e) {
   e.printStackTrace();
}

Handling the Response

After you make the request to send an SMS, our server will return the status of the request showing whether or not it was accepted. If the request was not accepted, it will return a Failed status and also the reason why the request failed in the status_txt. See the examples below:

With format=json

{
  "status" : "Failed",
  "status_code": 400,
  "status_txt": "Incorrect signature.",
  "data": null
}

With format=txt

status: Failed

On the other hand, if the request was accepted, it will return a Successful status with the SMS information.

With format=json

{
  "status" : "Successful",
  "status_code": 202,
  "status_txt": "Accepted",
  "data": {
    "message_type": "Sent", 
    "message_id": 51126, 
    "message_text": "This is a demo", 
    "message_sender": "2348123456789", 
    "message_recipients": [ 
        "07012345678", 
        "2348012345678", 
        "080234hhjjsoo12",  
    ], 
    "message_status": "Pending", 
    "message_cost": 3, 
    "summary_report": "2 Pending and 1 Invalid", 
    "detailed_report": { 
        "2347012345678": "Pending", 
        "2348012345678": "Pending", 
        "080234hhjjsoo12": "Invalid" 
    }, 
    "service_id": 50955, 
    "signature": "581414ff6dc2101eefc5eb4e4398b30a3f6b7860cc7f93ee447320445e35292c" 
  }
}

With format=txt

status: Successful

The SMS information will contain the following parameters:

  1. message_type: (string) the message type: whether Sent or Received.
  2. message_id: (integer) the ID for that message.
  3. message_text: (string) an echo back of the message you sent.
  4. message_sender: (string) the mobile number that will appear as the message sender on the recipient’s mobile phone.
  5. message_recipients: (array) the recipients of the message.
  6. message_status: (string) the status of the message. Possible values: Pending, Completed, Delivered, Sent, Sending, Rejected, Undelivered, Invalid or Failed.
  7. message_cost: (integer) the cost of sending the message.
  8. summary_report: (string) a summary of the delivery report.
  9. detailed_report: (array) an associative array providing details of the delivery report with the recipient as the key and the status of the message sent to that recipient as the value. Possible values for the status include: Delivered, Sent, Sending, Rejected, Undelivered, Invalid or Failed.
  10. service_id: (integer) an echo back of the Service ID you sent when sending the SMS.
  11. signature: (string) an echo back of the signature you sent when sending the SMS.

You can extract the SMS information from the server response and process it accordingly. A sample code will look like something below:

Java Python PHP Perl Ruby

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;

String message = "This is a demo";
String number = "07012345678,2348012345678,080234hhjjsoo12";
String service_id = 1234;
String format = "json";
String service_key = "B123bgGHU2342aB2GGfesyHUTJuyhTGR";
String data = String.join(":", message, number, service_id ); // In Java 8 (or newer), you can use String.join() method to create the concatenated string
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(service_key.getBytes(), "HmacSHA256");
sha256_HMAC.init(secretKey);
byte[] check = sha256_HMAC.doFinal(data.getBytes());
String signature = Hex.encodeHexString(check);
HttpClient httpclient = new HttpClient();
HttpMethod method = new GetMethod("https://api.airsob.com/sms/");
NameValuePair[] valuePair = new NameValuePair[] {
   new NameValuePair("message",message),
   new NameValuePair("number",number),
   new NameValuePair("service_id",service_id),
   new NameValuePair("signature",signature),
   new NameValuePair("format",format)
};
method.setQueryString(valuePair);
try {
   httpclient.executeMethod(method);
} catch (HttpException e) {
   e.printStackTrace();
} catch (IOException e) {
   e.printStackTrace();
}
String response = null;
try {
   response = method.getResponseBodyAsString();
} catch (IOException e) {
   e.printStackTrace();
}

// Parse the json response. In this case we're using the org.json library.
// A downloadable jar can be gotten at http://mvnrepository.com/artifact/org.json/json

import org.json.*;

JSONObject obj = new JSONObject(response);
if (obj.getString("status").equals("Failed")) {
   // An error has occured
   String error = obj.getString("status_txt");
} else {
    // There was no error. Proceed to process the SMS response
    String message_id = obj.getJSONObject("data").getString("message_id");
    String message_status = obj.getJSONObject("data").getString("message_status");
    String message_cost = obj.getJSONObject("data").getString("message_cost");
}

If you provided a callback_url when making the SMS request, we’ll send some of the SMS information via HTTP GET to the callback_url. The information we’ll send will include:

  1. message_id: (integer) the ID for that message.
  2. message_status: (string) the status of the message. Possible values: Pending, Completed, Delivered, Sent, Sending, Rejected, Undelivered, Invalid or Failed.
  3. message_text: (string) an echo back of the message you sent.
  4. recipients: (string) an echo back of the numbers you sent the message to.
  5. service_id: (integer) an echo back of the Service ID you sent when sending the SMS.
  6. signature: (string) an echo back of the signature you sent when sending the SMS.

We recommend you verify that the HTTP GET request was from us before you start processing it. You can do this by checking if the signature sent to the script via the HTTP GET request is correct. To check if the signature is correct, you have to first generate the correct signature yourself then compare it to the one sent to you. To generate the correct signature, do a HMAC-SHA256 hex digest of the message_text, recipients and service_id sent to you. For example, if the message_text is “This is a demo” and the recipients is “07012345678,2348012345678,080234hhjjsoo12” and the service_id is “1234”, create a concatenated string of the message_text:recipients:service_id which will be “This is a demo:07012345678,2348012345678,080234hhjjsoo12:1234”. Then do a HMAC-SHA256 hash of the concatenated string with your Service key to get your signature. If the signature you generated match with the one sent in the HTTP GET request, then the request is from us. If they don’t match, then the request was not from us.

A sample code will look like something below:

Java Python PHP Perl Ruby

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;

public class MyServlet extends HttpServlet {
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
      throws ServletException, IOException {

    String get_message_text = request.getParameter("message_text");
    String get_recipients = request.getParameter("recipients");
    String get_service_id = request.getParameter("service_id");
    String get_signature = request.getParameter("signature");
    String service_key = "B124bgGHU2442aB2GGfesyHUTJuyhTGR";
    String data = String.join(":", get_message_text, get_recipients, get_service_id ); // In Java 8 (or newer), you can use String.join() method to create the concatenated string

    // Generate correct signature
    Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretKey = new SecretKeySpec(service_key.getBytes(), "HmacSHA256");
    sha256_HMAC.init(secretKey);
    byte[] check = sha256_HMAC.doFinal(data.getBytes());
    String correct_signature = Hex.encodeHexString(check);

    // Compare the signature you generated with the signature sent by the Get request
    if (get_signature != null && get_signature.equals(correct_signature)) {
            //Everything is good. Proceed to process your payment.
            String message_id = request.getParameter("message_id");
            String message_status = request.getParameter("message_status");
    } else {
            //Something's wrong.
            PrintWriter pw = response.getWriter();
            pw.println("Error: Forbidden");
            pw.close();
    }
  }
}

It is also possible to retrieve the SMS information at any time after the request is made. To do this, simply do a HTTP GET request to https://api.airsob.com/messages/ with the parameters below:

  1. message_id: (integer) (required) the ID for the message which information you want to retrieve.
  2. signature: (string) (required) the signature for that message.
  3. format: (string) (optional) the format you want the SMS information to be returned in. Your options are json, xml, txt. Default: json.

Processing Incoming SMS

If an SMS is sent to your dedicated mobile number, the SMS will be forwarded to your service and will be processed based on the setting you specified in your Incoming SMS action. However, please note that you can only receive SMS from Nigerian based mobile numbers.

If you did not specify any action as your Incoming SMS Action, then the message will be saved in the Inbox folder on your dashboard as an Unread message. However, if you did specify an Incoming SMS Action, then after processing the SMS according to your setting, the message will be saved as a Read message in the Inbox folder on your dashboard.

These are how the incoming SMS will be processed: if you selected that an email be sent to you, then we will send you an email in the format below:

Hello John Doe,

You have an incoming SMS on your Airsob service: Demo Dedicated Two Way SMS. See details below:

From: 234812345678
Message:
This is a demo reply

Best Regards,
The Airsob Team

If you selected that an SMS be sent to you, we’ll send you an SMS in the format below. Please note that the service which received the incoming SMS will be billed for the forwarded SMS. So the SMS won’t be sent if the service does not have sufficient credit to send the SMS.

Forwarded SMS from Airsob
----
From: 234812345678
Message: This is a demo reply

If you selected that we trigger a script, we’ll send the incoming SMS information via HTTP GET to the script you specified. The SMS information will contain the following parameters:

  1. message_type: (string) the message type: whether Sent or Received.
  2. message_id: (integer) the ID for that message.
  3. message_text: (string) the incoming message.
  4. message_sender: (string) the mobile number that sent the message
  5. message_recipient: (string) the mobile number your service used to receive the message.
  6. service_id: (integer) the ID of the service that received the message.
  7. signature: (string) a HMAC-SHA256 hex digest of the message_text, message_sender and service_id. For example, if the message_text is “This is a demo reply” and the message_sender is “07012345678” and your service_id is “1234”, to get the signature, we created a concatenated string of the message_text:message_sender:service_id which will be “This is a demo reply:07012345678:1234”. Then we did a HMAC-SHA256 hash of the concatenated string with your Service key to get the signature.

We recommend you verify that the HTTP GET request was from us before you start processing it. You can do this by checking if the signature sent to the script via the HTTP GET request is correct. To check if the signature is correct, you have to first generate the correct signature yourself using the same method we specified above then compare it to the one sent to you. If they match, everything is good. If they don’t match, then the request was not from us.

A sample code will look like something below:

Java Python PHP Perl Ruby

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;

public class MyServlet extends HttpServlet {
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
      throws ServletException, IOException {

    String get_message_text = request.getParameter("message_text");
    String get_message_sender = request.getParameter("message_sender");
    String get_service_id = request.getParameter("service_id");
    String get_signature = request.getParameter("signature");
    String service_key = "B123bgGHU2342aB2GGfesyHUTJuyhTGR";
    String data = String.join(":", get_message_text, get_message_sender, get_service_id ); // In Java 8 (or newer), you can use String.join() method to create the concatenated string

    // Generate correct signature
    Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretKey = new SecretKeySpec(service_key.getBytes(), "HmacSHA256");
    sha256_HMAC.init(secretKey);
    byte[] check = sha256_HMAC.doFinal(data.getBytes());
    String correct_signature = Hex.encodeHexString(check);

    // Compare the signature you generated with the signature sent by the Get request
    if (get_signature != null && get_signature.equals(correct_signature)) {
            //Everything is good. Proceed to process your payment.
            String message_type = request.getParameter("message_type");
            String message_id = request.getParameter("message_id");
            String message_recipient = request.getParameter("message_recipient");
    } else {
            //Something's wrong.
            PrintWriter pw = response.getWriter();
            pw.println("Error: Forbidden");
            pw.close();
    }
  }
}