….::: VOX POPULI :::….
“Ministers… cannot in any country be uninfluenced by the voice of the people.”
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.

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.

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…
19th
MAY
Building an Open311 Application
Posted by Mark Headd under Cell Phones, CouchDB, Development Tools, Open Government, Twitter
Earlier this year, I had an idea to build a Twitter application that would allow a citizen to start a 311 service request with their city.
At the time, there was no way to build such an application as no municipality had yet adopted a 311 API that would support it (although the District of Columbia did have a 311 API in place, it did not - at the time - support the type of application I envisioned).
That changed recently, when San Francisco announced the deployment of their Open311 API. I quickly requested an API key and began trying to turn my idea into reality.
My idea resulted in an application that I soft launched last week. TweetMy311 is now live and can be used in the City/County of San Francisco to report 311 service requests. The project website has a detailed description of how it works, but its very close to my original idea.

More good news on the Open311 front came recently when it was announced that San Francisco and the District of Columbia had come to agreement on a shared Open311 standard. This means that apps built to work with the San Francisco 311 API will also work with the 311 API in Washington DC. I’m working on enabling TweetMy311 for Washington DC now, and hope to have this service live there in a few weeks.
Ultimately, I hope people use my application, that they like it, and that it makes it easier to report an issue to their municipality. I did, however, have some other motives in developing this application that I think are equally important.
Are You Experienced?
Since 311 APIs are rare, and (right now) applications that use 311 APIs are also rare, I think there is value in being able to capture the experience of developing an Open311 application from scratch. This information can provide tremendous value to the governments that deploy 311 APIs (what works, what doesn’t, what can be improved, etc.), and for developers thinking about building an Open311 application.
I hope to use TweetMy311 to provide feedback to governments that deploy 311 APIs (and to those thinking about deploying one) so that they can get a sense of how the experience works from a developer that has used one. At the end of the day the ease of use of an API, the quality of documentation, the ability to test applications in a meaningful way and a number of other factors will determine how many developers decide to take the step and become a “civic coder” by building an Open311 application.
Getting to Open
For me, the use of open source technologies in TweetMy311 was important. This project provided a great opportunities to learn more about a technology that I have become fascinated with of late - CouchDB. TweetMy311 is a NoSQL application that uses CouchDB at its core. It runs on Ubuntu Linux with Apache and was built with the PHP scripting language (I guess that makes it the CLAP stack - CouchDB, Linux, Apache, PHP)
Building with open source technologies was important because I hope to be able to share the code I have developed with interested governments that want to learn how an Open311 application is put together. I also believe it’s important because I think the Open311 initiative can be a great mechanism for encouraging the use of open source technologies.
Leading up to this project, I developed a small PHP library for interacting with the San Francisco Open311 API. I make use of this library in TweetMy311 and any other developer that wants to use it in their project is free to do so. I plan on branching this library soon so that it can work with the new version of the Open311 standard.
Give it a twhirl
So if you live in San Francisco and you want to give TweetMy311 a twhirl, check out the description on the project website. I’d appreciate any feedback - positive or negative - because ultimately I think it will make the project better.
I had a great experience developing TweetMy311, and I learned a lot. I’m looking forward to sharing my experience with interested governments and other developers.
13th
MAY
Cleaning up Graffiti. With Twitter.
Posted by Mark Headd under Open Government, Twitter
Can you use Twitter to clean up graffiti? Or patch potholes? Or report a problem with a sidewalk, sewer covering or trash pickup?
If you live in San Francisco, the answer is yes.
This yes answer will soon apply to the District of Columbia as well, and any other city that adopts the Open311 standard. Stay tuned for more good stuff!
25th
MAR
Tropo Goes Global
Posted by Mark Headd under CouchDB, Development Tools, Twitter, VoIP
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.

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’.
2nd
FEB
A Governor Tweets: Propaganda or Engagement?
Posted by Mark Headd under Open Government, Twitter
According to the one and only tweet in his account, Delaware Governor Jack Markell will “officially” join the Twitterverse at an upcoming event on February 3rd.
Although I imagine the public relations potential of Governor Markell joining the scores of other federal, state and local officials on Twitter is not lost on his staff, if the Governor is serious about embracing Twitter it could open up a new way for citizens to engage and communicate with him.
So, as the Governor prepares to “activate” his Twitter account, it makes sense for the citizens and taxpayers he serves in Delaware (particularity those of us that tweet) to ask whether this will mean propaganda or engagement.
WonderTwit powers, activate!
The Governor’s first tweet doesn’t bode well (in my mind anyway) for those of us eager to see his new account used to engage citizens and encourage communication with taxpayers.

I find the notion of “launching” a Twitter account that has already been created a bit odd. There is no way that I am aware of to create an “inactive” Twitter account – inactive accounts are those that Twitter considers abandoned.
By virtue of having a Twitter profile, the Governor’s account is indeed active. He could send tweets from it now, and could have sent tweets from it starting on the date it was first activated - June 19th, 2009 - a full 228 days prior to the date of this post.
However, even if the Governor has chosen not to tweet since last June, because his account is active anyone that uses Twitter can send a message directly to him by formatting a Tweet as a @reply (technically referred to as a “@mention” by Twitter).
I did this very thing not too long ago, sending a link I hoped the Governor would read before “officially” joining the Twitterverse.
Still waiting on a response…
Twitter engagement and communication
The @mention feature of Twitter is not one that can be turned off. Everyone has the ability to view tweets that @mention them by simply going to the proper tab on their Twitter home page (its worth noting that any one of the many Twitter clients can make checking, organizing and responding to @mentions quite easy).
It is this feature that has attracted people (like myself) interested in leveraging Twitter as a way to send messages directly to elected officials.
In early 2009, I develop a service called Hear Me Say This which uses IVR technology with Twitter to allow people to send recorded messages to members of Congress. Other people have taken this same approach to send messages directly to elected officials on Twitter using @mentions.
The critical issue for any elected official that uses Twitter is how they will handle tweets that @mention them. They are a potentially useful tool for citizens and activists because they can be sent directly to the official who owns the account (unless that official wants to fess up that someone is ghost tweeting for them). They can also be used to develop support for a cause or issue because friends and followers can retweet status messages (including those that @mention others).
Some elected officials may bank on the fact that responding directly to @mentions from their constituents can be portrayed as being unreasonable burdensome. One can certainly understand why the Governors of California or Michigan (both of whom are prolific tweeters) might be able to get away with not reposing to @mentions (for the record, I don’t know that they do).
However, most Delawareans have different expectations about personal interactions with their elected officials.
Only in Delaware…
Delaware’s small size, concentrated population and cordial political environment come together to create an atmosphere where it is not uncommon to bump into an elected official on the street, or at the gym, or in a store and engage them in a conversation.
Its not uncommon to bump into a Governor, a U.S. Senator or a Member of Congress while out for a jog (I once passed Congressman Mike Castle running at a park near my house), at the gym (I had a nice conversation with Senator Tom Carper between reps at the YMCA about the health care bill several weeks back) or at a gas station (I once stood in line with Joe Biden at a Greenville gas station).
Delaware isn’t a place where elected officials can get away with being insulated from citizens by surrounding themselves with an entourage or a group of handlers. People here aren’t surprised when they run into an elected official at the gas station or the corner store, and I think many expect to be able to interact with them.
So its only logical to ask whether this same type of interaction will work when Governor Markell officially “launches” his Twitter account.
It can work if the Governor decides (as many forward thinking politicians on Twitter already have) that using social networking services like Twitter will provide new opportunities for transparency and citizen contact.
Will the Governor respond to the following when he attends the upcoming Delaware Tweetup on February 3rd:
- Does he intend to use his Twitter account personally (even if he isn’t the exclusive user of the account) as a way to make his administration more open, transparent and receptive to citizen communication?
- Will he commit to responding to Twitter @mentions that appear to be from legitimate Twitter users, or from Delawareans that have an actual question, problem or complaint?
Whether or not Delaware’s somewhat unique brand of political interaction will work when our Governor starts tweeting is entirely up to him, and how he decides to use his newly “activated” Twitter account.
Unfortunately, I won’t be able to attend the event on February 3rd, but I sure would appreciate a response to my tweet.
18th
JAN
Twitter, Facebook, Geotagging and 311
Posted by Mark Headd under Open Government, Twitter
Several weeks back, I wrote a quick post about the new locational functionality being rolled out in Twitter. Now that this new functionality is being supported by more and more Twitter clients, I think its time for an object lesson in how Twitter’s new locational feature (and soon Facebook’s) can be used to engage citizens to submit 311 service requests.
Consider the following Tweet (sent using TweetDeck for iPhone):

Here is the data behind this Tweet in XML format, courtesy of the Twitter API:
Does this Tweet contain enough information to start a 311 Service request (and by “start” I mean via some application logic that automatically parses 311 tweets and requires no human intervention)?
It has a hashtag describing the nature of the request (#pothole), a URL to a picture of the offending pothole (admittedly a pretty wimpy one) and it also has the lat/long of the location where I took the picture. All together, it took me about 15-20 seconds to take the photo, geotag the Tweet and compose the message.
The Twitter API provides some background information on me, in the event that the government handling this kind of a service request wants or needs it. If there was really a need for more, it wouldn’t be all that hard to build a Twitter BOT to interact with the person Tweeting the service request and get any additional information that was required.
One of the primary benefits for governments from deploying a 311 API, or working with companies like CitySourced or SeeClickFix is that it can help engage (and empower) citizens to report service requests. If it’s quick, easy and convenient to report 311 requests, people will do it and they are more likely to be satisfied with the experience (something that doesn’t always happen when citizens interact with government).
The new locational feature of Twitter (and soon of Facebook) will provide governments with a very effective way of empowering citizens to report 311 service requests.
It will be interesting to see how many of the them leverage this as part of their 311 services.
20th
NOV
Command Line GeoTwitter
Posted by Mark Headd under Open Government, Twitter
A few months back I wrote a quick post about tweeting from the command line. With the recent announcement that Twitter’s location feature is starting to go live, I decided to revisit this idea, with an eye toward adding locational information.
(I am, at heart, a cheapskate - I could have bought one of the existing Twitter clients that support locational Tweets but I really just want to play around with this new feature for now. The command line is free, baby!)
Twitter’s API methods now support adding geographic coordinates with a status update. Sending out a GeoTweet using the command line is easy (note, this example assumes you know the lat/long of the location you want to associate with your Tweet).
Open up your favorite editor and drop the following into it:
curl -s -u user:password -d status="$1" -d lat="$2" -d long="$3" \ http://twitter.com/statuses/update.xml > /dev/null
Save the file and make sure it is executable (chmod u+x fileName). You can execute this file at the command line like this:
$ ./fileName "Testing twitter geolocation feature" "+39.754571" "-75.571985"
When you examine the properties of this tweet, you will see that it now has geographic information associated with it:
<geo xmlns:georss="http://www.georss.org/georss">
<georss :point>39.754571 -75.571985</georss>
</geo>
How cool is that!
As more Twitter applications (and the Twitter website itself) roll out support for this new feature, a host of new Gov 2.0 potential is going to be unlocked. I think this will have huge implications for services like 311, where location is critical to service requests.
Municipalities like New York City and San Francisco that have already incorporated Twitter into their 311 service will have a big head start in this regard.
29th
OCT
Next Steps in the Evolution of Multimodal Applications
Posted by Mark Headd under Development Tools, Twitter, VoIP
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.
Friend Connect:
@mheadd Tweets
- @nickgrossman Behind you 100%. Will do everything I can 2 help make it a big success. Just don't want to forget mistakes of the past. #
- @JeffSelf I was with the State of Delaware then. Frustrated that my state didn't make a bigger commitment, and that GOCC fizzled out. #
- Excited for Civic Commons. But there are lessons to learn from past efforts that have not worked. http://bit.ly/brK2P5 #civcoms #gov20 #g2s #
- RT @jefferyrlsmith: Such an awesome thing! Civic Commons to help local gov share software http://bit.ly/a9QW1a #gov20 #
- RT @govfresh: Join the 'Gov 2.0 Makeover' http://bit.ly/bWOrU8 #gov20 #manorgf #
Contact Me
Categories:
- Asterisk (14)
- Cell Phones (16)
- CouchDB (6)
- Development Tools (46)
- Digital Divide (8)
- General Discussion (84)
- Linux (10)
- News (21)
- Open Government (49)
- Open Source (37)
- Phone Voting (10)
- Standards (38)
- trixbox (4)
- Tropo (6)
- Tutorials (28)
- Twitter (32)
- VoIP (34)