Introduction
Interactive SMS messaging opens new opportunities for building dialogue with clients and providing additional services. Interactivity assumes a flexible process when messages/questions/responses may change depending on the information provided or available to the system. For example, we will create a simple interactive script for imaginary online clinic. It will perform health monitoring via SMS and will choose questions depending on symptoms provided by respondents.
The basic interactive SMS-script relies on Octopush API features and PHP scripting language. Our sample questions will be about name, body temperature and optionally about heat. To start interactive questioning a person should send a keyword START to assigned Octopush virtual number. It will be followed by a set of questions. The question about current body temperature will accept only numeric value as a response. Depending on temperature data provided by respondent the SMS-script will decide on the next question to ask.
Prerequisites
- Octopush account
- Octopush premium service (virtual number) active
- Web-hosting space with PHP support
- Registered or temporary domain name pointing to the web-hosting space
Implementation
To get the sample script working you need to obtain a virtual number from Octopush. Also, you need to setup it so all inbound SMS are forwarded to the script address.
The SMS-Script itself it to be placed at some hosting supporting PHP (nowadays most of hosting providers do). It should be reachable via the Internet so Octopush API can send the arrived SMS to it. You can copy paste set of files provided at the end of the article. To make it work you need to edit file “api-octoush.php” and fill in your own API data there.
The result of each session is stored as a text file in the same folder where the script is located.
Hosting setup
This part can be tricky depending on your experience or hosting provider rules. Make sure you have either a registered domain name either a temporary domain name or an IP-address pointing to the web-hosting space. Alternatively, you may set up your local hosting with XAMPP or similar tools for running PHP scripts.
Commonly the main folder at hosting space has the name “public_html”. Let’s create a subfolder “sms-interview” inside your “public_html” (or similar) folder at your hosting location. Also create a file named index.html inside the “sms-interview” folder. Write some text inside it (like a “test page”) and save changes. File is not a part of the script, but useful for preventing the folder from browsing.
Now you should have the folder “sms-interview” with file “index.html” at your hosting space in the main hosting folder. You can check if it’s accessible by visiting the URL “http://your-domain-name/sms-interview/” or “http://your-domain-name/sms-interview/index.html”. If all works fine you should see the text from the index.html file inside your browser window.
Download 4 files located at the end of this article and upload them to your hosting space “sms-interview “-folder next to the index.html file. So the path for saving files will be like “public_html/sms-interview/” in the case of accessing via FTP.
The script consists of 4 files:
- api-octopush.php – your Octopush account API details
- start.php – “secret” script to start interviewing the recipient (sends the first question)
- interview.php – “main” script. It receives SMS-response via Octopush API and sends the next question automatically
- questions.json – lists all questions
You can manage files creation or uploads via the file manager located inside hosting control panels (like cPanel, Plesk etc.). Then you only need to copy/paste the content of our examples.
Virtual number setup
You need to have a number for getting responses – the Octopush virtual number. Order the virtual number at Octopush panel in Premium services section. You need to send email to technical support team and ask to setup URL for getting inbound SMS arrived at this virtual number. If you follow “hosting setup” section – your URL will be like http://your-domain-name/sms-interview/interview.php
After number setup done properly, you should see all inbound SMS at https://client.octopush.com/sms-campaigns/history-of-answers and also arriving to the URL.
Questions file
To make questioning flexible and interactive we need to describe this process first. Now we will use more advanced file markup (compared to “Automated SMS-survey with Octopush API” article) to store all details.
Each question has several fields. Field “next” points to the next message to be sent. The special case of “next” is “-2” which means “end of session”.
In question with ID:1 there is a “condition” field as well as the value to compare to. Depending on condition result the script will choose a next item ID among “true_next” and “false_next” fields accordingly.
In our case the condition will compare the inbound message data to the “value” of 95. If provided temperature value is higher than that, the script will proceed to item with ID:3 (field “true_next”) – otherwise the next item will be ID:5 (from the field “false_next”).
The goal of the item ID:3 it to collect more information about person as high temperature means there are more symptoms could be. Item with ID:5 just ends dialogue gracefully.
As you can see item with ID:3 is a next question about health state, but item with ID:5 is a statement having “-2” in a field “next”. It means this ID:5 message will automatically close the session.
Sample questions file (questions.json) lists some sample questions with interactivity implemented in item ID:1
[
{
"id":0,
"text":"What is your name?",
"next":"1"
},
{
"id":1,
"text":"What is your temperature (Fahrenheit, digits and dot only in format XX.XX)?",
"condition":">=",
"value":"95",
"true_next":"3",
"false_next":"5"
},
{
"id":2,
"text":"Do you have a headache?",
"next":"3"
},
{
"id":3,
"text":"Do you have a fever?",
"next":"4"
},
{
"id":4,
"text":"You should see a doctor, our medic will call you soon.",
"next":"-2"
},
{
"id":5,
"text":"Your health is good. Have a nice day!",
"next":"-2"
}
]
Sample script first start
Just copy files to your hosting and fill “api-octopush.php” fields with your data and settings. You can get all these values from your personal panel on Octopush website.
$user_login = "";
$api_key = "";
This field should contain your virtual number assigned by Octopush service. Put it instead of ‘Octopush’ word here:
$sms_sender = "Octopush";
This line turns “simulation” mode on. No real SMS will be sent. To start sending a real SMS comment it out with double slash.
//sets SIMULATION
$sms->set_simulation_mode();
Send word START to your Octopush virtual number. You should get a response with the first message from the “questions.json” file i.e. “What is your name?”. It means your setup is correct.
How the script works
When the dialogue begins current timestamp is stored in a file named after sender. Once delay between last SMS (received or sent) became more than allowed threshold dialogue is considered outdated. User can’t continue the expired session, but only can start it over. This threshold is defined in seconds at the first lines of the “sms-next.php” script ($new_session_threshold = 30).
Questions-file “questions.json” contains questions and statements. Some questions may have “conditions” for checking input and choosing the next message to send. It is implemented for item ID:1 (temperature question). In this example the script checks if the input is numeric or not before applying a condition check. It will not proceed till numeric value is provided.
The file markup assumes each question contains information about the next item. It is either next item ID either “-2” for immediate ending.
To track the session progress script creates several additional files. Each filename begins with sender number and followed by word “-result”, “-timestamp” or “-index”.
- In a “-result” file script stores all inbound and outbound messages for current session. At the end this file contains the full history of each dialogue. If dialogue ends properly – file renamed and timestamp is added to the filename.
- File “-timestamp” stores last transaction time information (receiving or sending SMS)
- “-index” file contains the ID of the last processed item from “questions.json”
Warnings
Be aware – multiple sending of the START keyword to your virtual number with SMS-script attached may result in excessive credit spending. As each time the keyword comes in from the different number or after timeout threshold passed – the script will generate new SMS-response (the very first question). Before putting such system into production, please make sure you’ve implemented all necessary restrictions and checks.
Limitation rules
There are some limitation rules already implemented in the script. It is based on the threshold value (amount of seconds passed after last transaction) and applies to starting new conversations and to continuing current conversation:
- If sender already replied to the last question (session closed) and sends “START” keyword again – it will be ignored during 30 seconds after session closed.
- If there will be more than 30 second pause after last response received – the dialogue is considered closed and cannot be continued. It only can be started with START keyword.
The threshold is a value set inside the “sms-next.php” script – 30 by default.
Conclusion (Ways to Improve)
- Implement Regex based keyword recognition
- Limit number of sessions per sender per day (to save SMS-credits)
- Use previous response value in the next question (call respondent by name in the next message)
====Copy Paste script files===
Files config.inc.php and sms.inc.php from GITHUB link https://github.com/octopush/API-SMS-Octopush-PHP/tree/master/API_SMS_PHP_Octopush
Need to put into a sub-folder API-SMS-Octopush-PHP:
Script file “api-octopush.php”
set_user_login($user_login);
$sms->set_api_key($api_key);
$sms->set_sms_mode($sms_mode);
$sms->set_sms_type($sms_type);
$sms->set_sms_sender($sms_sender);
//sets SIMULATION
$sms->set_simulation_mode();
?>
Script file “sms-next.php”
text." to ".$senderId);
$sms->set_sms_text($questions[$nextMessage]->text);
$sms->set_sms_recipients(array($senderId));
$xml = $sms->send();
//write timestamp
file_put_contents($senderId."-timestamp.txt", time());
//update index & result
if($questions[$nextMessage]->next=="-2")
{
//ending session
file_put_contents($senderId."-result.txt", $inboundMsg.PHP_EOL, FILE_APPEND);
file_put_contents($senderId."-result.txt", $questions[$nextMessage]->text.PHP_EOL, FILE_APPEND);
file_put_contents($senderId."-result.txt", "SESSION OVER".PHP_EOL, FILE_APPEND);
rename($senderId."-result.txt", $senderId."-result-".time().".txt"); //making timestamped copy of last result
file_put_contents($senderId."-index.txt", "-2");
}
else
{
file_put_contents($senderId."-result.txt", $inboundMsg.PHP_EOL, FILE_APPEND);
file_put_contents($senderId."-index.txt", $nextMessage);
file_put_contents($senderId."-result.txt", $questions[$nextMessage]->text.PHP_EOL,FILE_APPEND);
}
function GetNextMessage($lastIndex, $inboundMsg, $questions)
{
$result = null;
if ($lastIndex==-1) die(" waiting for correct input");
$lastQuestion = $questions[$lastIndex];
//check if there any condition
if (isset($lastQuestion->condition))
{
switch ($lastQuestion->condition) {
case ">=":
if (!is_numeric($inboundMsg))
{
die(" waiting for numeric input");
}
if ($inboundMsg>=$lastQuestion->value)
{
$result = $lastQuestion->true_next;
}
else
{
$result = $lastQuestion->false_next;
}
break;
}
}
else //no conditions present
{
$result = $lastQuestion->next;
}
return $result;
}
function GetQuestions($filename)
{
if (file_exists($filename)) {
$questions_json = file_get_contents($filename);
$questions = json_decode($questions_json); //array of question objects
if (count($questions)<1)
{
die("questions file need to have at least 1 question");
}
} else
{
die("questions file does not exists");
}
return $questions;
}
function CheckTimestamp($filename, $session_threshold)
{
//timestamp file does not exists (means there were no sessions ever)
if (!file_exists($filename)) return false;
$timestampLast = file_get_contents($filename);
//timestamp is outdated
if ((time() - intval($timestampLast)) > $session_threshold) return false;
//timestamp existis & session not outdated
if ((time() - intval($timestampLast)) <= $session_threshold) return true;
}
function GetIndex($filename)
{
//inde-file file does not exists (means there were no sessions ever)
if (!file_exists($filename)) return -3;
$index = file_get_contents($filename);
return $index;
}
?>
- Octopush premium service (virtual number) active
- Web-hosting space with PHP support
- Registered or temporary domain name pointing to the web-hosting space
- Web browser