Building Cloud Communication Apps with Tropo: Part 4

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.


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!


Building Cloud Communication Apps with Tropo: Part 3

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:

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) {

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

        // 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", "");

// 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.

	// 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…

Building Cloud Communication Apps with Tropo: Part 2

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 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.

// Include Limonade framework (

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!

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" => "", "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…

Tropo Goes Global

A couple of months back, I wrote a post about how nontraditional communication channels – IM, SMS, social networks, etc. – are changing the way that businesses and governments interact with their customers. These channels are “nontraditional” because they are not typically utilized to provide customer service, or to take orders.

That is changing, and the announcement today from Voxeo about their new Tropo service is both evidence of that change, and the catalyst for even more change.

Voxeo Tropo Logo

I’ve always been impressed with Tropo, and not long ago I worked on a series of posts demonstrating how to utilize the Tropo platform with the utterly awesome NoSQL database CouchDB.

The newly reworked Tropo adds an impressive array of new features. It’s not all that unusual any more to see cloud telephony services offering SMS support – it makes sense, and its right in line with what I have been saying about how nontraditional communications channels are becoming more important. Tropo goes way beyond this by adding support for an array of IM networks and also for Twitter (the 800 lb gorilla of nontraditional communication channels).

The international support for Tropo is also impressive – they provide international numbers for inbound calls, and can also handle outbound dialing to international numbers. Phone applications can use international TTS engines to render content to non-English users. Even more impressive, Tropo’s speech recognition capabilities (which have always separated it from other cloud telephony providers) can now support a number of foreign languages – UK English, Dutch, French, German, Italian, Mexican Spanish or Castilian Spanish.

Tropo is an impressive platform for a number of reasons. It used to be very hard (and, in some respects, still is) to build a great phone application. The Tropo platform allows developers to build great phone applications, and to leverage the investment in these apps by extending them to other channels and other countries.

A single code base serving different customers on multiple channels. That’s powerful.

And now, with the release of the new Tropo service, a single code base can serve multiple channels in multiple countries in multiple languages.

The times they are indeed a-changin’.

Next Steps in the Evolution of Multimodal Applications

Over at eComm Europe – being held in Amsterdam – RJ Auburn gave a rocking presentation that can be summed up by its very apt title – the “Rise of Real Time Text and the Demise of Voice.”

There are many important take aways in this presentation for governments and any other organization that interfaces with customers (yes, taxpayers and citizens are customers). Most importantly, the increased use and growing ubiquity of alternate communications channels – IM, SMS, social networks, etc.

Stated simply, the customers of tomorrow will communicate differently than the customers of today. The customers of today are used to voice self service (although many grudgingly so). The customers of tomorrow will use new communications channels (perhaps some that do not yet exist). Your father’s customer service paradigm will probably not apply to them.

Bottom line, if you haven’t developed methods for communicating with the new wave of customers that use different modes of communication then your shiznit will be cooked. Ya dig?


Voxeo (the company for which RJ is CTO) has been on a buying spree of late, with the seeming goal of shoring up its offerings to cover a wide array of different communication modalities. I’ve expounded in the past on one acquisition in particular as being especially relevant – particularly as it relates to the next generation of customers – the acquisition of IMified.

IMified provides a simple API that allows developers to create applications that work across a host of IM networks, SMS and even Twitter. Voxeo has leveraged this acquisition to deploy new functionality on its core voice application platform to allow developers to deploy multimodal applications – apps that a user can interact with through several different modalities, whichever is most convenient for them.

Multimodal applications are not new – I’ve written about them many times and built several. But Voxeo and IMified have taken the notion of multimodality to a new level by making it practical for almost any developer to build one. Even more compelling, Voxeo’s platform lets you re-purpose applications developed for one specific modality (i.e., phone) for others (SMS, or IM).

Multimodal functionality is pretty much a requirement these days for successful customer interactions, but RJ’s presentation got me thinking about other possibilities.

Cascading Modality

The next step in the evolution of multimodal applications will be to support what I call “cascading modality.” Cascading applications will allow users to move across modalities over the course of one interaction with a company or a government.

For example, say a company wants to start a customer off in a communications channel that has relatively low cost – IM – using an application to collect basic customer information at the start of an interaction. At some point during this IM session, the customer could opt to move to a different modality. Say they send the following to the IM bot:

#switch 6401254789

This could generate an outbound call to (640) 125-4789 so that the caller could interact with an IVR system to complete their interaction – say, if they began the IM session on their desktop computer at the office and completed it while walking to the parking garage to get in their car. The information entered during the initial IM session is persisted across the switch to the IVR call, and all of the information (from both modes) is captured in a fulfillment or CRM system.

This session could be followed up by using a third modality – perhaps a confirmation message or receipt that is sent via SMS or even e-mail.

Concurrent Modality

Now consider another scenario, perhaps one that involves an older user who may be less comfortable with IM. This person could send the following to an IM bot:

  • User: #assist
  • IM Bot: I’d like to call you, and provide some additional assistance over the phone. Enter your 10-digit phone number.
  • User: 6401254789
  • IM Bot: Thank you. Hold one second while your call is placed.

As in the previous scenario, this would generate an outbound call to (640) 125-4789 but the focus of the IVR would not be to collect information – you still want the user to enter the information into the IM client they are using. The focus here would be to use the IVR to provide supportive information, so that the caller can more easily or efficiently enter required information.

One example of this “tag team” approach would be to simplify the input of information that needs to be in a particular format:

  • IVR App says: Enter your account number, which is a three part number separated by dashes. Enter all leading zeros on the left hand side of your account number.
  • IM Bot displays: Example: 00012345-87-1
  • User enters: 00078945-44-9

By using two modalities simultaneously to interact with the user, the information can be collected in less steps – a typical IVR system would probably collect this type of an account number in three separate steps, and could be prone to error (“to the left of the first dash, or the second..?”).

In this scenario, if a user enters 0 on their phone or sends #help via IM, they could automatically be routed to an agent for assistance.

Building Next Generation Multimodal Apps

Companies like Voxeo have removed a lot of the complexity from building multimodal applications, but developers will need to take heed of several factors that will become important as these kinds of applications become more widespread.

State persistence. Cascading modality will only work if a user can switch seamlessly from one mode to another without repeating data entry. VoiceXML applications and IM bots typically communicate with a backend via HTTP, which is stateless. And while there any number of different ways to maintain state in an HTTP-based application, they do not always scale well. Things can get complicated when clusters of servers or load balancers are required. These considerations require specialized skills to address properly.

Secure data transfer. A profusion of multimodal applications can raise questions about data security, particularity if said data is transmitted across pubic IM and social networks. Developers need to think clearly about what is suitable for transmission across these networks, and ways that data security can be enhanced where needed.

Yes, the dawn of a new customer service era is upon us my friends. Who knows, if you tool on over to the Voxeo or IMified developer sites, you might just get an opportunity to help build it.

Odd Tweet of the Day Award

Although it seems a bit early to be handing out an award that could cover the entire day (and it’s only 9:30 AM EST), the Odd Tweet of the Day Award goes to:


I have know idea what this Tweet means, and suspect it was posted in error – perhaps someone at FEMA though they were typing into their IM client.


Automatic for the People

Like lots of others, I think its worth noting San Francisco’s innovative use of Twitter. San Francisco residents can now use Twitter to send a message to an operator at the City’s 311 call center and receive a Tweet back.

This is exactly the type of interactive use of Twitter by governments I had in mind when I wrote about Twitter 2.0 for the public sector a few months ago. Still, now that I see an actual use of Twitter by a government to interact with citizens, I’m wondering if this approach can be improved upon, to make it more efficient for governments and still user friendly for citizens.

While San Francisco’s use of Twitter is indeed convenient for citizens, it has many of the same cost implications for government. Tweets to 311 operators must still be processed “manually” – someone has to read the content of a Tweet (even if its prefiltered based on message content) and assign a follow up action, or respond directly if its been assigned to them. And even though San Francisco is reportedly using the very interesting Twitter-CRM product CoTweet to make this process more efficient, I wonder if there isn’t a better way to do this.

I think this would be a perfect scenario to deploy an interactive IM/SMS BOT. Citizens could interact with an application to report common 311 service requests – potholes, traffic-light outages, abandoned vehicles, etc. As long as certain keywords / hashtags are used in the message content (something that probably needs to be done if Twitter is used instead anyway) it should be pretty easy to process reliably in an automatic way. Moreover, using an IM/SMS BOT would allow the process to have multiple steps, where the application and the citizen could exchange information successively.

For example, a citizen using a BOT to report a traffic signal outage could receive a an automated response asking if there are any noticeable power outages in the vicinity, or telling them to send a follow up message when the repair crew arrives (to audit response times). The possibilities are enormous.

Requests that could not be processed automatically could be routed to a live operator and handled the traditional way. This would more efficiently allocate the finite resource of 311 operators — human operators would only intervene in the processing of 311 service requests when they could not be processed automatically.

Here’s hoping that someday very soon, we’ll see a government go “automatic for the people” with 311 service requests.