Vox Populi (Latin for “Voice of the People”) aims to provide useful information on interactive communication technologies and social networking tools that can be used by government officials to improve services to citizens and taxpayers. This is the voice of Government 2.0.

5th
JUL

Building Cloud Communication Apps with Tropo: Part 4

Posted by Mark Headd under Development Tools, Tropo, Tutorials, Twitter

This post is the final installment in the series on building cloud communication applications with Tropo, the PHP WebAPI Library and the Limonade framework for PHP.

If you’re just starting, you can take a look back at part 1, part 2 and part 3 to get caught up.

In the last installment, we finished our first complete script using the PHP WebAPI Library and Limonade. We tested this script by calling it using one of the numbers automatically provisioned for applications on the Tropo platform. In this case, we used the auto provisioned Skype number to make test calls.

In this post we’ll refine our script by optimizing it so that the exact same code can efficiently service users on an array of different communication channels. This is the definition of “multi-modality,” and the Tropo platform does it better than pretty much any other platform currently available to developers.

So Many Channels, So Little Code

Tropo’s strong suit is empowering developers to build applications that work across multiple channels from the same code base. Enabling different channels for existing application is easy - log into your Tropo account and go to “Your Applications.” Select the application we’ve been using for this series, and make note of the sections entitled “Phone Numbers” and “Instant Messaging Networks.”

To SMS-enable your application (so that users can simply send a text message to get weather information) select Add a New Phone Number. The phone number you add can be used for both voice phone calls and for SMS messages. Under “Instant Messaging Networks” you can add any one of the many networks supported by Tropo - for this example, we’ll add a Jabber account so we can test a channel other than voice.

If you set up a Jabber account for your app, you can interact with it by sending it a message - try starting things off by sending a simple message like “Hello.” Once you do, you’ll see the same series of prompts that you can hear when you call into your application via Skype.


IM Bot Before Changes

Now that we can see how our application behaves when we interact with it using an IM client, it becomes obvious that there are some things we’d like to change to optimize it for this channel. User interface elements like a welcome message, reprompts (playing a prompt over again when a user has not entered any input), etc. don’t really make much sense in the context of an IM session. More importantly, it would be nice if we could simply send a zip code to our application to begin the session, as opposed to sending a message like “Hello.”

Fortunately, Tropo was built with multi-modality baked into it so changes like these are rather trivial. To illustrate how to optimize our application so that it can be used on multiple channels, consider the Session object we examined in detail in one of the previous posts in this series.

That Session object was created when we placed a phone call to our application - note that the property name initialText is null.

When we access our application using an IM client, the Session object looks like this:

This Session objects looks considerably different than the one created when we made a phone call to our application. In particular, you can see that the initialText property is now populated with the text we first sent - the string “Hello.”

We can access this property using the PHP WebAPI Library like so:

$session = new Session();
$initial_text = $session->getInitialText();

After accessing the value of this property, we need to do something with it:

if(strlen($initial_text) == 5 && is_numeric($initial_text)) {
	// Since the user submitted a zip code, look up weather info.
}

Now that we can access the initialText sent to our application, and we can examine it to determine if the user has sent us a valid zip code. This allows us to tailor the behavior of our app more efficiently to an IM channel without changing how it behaves when a caller makes a telephone call to it.


IM Bot Before Changes

The modified script with changes to optimize it for IM can be found here.

Conclusion

Clearly there are lots of other things we could do to tweak our application, to tailor it more efficiently to different channels supported by Tropo. For example, breaking out the weather information into discreet segments for temperature, wind, etc. (by using a separate Say object for each) might work well with a voice or IM channel, but it would probably not work well for SMS or Twitter.

Additional changes to optimize this script for these other channels is pretty straightforward. I won’t get into it in this post, but now that you’ve got the hang of how easy it is to create multi-modal communication apps with Tropo, Limonade and the PHP WebAPI Library you should give it a try.

Rock on!

21st
JUN

Building Cloud Communication Apps with Tropo: Part 3

Posted by Mark Headd under Development Tools, Tropo, Tutorials, Twitter, VoIP

This post is a continuation of the series on building cloud communication applications with Tropo, the PHP WebAPI Library and the Limonade framework for PHP .

If you’re just starting, you can take a look back at part 1 and part 2 to get caught up.

In this post, we’ll continue our work from the last post and complete a simple, yet powerful multi-channel application that can be accessed via telephone, SMS or IM client.

In the previous post, we looked closely at the Session and Result objects - these are JSON objects that are sent to your application by the Tropo platform that contain information about how a user is accessing your app (i.e., through which channel) and any input they have provided in response to prompts. If you worked through the last post, you have a partially complete script that looks like this:

You should save this script to a server that can be accessed by the Tropo platform - any web hosting platform that supports PHP >= 5.2.0 will do. Let’s call our script get_zip_code.php.

When you set up the start URL for this script in the Tropo Application Manager, you’ll want to structure it like so:

http://name_of_my_host.com/path/to/get_zip_code.php?uri=start

As you can see, we’ve added a querystring parameter called uri. This will ensure that the initial HTTP POST to this script by the Tropo platform matches our /start pattern and executes our zip_start() method, which is where we want users to begin. Make sure you review the Limonade documentation on setting up routes, as there are multiple options for configuring route pattern matching.

Next, we’ll want to start modifying our partially constructed script. First go to step 6 in the zip_start() method, where we had set up a PostBin URL for Tropo to send a user’s input to so we could examine the Result object. Now that we know what the Result object looks like, we want to start using it to look up information and present it to the caller.

You’ll want to set up a URL to the get_zip_code.php script that will match the route for the zip_end() method. This is where we will access the Tropo Result object and process it. Change the URL in the “next” array element to look like this:

$tropo->on(array(”event” => “continue”, “next” => “get_zip_code.php?uri=end“, “say” => “Please hold.”));

This change tells Tropo that when the “continue” event is raised (after the caller has completed entering input) POST the Result object back to the get_zip_code.php script using a relative URL and a querystring parameter that will ensure matching of our /end pattern.

Next, we need to build out the zip_end() method to process the results:

dispatch_post('/end', 'zip_end');
function zip_end() {

        // Step 1. Create a new instance of the result object
	$result = new Result();
	$zip = $result->getValue(); // get the value of the user input.

        // Step 2. Get weather information for the zip code the caller entered.
	$weather_info = getWeather($zip);
	$city = array_pop($weather_info);

        // Step 3. Create a new instance of the Tropo object.
	$tropo = new Tropo();

        // Step 4. Begin telling the user the weather for the city their zip code is in.
	$tropo->say("The current weather for $city is...");

        // Step 5. Iterate over an array of weather information.
	foreach ($weather_info as $info) {
	    $tropo->say("$info.");
	}

        // Step 6. Say thank you (never hurts to be polite) and end the session.
	$tropo->say("Thank you for using Tropo!");
        $tropo->hangup();

        // Step 7. Render the JSON for the Tropo WebAPI to consume.
       return $tropo->RenderJson();

}

As you can see, our zip_end() method looks similar to our zip_start() method - both use a Tropo object to format information that will be presented to the user, and both call the RenderJson() method of the Tropo object at the end.

You may be wondering about the getWeather() method that is called in step 2. Let’s build that out now and examine how it works - to keep things simple, we’ll make use of the Google Weather API, which provides weather information by zip code and returns the information in XML format.

// The URL to the Google weather service. Renders as XML doc.
define("GOOGLE_WEATHER_URL", "http://www.google.com/ig/api?weather=%zip%&hl=en");

// A helper method to get weather details by zip code.
function getWeather($zip) {

	$url = str_replace("%zip", $zip, GOOGLE_WEATHER_URL);
	$weatherXML = simplexml_load_file($url);
	$city = $weatherXML->weather->forecast_information->city["data"];
	$current_conditions = $weatherXML->weather->current_conditions;
	$current_weather = array(
		"condition" => $current_conditions->condition["data"],
		"temperature" => $current_conditions->temp_f["data"]." degrees",
		"wind" => formatDirection($current_conditions->wind_condition["data"]),
		"city" => $city
	);
	return $current_weather;

}

// A helper method to format directional abbreviations.
function formatDirection($wind) {
	$abbreviated = array(" N ", " S ", " E ", " W ", " NE ", " SE ", " SW ", " NW ");
	$full_name = array(" North ", " South ", " East ", " West ", " North East ", " South East ", " South West ", " North West ");
	return str_replace($abbreviated, $full_name, str_replace("mph", "miles per hour", $wind));
}

The mechanics of these functions are pretty straighforward, so I won’t go in to too much detail - you can now see the connection between the call to the getWeather() method mentioned above and the array of weather data that it returns.

The last thing we need to do in order to complete our zip code weather demo script is to finish the zip_error() method. This is a method we’ll use to tell a user an error occurred (never hurts to be prepared for the unexpected):

dispatch_post('/error', 'zip_error');
function zip_error() {

	// Step 1. Create a new instance of the Tropo object.
	$tropo = new Tropo();

	// Step 2. This is the last thing the user will be told before the session ends.
	$tropo->say("Please try your request again later.");

	// Step 3. End the session.
	$tropo->hangup();

	// Step 4. Render the JSON for the Tropo WebAPI to consume.
	return $tropo->renderJSON();
}

In order for this method to be invoked, we need to make sure that we set up the proper handler in our zip_start() method for it. The Tropo WebAPI makes it possible to set up callback methods that handle things when certain events are raised. This is done by using the On object.

Setting up an event handler using the On object with the PHP WebAPI Library is easy. In fact, we’ve already done it once - look at the zip_start() method and you’ll see a hander for the “continue” event (which is raised when a user has finished entering the proper input). We want to set up something similar for when an error event is raised. Let’s add a handler in our zip_start() method for an error event:

	// Step 6. Tell Tropo what to do when the user has entered input, or if there is an error.
	$tropo->on(array("event" => "continue", "next" => "get_zip_code.php?uri=end", "say" => "Please hold."));
	$tropo->on(array("event" => "error", "next" => "get_zip_code.php?uri=error", "say" => "An error has occured."));

Our script is now complete and ready to test.

Make sure you log into your Tropo account and set up the start URL to your script as discussed above. You can test this script with the phone numbers that are automatically provisioned by Tropo when you set up your account.

Tropo will automatically provision a Skype number, a SIP number and an iNum. You can additionally add a PSTN number in a range of different area codes at no charge. This PSTN number can also be used to send an SMS to, so you can interact with this script via text message. Additionally, you can add an IM account, so you can test this script using your favorite IM client/network.

You may notice, if you test this script using SMS or IM that there are things that don’t yet work perfectly. In the next post, we will make some very simple changes to this script to optimize it for use with SMS and IM (and even Twitter!).

This will transform our simple PHP script into a powerful unified communications application.

Stay tuned…

14th
JUN

Building Cloud Communication Apps with Tropo: Part 2

Posted by Mark Headd under Development Tools, Tropo, Tutorials, Twitter, VoIP

This post is a continuation of the series on building cloud communication applications with Tropo and the PHP WebAPI Library.

In this post, we’ll be looking at Tropo’s support for multi-channel applications and using the incredibly flexible and powerful Limonade library for PHP (think Sinatra for PHP).

Working with the Session Object

As I explained very briefly in the previous post on this subject, the Tropo WebAPI is an HTTP/JSON API for building multi-channel communication apps.

What this means essentially is that the Tropo platform does all of the hard stuff involved with executing a communication app - DTMF/speech recognition, rendering Text-To-Speech (TTS), maintaining and managing all of the connections to the different communication networks (PSTN, SMS, IM networks, Twitter). You tell Tropo how to govern the interaction between a caller and your application on a specific channel by sending it a set of instructions in JSON format.

In this series of posts, we’re using the PHP WebAPI Library for Tropo to generate the JSON that gets sent to, and consumed by Tropo. But this exchange of JSON isn’t one-way - Tropo also sends JSON packages to your application with important information about (among other things) the network a user selects to interact with your application on and any input they have provided in response to prompts.

At the beginning of a user session (when a user first connects to your application), Tropo will deliver a JSON Session object to your application. This object contains all sorts of useful information that your app can use when rendering out JSON instructions to send back to Tropo. Let’s examine what a real life Session object looks like.

The easiest way to do this is to simply go over to PostBin.org and make a new PostBin. PostBin is a service that lets you see HTTP posts that get sent to the special URL that is generated when you create a new PostBin.

After you have created a new PostBin, log into your Tropo account and create a new WebAPI application. Use the PostBin URL as the URL that powers your new Tropo WebAPI app. After your app is created, you will have a newly provisioned Skype number that you can use to call it.

When you call your application using the Skype number provisioned by Tropo, you won’t hear anything - remember, we haven’t yet generated any JSON to tell the Tropo platform what to say or do when a user connects. After you make your call (it will be over quickly), go back to your PostBin URL (you may need to refresh) and you will see an object in JSON format, like this:

This is the Session object for the call you just made. It’s what is sent to your application (via HTTP POST) each time a new session is started on Tropo. Working with this object using the PHP WebAPI Library is easy. You just create a new instance of the Session object in PHP and you can start accessing the properties of this object:


$session = new Session();
$from_info = $session->getFrom();
echo $from_info['channel'];

// Using the example Session object JSON from above would render VOICE.

Being able to access the channel and network a user is accessing your application from can be useful when you want to tailor prompts or actions to a specific channel - e.g., a phone call vs. an IM session.

Also make note of the initialText property - this will be important when building SMS and IM applications, where a user will begin an interaction with your application by sending information to it. This property will allow you to process the initial input for those channels without having to ask the user for it again (something users generally dislike).

Next, let’s take a look a the Result object that is sent from Tropo to your application when a user provides input in response to a prompt or direction. In order to do this, we need to take a sip of Limonade.

Mmmm… Limonade!

Limonade is a lightweight PHP framework that is very much like the Sinatra framework for Ruby. I won’t go into too much detail on it, as there is ample documentation available on the Limonade site , but here is quick introduction that will let us build enough of a structure to see the Tropo result object.

When you use Limonade, you set up routes for HTTP requests. A route is comprised of an HTTP method, a URL matching pattern and a PHP method. When an HTTP request is made to a URL that matches the pattern, and uses the method specified in the route, the designated PHP function gets invoked. For example:

dispatch_post('/', 'test');
  function test() {
    echo 'This is a test.';
}

The ‘dispatch_post()’ directive specifies that the HTTP method for this route with be POST (which is what is used by Tropo to send JSON to your application). The two parameters to this directive specify the URL pattern to match (in this case, the root directory on the domain were this script is located) and the PHP method to invoke, which is defined below this directive. In a nutshell, whenever an HTTP POST is made to the root domain where this script is located, the text This is a test will be rendered.

Let’s build out a simple shell that we’ll use to construct our Tropo application for the next few posts in this series:

// Include Tropo classes.
require('TropoClasses.php');

// Include Limonade framework (http://www.limonade-php.net/).
require('path/to/limonade/lib/limonade.php');

dispatch_post('/start', 'zip_start');
function zip_start() {
	// Tell the user to enter their zip code.
}

dispatch_post('/end', 'zip_end');
function zip_end() {
	// Do something with the entered zip code.
}

dispatch_post('/error', 'zip_error');
function zip_error() {
	// Tell the user an error has occurred.
}

// Run this sucker!
run();

Our Tropo application will collect a user’s zip code and then look up some information based on the input they provide. As you can see, we’ve included the PHP WebAPI Library and the Limonade Framework. We’ve also set up three Limonade routes start, end and error (all using the HTTP POST method) and stubbed out the PHP function that will render JSON for Tropo to consume.

To get a look at the Tropo Result object, lets add some logic to the zip_start() function:


dispatch_post('/start', 'zip_start');
function zip_start() {

	// Step 1. Create a new instance of the Session object, and get the channel information.
	$session = new Session();
	$from_info = $session->getFrom();
	$network = $from_info['channel'];	

       // Step 2. Create a new instance of the Tropo object.
	$tropo = new Tropo();

	// Step 3. Welcome prompt.
	$tropo->say("Welcome to the Tropo PHP zip code example for $network");

	// Step 4. Set up options for zip code input.
	$options = array("attempts" => 3, "bargein" => true, "choices" => "[5 DIGITS]", "name" => "zip", "timeout" => 5);

	// Step 5. Ask the caller for input, pass in options.
	$tropo->ask("Please enter your 5 digit zip code.", $options);

	// Step 6. Tell Tropo what to do when the user has entered input. Enter your PostBin URL in the "next" array element.
	$tropo->on(array("event" => "continue", "next" => "http://www.PostBin.org/xxxxxxx", "say" => "Please hold."));

	// Step 7. Render the JSON for the Tropo WebAPI to consume.
	return $tropo->RenderJson();

}

As you can see, inside this function we create a new instance of the Session object and get the channel the user is accessing our application from. We also create a new instance of the Tropo object (this is what we’ll use to send JSON instructions back to the Tropo platform).

The next several steps are fairly self explanatory, but take special note of Step 6. Here we are telling the Tropo platform that when a ‘continue’ event is raised (when a user finishes entering input) tell them to ‘Please hold’ and then POST the results of their input to a PostBin URL. (Note - replace the value above with the PostBin URL you used at the beginning of this tutorial.)

Working with the Result Object

Save your script and change the URL for your WebAPI application in the Tropo Applications manager to point to it. You can now test your script using the the Skype number for your app as we did before . When you access your script, you’ll get the instructions to enter a zip code, after which Tropo will POST the results to the PostBin URL you inserted into the script in Step 6 above.

Now, when you look at your PostBin URL, you’ll see something like this:

As you can see, the Result object that gets sent from Tropo to your app has a wealth of information on what the user entered, how it was interpreted by Tropo and even the confidence level of the recognition (if speech recognition is used).

You can access the Result object using the PHP WebAPI Library just like you can the Session object:

$result = new Result();
$zip = $result->getValue();
echo $zip

// Using the example Result object JSON from above would render 12345

You would use the Result object in the zip_end() function we stubbed out above. You use the value of the zip code entered to look up information relevant for that zip code (like a weather forecast) and present it to the caller.

In the next post in this series, we’ll complete our simple zip code example by adding a weather forecast lookup and present it to the user. We’ll also tweak our script to optimize it for different channels that a user might employ to access it, to ensure the experience is optimized for phone, IM and SMS.

Stay tuned…

6th
JUN

Building Cloud Communication Apps with Tropo: Part 1

Posted by Mark Headd under Development Tools, Tropo, Tutorials, VoIP

A few months back, I wrote a series of posts on building NoSQL telephony applications with Tropo and CouchDB. Today I’m going to start a continuation of that series, focusing on how to build cutting edge cloud communications apps with the Tropo WebAPI.

What is the Tropo WebAPI?

The Tropo WebAPI is, in a nutshell, an HTTP/JSON API for building multi-channel communication applications - applications that you interact with via phone, IM, SMS or Twitter. While my earlier series on Tropo focused on building applications in Tropo’s scripting environment (another fine option for developers), this series will focus on building JSON-based applications (generated using PHP) that can be hosted anywhere and executed in the Tropo cloud environment.

Faithful readers will recognize some similarities here to a post I did a while back on the HTTP/JSON API provided by CloudVox, another cloud telephony provider. While the concept behind these two API’s is very similar, there are some key differences that make Tropo a highly attractive option for developers.

First, the Tropo service is truly multi-channel - using the Tropo WebAPI you can build applications that work on a range of different communication channels, not just phones (although you can build some pretty slamming phone apps as well).

Since I’m a phone app developer at heart, some of the features that Tropo provides for phone applications really get me excited. Tropo supports both DTMF entry and speech recognition. It also has broad multilingual support. In addition, Tropo gives phone application developers the ability to manipulate SIP headers, an important feature in building sophisticated cloud communication apps that I hope to demonstrate down the road a bit.

Getting Started

Head on over to Tropo.com and set up a new account (if you don’t have one already). Take a little time to review the documentation for the Tropo WebAPI. For the example applications in this series of blog posts I’ll be using a PHP class library I developed specifically to interact with the Tropo WebAPI.

The crew behind Tropo have provided a Ruby Gem for interacting with the Tropo WebAPI. However, since I like to do my cloud telephony work with PHP I decided to write my own set of classes for doing this. Whether you’re a Ruby-head or a PHP enthusiast, using one of these tools to generate JSON for consumption by the Tropo WebAPI can make build an application significantly easier, particularly as you get into more sophisticated application development.

You can get my PHP Library, as well as some of the sample apps we’ll be looking at, from GitHub:

$ git clone git@github.com:mheadd/TropoPHP.git

You’ll need to host these classes and the PHP scripts you write with them on a server that can be accessed from the Tropo environment. Any web server that supports PHP will do.

My First Tropo WebAPI Application

Let’s start with the standard Hello World app:


< ?php

// Include Tropo classes.
require('path/to/TropoClasses.php');

// Create a new instance of the Tropo object.
$tropo = new Tropo();

// Add a prompt to the object using the Say() method.
$tropo->Say(”Hello World!”);

// Render the JSON for the Tropo WebAPI to consume.
$tropo->RenderJson();

?>

You can look at the rendered JSON in your browser, and you should see something like this:


{
    "tropo": [
        {
            "say": [
                {
                    "value": "Hello World!"
                }
            ]
        }
    ]
}

Go to the Applications section in your Tropo account and set up a new WebAPI application that points to the location of this script.


Create a new Tropo WebAPI application

Assign a URL to your new Tropo WebAPI application


When you create your application, Tropo will automatically provision a Skype number, a SIP number and an iNum. You can additionally add a PSTN number in a range of different area codes at no charge.

You may also notice the section below the provisioned phone numbers entitled “Instant Messaging Networks” - this section allows you to set up any number of different IM accounts (and Twitter!) that your application can use. We’ll dive deeper into this in future posts.

For now, we’ll keep it simple and use the auto provisioned Skype number - when you call this number, you will hear it say “Hello World.”

The next post in this series will focus on a more sophisticated application that uses the TropoPHP classes and the utterly awesome Limonade PHP framework.

Stay tuned…

25th
FEB

Cloudvox: Cloud Telephony Applications Made Easy

Posted by Mark Headd under Development Tools, Open Source, Tutorials

A couple of months ago, I did a quick write up on a new cloud telephony company named Cloudvox. In the interim, I’ve been doing some playing around with their HTTP/JSON API for creating telephone applications, and I’ve been blown away by how simple and powerful a tool it is for building sophisticated cloud telephony applications.

This post will provide a quick overview of how the Cloudvox JSON API can be paired with PHP and the delightfully awesome Limonade Framework. If you’re not a PHP developer don’t despair - this example can easily be ported to other languages like Ruby (using Sinatra) or C# (using Kayak).

Cloudvox API Helper Classes

When writing apps for the Cloudvox JSON API, there are two things that we need to manage - the JSON that we will send to Cloudvox (using plain old HTTP) and the response Cloudvox sends back to our app (this will include any user input collected from the caller, and also things like a unique identifier for the call, caller ID and other information about the call).

To make managing both sides of our exchange with Cloudvox easier, I’ve created a set of PHP classes that can be used with any standard PHP IDE to make writing Cloudvox JSON and parsing Cloudvox responses simple and easy. You can download this class library from GitHub.

Using these classes is pretty straightforward:


< ?php
include('cloudvox-json-http-classes.php');
$speak = new Speak("Hello world!");
$hangup = new Hangup();
Output::renderJSON($speak, $hangup);
?>

Will render:

[{"name":"Speak","phrase":"Hello world!"},{"name":"Hangup"}]

Required properties are included in the constructor for each class - in most IDE’s this means that you can simply use Shift + Control + Space Bar when you create a new instance of the object to see what properties are required.

Optional properties on all classes are handled by using the PHP __set() method in the base class. This effectively let’s you overload the object and set properties which are not declared in the class definition. So for example, if we wanted to collect input from the caller (e.g., their zip code) we would use the GetDigits class, and overload it to add a URL to post the results to:


< ?php

// First argument passed into the constructor sets # of digits to collect.
// Second argument sets the timeout.
$getDigits = new GetDigits(1,5);

// Now we overload the object to add a URL to post the results to.
$getDigits->url = “http://somehost.com/myscript.php”;

?>

The problem with overloading in PHP is that you don’t get the benefit of having your IDE display overload options (it can’t because the properties that we wish to set are not declared in the class definition). There also isn’t any way to control what overloaded properties get set, so its possible to add things the Cloudvox won’t understand.

I’m not sure there is any way around this given the way that PHP has implemented overloading. I do plan to work on a set of Cloudvox classes using another language that handles overloading a bit better, like C#, but for now you should only overload to set the url and method properites for classes that can use them (see the Cloudvox docs for more details).

Sipping on some Limonade

If you know of the excellent Ruby Framework Sinatra but you want to code your project in PHP, fear not - check out the equally excellent PHP framework called Limonade. It’s the functional equivalent of Sinatra for PHP.

Using Limonade with our set of Cloudvox JSON classes makes building cloud telephony applications very simple. The biggest benefit is that you don’t have to split up the different steps in your application (i.e., collecting input, validating input, re prompting, etc.) into different PHP files (which can be kind of a pain) - all of your steps can be contained within a single file.

Limonade lets you set a URL “route” that Cloudvox can send HTTP requests to with results, and to get rendered JSON for another application step. For example:


< ?php

dispatch_get('/start', 'cloudvox_start');
function cloudvox_start() {

$speak = new Speak("Hello world!");
$hangup = new Hangup();
Output::renderJSON($speak, $hangup);

}

?>

This “Hello World” example - defined in a script named sample.php - could be accessed by hitting http://somehost.com/index.php?/start. To make things easier, we’ll use a little Apache magic to allow URL rewriting:

This will let us access the above URL by hitting http://somehost.com/index.php/start.

A simple demo app using the Cloudvox JSON helper classes and the Limonade Framework can be seen below. You can use this sample application with a new Cloudvox account to get started building cloud telephony applications.

This simple app demonstrates how powerful the Cloudvox JSON API is for creating cloud telephony apps. When coupled with an elegant framework like Limonade, sophisticated, cloud-based telephony applications are readily available to any developer that wants to build one.

The helper classes for the Cloudvox API are obviously a work in progress, so if anyone reading this has comments or suggestions feel free to let me know - mheadd [at] voiceingov.org.

12th
JAN

NoSQL Telephony with Tropo and CouchDB

Posted by Mark Headd under CouchDB, Development Tools, Open Government, Tutorials

In the last two posts, I’ve provided a basic overview of how to create cloud telephony applications using the Tropo platform and CouchDB.

Apache CouchDB Logo

In the first post of this series, I walked through a quick install of CouchDB and provided information on getting a Tropo account set up. In the second post, we created a simple auto attendant Tropo script in PHP that populates a CouchDB database with a call record for each inbound call that is transferred.

I’ll conclude the series with information on how to retrieve information from a CouchDB instance for use in a cloud telephony application, and talk about design documents. This post will also introduce the reader to the concepts of CouchDB Views and Show Functions - powerful tools that can be harnessed to create truly cutting edge cloud phone apps.

First, let’s create a CouchDB database to hold our call settings.

Creating a Call Settings Database

As mentioned in the previous CouchDB posts, you can create a new call settings database using curl from the command line, or using the Futon GUI.

$ curl -X PUT http://your_new_couchdb_ip:5984/call_settings

You should see a response from CouchDB like this:

{”ok”:true}

You can add a record to the call settings database the same way. This time, however, we’ll append the URL for our CouchDB database with a document ID, in this case ‘1000′ - this is the extension that a caller to our cloud telephony app will dial. We’ll use the document ID and and the CouchDB REST API to get all of the settings we’ll need to conduct the transfer - these settings can be seen in the document structure below (feel free to add others to meet your needs or preferences).

$ curl -X PUT http://your_new_couchdb_ip:5984/call_settings/1000 -d ‘{”first_name”:”Joe”,”last_name”:”Blow”,”phone”:”17777777777″,”title”:”Master of Disaster”,”ring_tone”:”audio/ring.wav”}’

You should see a response from CouchDB like this:

{”ok”:true,”id”:”1000″,”rev”:”1-0cf5a7c3a70ac5760f1a5d8dcb8b48d2″}

Let’s add a few more documents to our call settings database (replacing the telephone numbers below with real ones that you want callers to transfer to) and then view all of the documents that we have created.

$ curl -X PUT http://your_new_couchdb_ip:5984/call_settings/2000 -d ‘{”first_name”:”Harry”,”last_name”:”Smith”,”phone”:”18888888888″,”title”:”President of the World”,”ring_tone”:”audio/ring.wav”}’

$ curl -X PUT http://your_new_couchdb_ip:5984/call_settings/3000 -d ‘{”first_name”:”Martin”,”last_name”:”Scorsese”,”phone”:”19999999999″,”title”:”The Departed”,”ring_tone”:”audio/ring.wav”}’

You can view all of the documents in a CouchDB database using the HTTP GET method:

$ curl -X GET http://your_new_couchdb_ip:5984/call_settings/_all_docs

You should see a response from CouchDB like this:

{”total_rows”:3,”offset”:0,”rows”:[
{"id":"1000","key":"1000","value":{"rev":"1-0cf5a7c3a70ac5760f1a5d8dcb8b48d2"}},
{"id":"2000","key":"2000","value":{"rev":"1-ee2f09516df8b191a89791b01828d788"}},
{"id":"3000","key":"3000","value":{"rev":"1-a1399e8218ae75e1efb73ba3f87862ff"}}
]}

Now we need to modify our Tropo PHP script to retrieve the settings we want to use with each transferred call.

Note, for now we’ll keep the logic simple - if a caller enters an extension that does not exist we’ll get a specific HTTP response back from CouchDB - something in the 400 class of responses. If this happens, we’ll just end the call - in the real world you’d want to do something a little more friendly, but you can sort that out when you build your own cloud telephony application. ;-)

Modifying the Tropo Script

So, our new Tropo script looks like this:

Note that the getPhoneNumberByExtension() method no longer returns a hard coded phone number - it is using the 4-digit extension entered by the caller to access our CouchDB database using the REST API. The response from CouchDB is a document in JSON format, that we can easily parse using PHP’s handy json_decode() function.

I’ve also modified the value of the $callLog variable to correctly capture some of the variables exposed in the Tropo environment (i.e., the session ID of the call, and the caller ID - see this thread for more information).

So now we have a working cloud telephony application built on Tropo that uses CouchDB to get its call settings, and also to write a call record for billing, reconciliation, etc.

As cool as this is, there is still a lot more we can do with CouchDB in our cloud telephony apps. Note the constants declared at the top of the Tropo script - the last two are blank; one for a design document name, and one for a show function.

define(”COUCH_DB_DESIGN_DOCUMENT_NAME”, “”);
define(”COUCH_DB_SHOW_FUNCTION_NAME”, “”);

Let’s talk about those concepts now, and explore how they could be used in a cloud telephony application.

Getting more out of CouchDB - Design Documents, Map/Reduce and Show Functions

As the title of this post suggests, we’re building cloud-based phone applications without SQL. CouchDB doesn’t use SQL - instead it uses a Map/Recuce framework to index documents in a database.

Map functions can be used to emit a key-value listing of documents in a CouchDB database. Reduce functions are used to aggregate the key-value pairs emitted by a Map function. Map/Reduce functions (or Views) live inside of a special document in a CouchDB database called a “design document“, which has a document ID prefixed with “_design/”.

For example, suppose we have a special design document in our database called “_design/extensions” with a View called “getExtensions” - our View is made up of a Map function and (optionally) a Reduce function. Let’s assume our View has only a Map function to return data on extensions with valid phone numbers to transfer a caller to.

function(doc) {
  if(doc.phone.length == 11 && doc.phone.substr(0,1) == ‘1′) {
    emit(doc._id, doc.phone);
  }
}

Our Map function (which is written in JavaScript, and stored in our design document) has one parameter - doc. This function is called for each document in our database, and the doc parameter represents the document itself. As can be seen, we simply examine each document in the database to see if it has a valid phone number (11 digits, starting with 1).

Views are accessed using a specific URI structure (do note, however, that the REST API for querying Views can change significantly between CouchDB versions), and the response is a set of key-value pairs formatted as JSON.

http://{server_ip_address}:5984/{database_name}/_design/{design_document_id}/_view/{view_name}

$ curl -X GET http://your_new_couchdb_ip:5984/call_settings/_design/extensions/_view/getExtensions

You should see a response from CouchDB like this:

{”total_rows”:3,”offset”:0,”rows”:[
{"id":"1000","key":"1000","value":"17777777777"},
{"id":"2000","key":"2000","value":"18888888888"},
{"id":"3000","key":"3000","value":"19999999999"}
]}

You can check to see if your Map function is working properly by adding a document with an invalid phone number.

$ curl -X PUT http://your_new_couchdb_ip:5984/call_settings/4000 -d ‘{”first_name”:”Richard”,”last_name”:”Kimble”,”phone”:”4444444″,”title”:”The Fugitive”,”ring_tone”:”audio/ring.wav”}’

Accessing the getExtensions view will return the same results as before, as the phone number for the new document does not pass validation. Using design documents and Views, cloud telephony developers can use CouchDB to build grammars for user input which will significantly enhance the usability of the sample application we’ve used during the last few posts.

But there is even more potential with another piece of functionality in CouchDB - show functions. Show function also live in design documents, alongside Views. Show functions allow a developer to return specifically formatted content from a CouchDB instance, not just data in JSON format.

A basic show function that can be used to return information from our CouchDB database in the format of a SRGS grammar might look like this.

function(doc, req) {
 var grammer = ‘<?xml version=\”1.0\”?><grammar xmlns=\”http://www.w3.org/2001/06/grammar\”>’;
 grammar += ‘<rule id=\”R_1\”><one-of>’;
 grammar += ‘<item>’ + doc.phone + ‘<\item>’;
 grammar += ‘</one-of></rule></grammar>’;
 return grammar;
}

Like Views, Show Functions are accessed using a specific URI structure.

http://{server_ip_address}:5984/{database_name}/_design/{design_document_id}/_show/{show_function_name}/{document_id}

Note that the Show function above is different from the Map function discussed earlier in that it takes two parameters - doc and req. As before, the doc parameter represents the document the function is called against. The req parameter represents a parameter that is sent in with the HTTP request, which can be used inside the function to render output. So a Show function canbe accessed using the above URL with an optional parameter as well, like so.

http://{server_ip_address}:5984/{database_name}/_design/{design_document_id}/_show/{show_function_name}/{document_id}?{parameter}={some_value}

Conclusion

I hope this series of posts has provided a helpful overview of CouchDB, with an emphasis on how it can be used to build cloud telephony applications.

Cloud telephony platforms like Tropo, CloudVox, CallFire and others provide enormous flexibility to developers in building and deploying sophisticated cloud telephony applications.

Pair these tools with CouchDB and you’ve got a powerful combination for building full featured, easy to maintain cloud-based phone apps.

6th
JAN

Relaxing on the Couch with Tropo and CouchDB

Posted by Mark Headd under CouchDB, Development Tools, Open Source, Tutorials

This is the continuation of a series that will describe how to build voice applications with the Tropo cloud telephony platform and CouchDB.
Apache CouchDB Logo
In the last post, I detailed how to get a CouchDB instance up and running on Ubuntu, and how to get an account started on Tropo so that you can start building cloud telephony applications. In this post, we’ll create our first CouchDB database and create a simple Tropo application that connects to our CouchDB instance. First, however, we need to tweak the default settings for CouchDB so that we can access our CouchDB instance from the an external environment.

Configuring CouchDB

Recall from the last post that the configuration files for CouchDB are located in /usr/local/etc/couchdb/. Open the local configuration file and take a look at the default settings:

$ sudo vim /usr/local/etc/couchdb/local.ini

In the [httpd] section, you’ll notice the setting for the default port that is used to connect to CouchDB - 5984. You’ll also note the bind_address setting. By default, CouchDB listens only on localhost – you can change this by altering the value of bind_address to a publicly resolvable IP address (you may need to uncomment this setting as well).

However, before proceeding please note that CouchDB does not yet have a built in security model, so anyone that can access the IP address in the configuration file can potentially access your CouchDB instance. We’ll need to take some steps to restrict access to our CouchDB instance – there are several ways of doing this.

First, if you know the IP address (or range of addresses) that will be accessing your CouchDB instances, you can simply use IPTables to restrict access to that IP:

$ iptables -A INPUT -p tcp -s 64.57.102.34 –dport 5984 -j ACCEPT

The above command would restrict access to your CouchDB instance to a single IP address.

Another method for securing a publicly exposed CouchDB instance is to use Apache password authentication. A good overview of this approach can be found here.

After you’ve modified the bind_address setting, restart CouchDB and test connectivity to it:

$ sudo /usr/local/etc/init.d/couchdb restart
$ curl http://your_new_couchdb_ip:5984

Creating our CouchDB Database

Once you have your CouchDB instance up and running, you can create a database in one of two ways. The first, and easiest, is simply to use the curl command. You create a database in CouchDB by using the HTTP PUT method:

$curl -X PUT http://your_new_couchdb_ip:5984/call_logs

You can also create a database (and do lots of management functions in CouchDB) by using the GUI (called Futon). Its located at http://your_new_couchdb_ip:5984/_utils

Building a Simple Auto Attendant Application with Tropo

Now that we have an initial database in our CouchDB instance, lets build a simple Tropo application that will populate it with records (or documents in CouchDB parlance):

This simple application is a basic auto attendant. It asks the caller for a 4-digit extension and then transfers them to a 10-digit PSTN number. At the end of the call, we write a very simple call log document to our new call_logs database using the HTTP POST method.

(One small side note – you can use either the POST or PUT methods to insert a document into a CouchDB database. However, using PUT assumes you want to assign a specific document ID to your document. When you use HTTP POST, CouchDB will automatically assign a document ID. For now, we’ll keep things simple and use POST.)

Much of the functionality in this simple app is just stubbed out for now - i.e., the getPhoneNumberByExtension() method - we’ll build more of this out in later posts.

Modify this file by adding your instance-specifc details to the constant declarations at the top. Do also note that the last two constants can remain blank for now.


define("COUCH_DB_DESIGN_DOCUMENT_NAME", "");
define("COUCH_DB_SHOW_FUNCTION_NAME", "");

We’ll talk about how to use design documents in the next post.

When you load this file up on Tropo and make a test call, you will see your call log document is inserted into the call_logs database. The structure of the document is pure JSON, which is supported quite nicely in PHP (and most every other language that can run on Tropo as well).

In the next post, we’ll examine CouchDB design documents in more detail and modify our simple demo application to get a list of extensions from another CouchDB database and parse the JSON data structure in the getPhoneNumberByExtension() method.

Until then, keep on relaxing….

4th
JAN

Building Voice Applications with Tropo and CouchDB

Posted by Mark Headd under CouchDB, Development Tools, Open Source, Tutorials

The beginning of a new decade is usually the time when there is a lot of reflection on what has changed for the better (and the worse) over the past 10 years.
Voxeo Tropo Logo

The end of 2009 saw its fair share of pundits talking about how far we’ve come since the year 2000, but for me the most dramatic change has been to the way that voice applications are developed and deployed. In the past 10 years (hell, in the past 10 months!) we’ve seen a dramatic shift toward cloud telephony with the launch of a number of new services that have fundamentally altered how voice applications can be built.

There has simply never been a more varied and powerful array of tools available for developers to build phone applications with than exists today. Some of the newest and most innovative platforms around for building cloud-based phone applications are listed below:

Over the same period of time there’s also been lots of changes to some of the foundational technologies supporting voice applications (and other kinds of web applications). The NoSQL movement is gaining steam, and there is an interesting collection of new document-oriented databases available for developers to use. One of my favorite is Apache CouchDB.

Apache CouchDB Logo

The thing I find really interesting about CouchDB is that it makes use of an HTTP-based API - pretty much any tool or technology that can communicate via HTTP can be used to interact with a CouchDB instance (hello command line…). In addition, that data structure of the documents stored in a CouchDB instance is JSON. In my mind, this makes CouchDB a very useful choice when building cloud applications, specifically cloud telephony applications.

Who wants to use one of those old relational databases to build a cutting edge cloud phone app? That’s so 2009.

This post and the next several that follow it will detail how to set up a CouchDB instance and to build a cloud telephony application with it using the Voxeo Tropo platform.

For those that don’t know, Tropo is one of the new cloud telephony platforms that lets developers author voice apps quickly and easily using one of several different languages. It’s open source, well documented and supported by Voxeo’s industry leading telephony infrastructure.

So, if you want to start the new decade of right by learning how to build powerful, scalable, full featured voice applications using Tropo and CouchDB, read on.

Getting Started with Tropo

Head on over to Tropo.com and set up a new account (if you don’t have one already). Take a little time to review the documentation for Tropo - I’d recommend running through a few of the sample apps if you have time. They’re fairly self explanatory and provide a solid overview of the different languages that can be used to write a Tropo app - I’ll be using PHP for the example application in this series of blog posts, but you can use any language that Tropo supports.

Deploying and testing an application on Tropo is a snap, and you can even deploy a PSTN number for your application (or you can use the Skype calling number automatically provisioned when you create a Tropo app). More on this in the next post.

Installing CouchDB

The next step in building our cloud telephony application for the new decade is getting CouchDB up and running. The steps listed below detail how to install CouchDB 0.9 on Ubuntu 8.04 (the long-term support version of Ubuntu). A few points before we get started…

This specific combination of Ubuntu and CouchDB is my own preference. I typically run Ubuntu 8.04 when I deploy a new virtual server, but you are free to run whatever version you like, or another Linux distro entirely - its up to you. Depending on the version of Ubuntu you are running, you may be able to get CouchDB 0.9 installed by simply doing sudo apt-get install couchdb.

Keep in mind, though, that the HTTP API for CouchDB can change dramatically between versions - I’ve noticed some significant changes when going from 0.8 to 0.9 - the discussion here will focus on version 0.9 (as does a lot of good documentation on CouchDB available on the web).

If you don’t want to install CouchDB yourself, you may be able to take advantage of one of the growing number of CouchDB hosting services like CloudAnt or Couch.io. Again, its up to you.

To install CouchDB 0.9 on Ubuntu 8.04, using the following steps.

Step 1. Determine what version of Ubuntu is running on your machine:

$ cat /etc/lsb-release

Step 2. Install Erlang - CouchDB 0.9 requires at least Erlang version 5.5.5. If you are running Ubuntu 8.10 or above, you can probably get the required Erlang version by simply doing sudo apt-get install erlang. (Note - The last step in this section may take a while, feel free to go grab a cup of Joe while the source compiles.)

$ sudo apt-get build-dep erlang
$ sudo apt-get install java-gcj-compat java-gcj-compat-dev
$ wget http://www.erlang.org/download/otp_src_R12B-5.tar.gz
$ tar -zxvf otp_src_R12B-5.tar.gz
$ cd otp_src_R12B-5/
$ ./configure && make && sudo make install

Step 3. Install CouchDB dependencies:

$ sudo apt-get install libmozjs-dev libicu-dev libcurl4-openssl-dev

Step 4. Download CouchDB 0.9 Source and install:

$ wget http://apache.mirrors.redwire.net/couchdb/0.9.0/apache-couchdb-0.9.0.tar.gz
$ tar -zxvf apache-couchdb-0.9.0.tar.gz
$ cd apache-couchdb-0.9.0/
$ ./configure && make && sudo make install

Step 5. Create a user for CouchDB (More on this in the CouchDB README.txt file):

$ sudo adduser – –system – –home /usr/local/var/lib/couchdb – –no-create-home – –shell /bin/bash – –group – –gecos “CouchDB Administrator” couchdb
$ sudo chown -R couchdb /usr/local/etc/couchdb
$ sudo chown -R couchdb /usr/local/var/lib/couchdb
$ sudo chown -R couchdb /usr/local/var/log/couchdb

Step 6. Start CouchDB

$ sudo /usr/local/etc/init.d/couchdb start

If you see an error that says:

“Apache CouchDB needs write permission on the PID file: /usr/local/var/run/couchdb.pid”

Do the following, then try starting CouchDB again:

$ sudo touch /usr/local/var/run/couchdb.pid
$ sudo chown couchdb:couchdb /usr/local/var/run/couchdb.pid

When CouchDB starts successfully, you will see a message that says:

* Starting database server couchdb     [ OK ]

Step 7. Test connectivity to CouchDB:

$ curl http://127.0.0.1:5984

You should see:

{”couchdb”:”Welcome”,”version”:”0.9.0″}

The configuration file for CouchDB is located at /usr/local/etc/couchdb/local.ini — in the next post, we’ll modify some of the config settings for our CouchDB instance so that we can access it via HTTP from the Tropo environment.

We’ll also set up our first CouchDB database, add some documents and start coding our new cloud telephony application using Tropo.

Stay tuned…

5th
DEC

User Agent Sniffing for Multi-Channel Apps

Posted by Mark Headd under Development Tools, Tutorials

Several months ago, voice platform company Voxeo announced an exciting addition to its industry leading VoiceXML platform - the ability to repurpose existing VoiceXML applications and turn them into instant messaging (IM) applications and text messaging (SMS) applications.

And while I’ve had several opportunities to expound on the importance of this announcement, I have not yet had time to use a practical example to demonstrate just how powerful the new functionality Voxeo is now offering can be.

How big a deal is this really?

To be honest, when I first read about Voxeo’s new offering, I didn’t think it was a big deal. I thought it was a freaking huge deal - I’m talking Godzilla, baby. This is big!

Lots of people are wary of proprietary extensions to open standards like VoiceXML because they can make your code less portable (if you find you need to transition from one vendor to another). But unlike other platform-specific extensions to VoiceXML, Voxeo’s new feature doesn’t make you write VoiceXML in a way that violates the standard, it changes the way that the platform consumes VoiceXML.

The example that I will demonstrate below is written in 100% standard-compliant VoiceXML. It can be run on any VoiceXML platform that adheres to the VoiceXML spec, and probably a bunch that don’t.

That’s why this announcement from Voxeo is a game changer for developers - it provides sophisticated and powerful new functionality without the burden of having to alter your code in a way that makes it less portable. In addition, it allows developer to create sophisticated applications that can be delivered to users via IM and SMS using all the familiar tools of VoiceXML.

All of the benefits of working with VoiceXML are available for developers that want to write SMS and IM apps — grammars, the FIA, the standard root-leaf structure of VoiceXML applications — its all there.

The nose knows

While it might be tempting to think that any existing VoiceXML application can be repurposed with no changes for IM and/or SMS, this is probably not true except for the most simplistic of apps. Just as there are certain types of interactions that may make sense for use with visual web applications and not with voice apps, there are certain types of dialog flows that work well in voice apps but don’t necessarily translate well to the world of IM and SMS.

Consider the following:

  • Phone applications often employ a confirmation dialog, to prompt a caller to verify what they have just entered - particularly if the information is important or sensitive (e.g., a credit card number, or account number). This probably not a good practice with SMS or IM apps because, unlike with a phone application, a user can see what information they are about to submit before the actually send it. Also, since multiple text messages can mean increased changes for a user its a good idea to cut down on this where possible.
  • DTMF-based phone applications often use prompts like “Press 1 to repeat, press 2 to go to the previous menu…” The notion of “pressing” something is really tied to the telephone key pad and is probably not appropriate for SMS or IM applications. Its much clearer to use prompts like “Enter 1 to go to the next option”, or “Send #back to go to the previous step”.
  • Re-prompting a user on noinput is a pretty standard practice in phone applications, but is probably not a good idea in IM or SMS apps. If a person is using their cell phone to interact with an SMS application, and then gets a call, they probably do not want to be repeatedly prompted for input by your app that they will not have an opportunity to enter until after their call has finished.

So if all of this is true, then how does a developer determine how an application is being accessed? It seems pretty clear that there needs to be a way to determine if an application is being called from a phone, from an SMS cell phone or from an IM client.

Turns out, there is - good old fashioned browser sniffing.

A simple example

The Voxeo blog has a good overview of this new feature, and how you can set up and run a VoiceXML application that is also IM and SMS enabled.

One of things that is really nice about this new feature of the Voxeo Prophecy platform is that the text that is sent to a user via SMS or IM, and all of the inputs sent back from the user, follow the same logic rules as with a phone interaction. This means that if there are VoiceXML elements with conditional attributes on them, they get evaluated when rendering text for SMS and IM, just like they do for the telephone.

Another really nice feature is that Voxeo lets you deploy a single number for SMS and traditional phone access to your application. So if you dial a provisioned number on your telephone, the traditional VoiceXML browser engages and executes your code in the typical fashion. If you send an SMS message to the number, the new Prophecy 10 browser engages your code and manages the SMS interaction.

Because of this, its fairly straightforward to detect which browser is accessing your code, and create a simple variable declaration that will govern how your output is rendered.

The following is a simple PHP class that can be used to sniff the browser type requesting a specific file.

To use this class, we simply include it in our PHP page that will render VoiceXML, determine what kind of user agent is requesting the page by calling getChannelType() and set a VoiceXML variable accordingly.

If an SMS or IM client is interacting with our application, the Prophecy 10 browser will make the request. If its a standard telephone, it will be the Prophecy 8 browser, so we really just need to use the value of $_SERVER['HTTP_USER_AGENT'] to guide our app.

You’ll notice that if an SMS or IM client is accessing our app, we skip the confirmation field. We’ve also customized the reprompt logic on noinput to ensure that a user does not get successive SMS or IM messages telling them “Sorry, I did not get your response.”

So with a few lines of server side code, we’ve custom tailored our VoiceXML dialog to ensure that it renders properly regardless of the type of user agent accessing it.

Voxeo Prophecy’s new features are powerful, and VoiceXML developers should take notice. With Prophecy, they can leverage their skills and become crackerjack SMS and IM app developers as well.

28th
MAY

Talk to the BOT

Posted by Mark Headd under Development Tools, Tutorials

With governments under enormous budgetary pressure, finding ways to provide service at lower cost is more important than ever. The term “‘automated self-service” usually conjures up thoughts of web applications or interactive voice response (IVR) systems, but there are other ways that governments (and other organizations) can enable citizens and customers to self serve.

One intriguing new way to enable self service is to deploy instant messaging (IM) applications, sometimes referred to as IM “BOTS”. Personally, I would love to be able to make a park reservation or find out the wait time at the DMV by simply opening up an IM client - perhaps one on my iPhone - and entering a few simple commands.

Writing an IM BOT might usually require some in-depth knowledge of XMPP or specific IM platform requirements, but a simple and effective way of writing an IM BOT that can work with a number of different IM services is to use the IMified Platform.

IMified, which was recently bought by Voxeo, provides a simple and effective API for developing interactive IM BOTS. Essentially, IMified provides a IM front end to a web application that can be used to interact with back end databases, web services, etc. Communication between your web application and the IMified platform is in HTTP, so any web programming language can be used to write an IM BOT. (This architectural set up is very similar to the services provided by Voxeo’s hosted offering - they provide a front end to the PSTN and allow you to write telephone applications in a variety of traditional web programming languages.)

When a user interacts with your IM BOT, the IMified platform will make an HTTP request (using the POST method) to your web application and allow you to write out information in the response. A quick read of their API documentation will get you started on your first BOT. There is also a very nice debugger tool provided by IMified that allows developers to interact with their application and get access to the name/value pairs sent in each successive HTTP request - a very handy tool indeed!

Having said all of that, you might be trying to reconcile the notion of using HTTP with an interactive BOT. Self service usually requiers some sort of state management, and HTTP is stateless. IMified provides a nifty mechanism for managing state during your interaction with a user of your BOT. Among the name/value pairs sent to your web application with each request from the IMified platform are the following:

userkey: a unique token generated by IMified when presence is established with an IM user sending a message to your bot. This userkey uniquely identifies a user of your bot and can be used for instance, to associate the IM user with a user in your system.

value1 - valuex are the values entered by the IM user for each respective step in the interaction. So a user that has entered text multiple times might generate a request with - value0=hello, value1=My name is Joe, valueX=Nice BOT you have there, etc.

So, as your user (identifiable via userkey) interacts with your BOT, the list of values is increased, with a new name/value pair being added for each turn. This makes it easy to collect information, and even to verify new input based on previous responses.

After playing around with IMified, I decided that I wanted to write a sample app that used a small PHP class to make managing the information provided in each HTTP request more manageable. The code for the IMified class is as follows:

A simple example BOT demonstrates the power of this class, and how easy it is to create your own IM BOT on the IMified platform:

< ?php

/*
 *  This is an example script demonstrating the functionality of the IMified class
 */

require('class.imified.php');

try {

  $testBotMessage = new imified($_POST);
  $step = $testBotMessage->getStep();

  echo "Hello. Your IM network is: ". $testBotMessage->getNetwork().".";
  echo "This is step ".$step.".";
  if($step > 1)
    echo "In the last step, you said ".$testBotMessage->getLastValue().".";

}

catch (Exception $ex) {
  echo "Sorry. The Bot is having some issues: ".$ex->getMessage();
}

?>

In the above example, we create a new instance of the IMified class and pass the $_POST superglobal array into its constructor. This will automatically assign all of the data in the HTTP request to the object’s properties and, as in the case of the step value, cast to the proper type:

...
$this->step = (int) $postValues['step'];
...

What I really like about this class is that it takes any user interaction values submitted with the request and packages them up neatly into an array - this array is assigned to one of the class properties, and there are several accessor methods that let you work with responses submitted by the BOT user. You can see this demo BOT in action by adding voiceingovtest@bot.im to your Jabber/XMPP client contacts and sending it a message (note - you can use the Google Talk client for this).

Governments interested in creating new service delivery channels that can lower costs and increase customer satisfaction should take a close look at IM BOTS in general, and the powerful combination of Voxeo/IMified in particular.

I hope to expand on the simple example shown here and further build out the IMified class to demonstrate the power of interactive IM BOTS to improve government service delivery.

Stay tuned!