….::: 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.
31st
AUG
Gov 2.0 is Open Source
Posted by Mark Headd under Open Government, Open Source
It’s interesting to reflect back on the not too distant past and think about how governments have used open source software.
For many state and local governments - as recently as a few years ago - the use of open source software was something of a foreign concept. Many a government IT worker made an impassioned and well reasoned plea to bosses and co-workers to consider using open source software to capitalize on a range of different benefits. (And yes, in case you’re wondering, when I was a state government IT worker I made many such pleas to bosses and co-workers.)
For a long time, those pleas usually went unheeded. How far we’ve now come.
Not only are more and more state and local governments starting to realize the benefits of using open source software, some of them are actually starting to become developers of open source solutions.
The notion of government-sponsored open source software development isn’t necessarily new - it’s how we got SE Linux for example. But it is still a relatively new concept for state and local governments. I can think of two government entities that are leading the charge.
First, the New York State Senate. Under CIO Andrew Hoppin, the New York legislature’s upper chamber has become a leader in the public sector for its use of open source software. Not only does the Senate use Drupal for its public website, they also contribute Drupal modules back to the community.
After becoming the first legislative body in the country to develop iPhone and iPad apps, they not only released the code for these apps on GitHub, they actually did a code walk through for developers at a recent event in Albany.
And now, the State of Washington has released the code for its own mobile apps on GitHub. They are actively encouraging people to submit ideas to help further develop the software and to identify bugs.
Both of these governments (and others who are out there doing the same thing) will realize more benefits by open sourcing the code for their apps than they would have had they kept the source code a secret. By making the code for their apps visible and reusable, they’ll attract more developer interest and help ensure that bugs or security issues get identified quickly.
Other governments will benefit as well - these two organizations are clearly ahead of the curve in developing mobile apps, and other governments will benefit from their experience and expertise. Since’s governments generally don’t compete directly with each other, this type of sharing makes perfect sense.
Improvements or enhancements to these open source applications will in turn provide benefits for the governments that created them - this is one of the driving dynamics of Gov 2.0.
I’m wondering if there are other state and local governments out there doing this same thing. Do you know of a government agency or entity with a GitHub repo or other open source code repository?
Leave a comment below with the details.
13th
AUG
Make the Cloud Listen (and Understand)
Posted by Mark Headd under Development Tools, Open Source, Tropo, Tutorials
Yesterday I wrote a post about the changing cloud telephony landscape, and highlighted some key factors that will dictate which cloud telephony providers are around for the long haul and deliver the next innovations.
One of those factors - support for speech recognition - is a good differentiator for developers to use when choosing a cloud telephony platform.
Speech recognition is becoming increasingly important in our everyday lives. Smartphones and powerful handheld devices enable multimodality, and there are more and more restrictions placed on our use of phones while doing other tings (like driving).
Plus, I can’t think of a more deflating concept than a cloud telephony provider that allows developers to build sophisticated apps and mashups in the language of their choice but that chains users of those apps to a telephone keypad. No fun.
To give an example of how powerful speech recognition can be, and how easy it is to use with a cloud telephony provider that supports it, I worked up a small demo to illustrate the point. The sample code for this demo is on Github, and we’ll dive into it in more detail below.
This demo uses two PHP libraries that are designed to work with the Tropo platform (one of the only cloud telephony providers to support speech recognition):
- A set of PHP classes for working with the Tropo WebAPI.
- A PHP library for creating SRGS grammars in XML format.
If you’ve read any of my previous posts on build applications for the Tropo platform, you’ll see lots of similarities between this and previous sample apps. Here I continue my use of the insanely awesome Limonade Framework for PHP.
Let’s take the example of a company directory that allows callers to dial a single number, select a person or department at the company and then be transferred to the person they select.
With cloud telephony, there is no need to have such a system live on a machine in the server room - it can be hosted externally in the cloud, making it easier to manage and to scale. In addition, with the Tropo Platform, it doesn’t have to be the same tired old DTMF-based menu telling callers to press an extension number or to “dial by name…”.
Using the PHP WebAPI Library and Limonade, we can construct a simple, yet power script that looks like this:
This script is pretty self-explanatory, but there are some key points I want to emphasize. First, note the $options array that holds the reference to an external grammar file (more on that in a bit). Tropo seems to need for this reference to be an absolute one and not a relative reference to the file (not hard to do with PHP - you just need to be aware of it).
Also, the file reference needs to include a trailing parameter indicating that this is an XML grammar (;type=application/grammar-xml). This seems to be true even if the grammar file is served with the correct MIME type by whatever is serving it.
Now lets have a look at this grammar file.
This simplistic example demonstrates how to use the PHPGrammar library. Note the simple array structure that is being used to hold the details of employees for our fictitious company. This could very easily be replaced with a dip into a data source of pretty much any kind, like an LDAP directory or database holding employee details.
Also note in this example that we want to do something referred to as Semantic Interpretation. Our grammar file is a set of rules that will be applied to what the caller says - Semantic Interpretation (SI) dictates the value that is given to our application from the grammar when a successful match occurs.
In this example, we want the caller to be able to say the name of the person they want to be transfered to. We make the first name optional so they may either say the last name of the person or (optionally) the full name. Obviously this may need to be changed based on the size of the directory to render in a grammar file (e.g., multiple employees with the same last name).
Do note that the Tropo platform seems to require the “Script” sytax for returning SI values on a successful match as opposed to the “String Literal” syntax. (More on these alternatives here.)
Works on Tropo (Script syntax):
<item>foo<tag>out=”bar”;</tag></item>Does not work on Tropo (String Literal syntax):
<item>foo<tag>bar</tag></item>
So, when a caller says the name of a person in our company directory we want to return the number for that person to our Tropo script so we can transfer the call to them. This can clearly be seen when we examine the Result object that is delivered by the Tropo platform.
Tropo’s Result object includes the full grammar engine output, and lots of very detailed information about the recognition. As you can see, the utterance that the speech recognition engine heard was the name of one of our faux employees. The value that was returned is the number of that person.
We use this value in the transfer_call() method of our Tropo script.
// Create a new instance of the Result object.
$result = new Result();// Get the value of the selection the caller made.
$phone = $result->getValue();// Create a new instance of the Tropo object and transfer the call.
$tropo = new Tropo();
$tropo->transfer('+1'.$phone);// Write out the JSON for Tropo to consume.
$tropo->RenderJson();
Using the PHP WebAPI library, it takes just 5 lines of code (excluding comments) to get the value of the grammar result and transfer the call. How cool is that?!
Obviously there are lots of things that can be done to enhance this script, to make it more robust, but it illustrates the essential concepts of speech recognition in the cloud.
What’s more, because of all of the great functionality provided by the Tropo cloud platform we can really push the envelope on the tired old company directory:
- We could take an inbound call from a Skype user and transfer to a cell phone (or a SIP endpoint).
- We could let our caller select a department in our company and then ring several different numbers at once, transferring the call to the first one answered (sort of a “hunt group in the cloud”).
- We could use Tropo’s built in IM capabilities to send a screen pop to the person receiving the call.
The sky is the limit. Which I guess is the point of cloud telephony…
12th
AUG
What Matters in Cloud Telephony
Posted by Mark Headd under News, Standards, Tropo, VoIP
The landscape of cloud telephony continues to change.
I was heartened this week to see some of the sharpest minds I know in cloud telephony and unified communications get together with the acquisition of Teleku by Voxeo. Teleku and Voxeo’s Tropo service are complimentary ones that offer lots of goodies for developers, and I’m anxious to see what these guys will be cooking up now that they have joined forces. Congrats to all involved!
While there is lots of discussion about what this acquisition means for the constantly changing landscape of cloud telephony, this move validates (in my mind) some of the important trends that will determine which cloud telephony companies will be around for the long-term and how developers will use their services.
None of this is new - I’ve said it all before. It is worth noting, however, that all of the trends that I’ve observed before that are going to make the difference in the cloud telephony space are ones that both Tropo and Teleku do very well.
Portability - underscored not only by Teleku’s support for the open standard VoiceXML, but also the Tropo crew’s involvement in the Asterisk world, and the defacto standard for building Asterisk apps in Ruby - Adhearsion.
SIP integration - remember this kids: true cloud telephony has SIP baked in - the rest is just marketing fluff. Both Tropo and Teleku support SIP interoperability and make it very easy for developers to use SIP as part of their applications.
Multi-channel / multi-modality - Both Tropo and Teleku have big multi-modal chops. Being able to interact with users on multiple communication channels from one code base is a key tenet of unified communications and cloud telephony, and this will become increasingly important in the future.
Speech recognition - cloud telephony isn’t your grandfather’s way to build a phone app, so why should users be restricted to their grandfather’s way of interacting with a phone app? Speech recognition is fully supported in both Tropo and Teleku, and this will matter more and more to cloud telephony developers going forward.
So if you’re wondering what the next change in the cloud telephony landscape will be, you can bet that one of these trends will dictate the change.
Until then, I’ll be hacking on some cloud-based, speech rec enabled UC apps.
9th
AUG
Time to Get Tough with 311 Vendors
Posted by Mark Headd under Open Government
Big news recently in the Open311 world.
Lagan - a technology company that provides solutions for local government, including 311 systems - has announced the launch of an integration toolkit to allow “local government customers worldwide to receive and action service requests via social networks, mobile applications and third-party websites.”
This is good news for governments that want to utilize different communication channels to accept and respond to non-emergency service requests, or that want to stand up an API for outside developers to use.
Lagan’s announcement is based on some pioneering work done in the City of San Francisco to do both of these things - San Francisco was one of the first (if not the first) city to use social networking services to take 311 service requests, and they were an early adopter and enthusiastic advocate of the Open311 initiative.
Hopefully, this action by Lagan will catch on with other vendors. It’s worth noting that, according to the Pew Charitable Trusts (which conducted a study of Philadelphia’s 311 system earlier this year, and compared it to 14 other large cities with 311 service) that over 30 percent of large municipalities with 311 service share a common vendor - Motorola. It would be nice if Motorola would follow Lagan’s lead on this issue.
Whether or not they do is an open question. Certainly they have a customer that is as pioneering in their support of Open311 and alternative channels for 311 service as Lagan does (Motorola is the vendor for the District of Columbia).
I continue to believe (and have argued the point with other Open311 advocates) that the best way to “encourage” vendors to support integration toolkits like Lagan’s in their products is to make it a requirement in bidding on 311 projects.
Let’s be realistic - if even one of the large cities that utilize Motorola’s 311 solution made it a requirement during a contract renewal or an open bid that any 311 solution considered must support integration of multiple communication channels or have a generic interface for implementing an externally facing API it would get done. No question about it.
This position is actually strengthened by Lagan’s recent announcement. They have removed any possibility of responding to such a requirement in a bid by saying that no vendor supports such functionality. There is now a vendor that does - Lagan.
It’s time for governments with 311 services to get tough with their vendors and insist that they support alternate channels for servicing 311 requests and for implementing external API’s.
30th
JUL
The Case for Open Transit Data
Posted by Mark Headd under Open Government
This is an awesome short film from StreetFilms.org that convincingly lays out the case for open transit data.
Later this year, the State of Delaware will - for the first time ever - release all of its transit data in open formats. This is the result of a bill introduced this past legislative session by State Senator Bethany Hall-Long.
I’m hoping that there is a lot of excitement generated as a result of this data being released, and that our leaders in state government realize the potential benefits of opening up all kinds of government data.
It would be great to see state government engage local developers (from all over the Delaware Valley and the Philadelphia area) and have them build all sorts of cool civic applications with open data.
20th
JUL
Sunlight Creeps In…
Posted by Mark Headd under Open Government
A few weeks ago, I wrote a blog post about a now infamous land deal in Delaware between the state’s Department of Transportation and a close personal friend of the former governor, Ruth Ann Minner.
Following a series of scathing newspaper articles and editorials about the deal, the current Administration began constructing new regulations to govern the long-term lease of public lands by the Department of Transportation.
My post was written primarily in reaction to comments made by the current Secretary of Transportation (who, by the way, was the Secretary under the former governor when the sweetheart deal was granted) which suggested that she did not want to see an outside body review potential lease deals.
At the time, I suggested that this was a defining moment for the current Governor, who campaigned on opening up state government to more scrutiny and enhancing transparency:
I would suggest that this is a litmus test moment for Governor Jack Markell on transparency. It’s time for him to put his actions where his rhetoric has been.
Governor Markell should immediately direct DelDOT to develop a system for leasing public land for private development that is open and accountable. The current system used by DEDO should be emulated with an emphasis on public review of proposed leases with an opportunity for Delaware citizens to access details of proposed leases and raise questions.
In reviewing the proposed regulation submitted by the Department of Transportation in the wake of this scandal, I’m pleased to see that a some public review mechanisms have been included, despite the earlier comments of the Transportation Secretary. It’s also somewhat reassuring to see that the responsibility for determining if a below-market value lease of publicly owned land is approved rests with an oversight body - the state’s Council on Development Finance.
Having said that, there is room for improvement. For one, I can’t figure out what decade this regulation was written for.
The State of Delaware has spent millions on an infrastructure for publishing and managing state agency web sites. The State (including the Office of the Governor itself) has devoted countless hours to using social media platforms, including a massive overhaul of the State’s web site to highlight the social network accounts of state agencies.
And yet, nowhere in the proposed regulations does the word “Internet” appear. Or the word “website.” The regulations would require only that the Department of Transportation advertise a proposed lease of public land at a below-market rate in a “newspaper of general circulation in the county in which the parcel is located.” How 1975 is that?
It’s worth noting that the current Governor campaigned on his record as a technology executive, and his past participation in efforts to modernize the state’s IT workforce. It seems somewhat ironic then that this proposed regulation (written in concert with the Governor’s own legal counsel) could — from a technology perspective — easily have been written for a time when the Governor was in high school.
I guess I’m just curious why Twitter is appropriate for telling Delaware citizens to conserve water, but not to inform people of a potential lease opportunity of public lands.
Sunlight is indeed creeping into Delaware Government. Very, very slowly…
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…
9th
JUN
How Not to do a State Website Makeover
Posted by Mark Headd under News, Open Government
The Twitters have been abuzz lately with news of lots of state government websites being updated. California, Texas and Massachusetts have all made dramatic changes to their state websites to better serve citizens.
One recent state website overhaul was of particular interest to me - that of my current state of Delaware.
Before I offer my critique and tell you what I like and don’t like about the new Delaware.gov website, I should say that my opinion is somewhat biased. I was the Director of the Delaware Government Information Center during a previous Administration and the project manager of the effort to overhaul the old Gov 1.0 state web site and create a new citizen-focused web portal. The project I oversaw resulted in the first Delaware state web site to use the “delaware.gov” domain name.
The project I worked on was difficult - it took a lot of effort to get buy-in from agencies and agreement from them to relinquish some of the control they had over their old stovepiped web sites and work to incorporate their information into a centralized portal. For it’s time, it was a dramatic step forward and the state received national recognition for its efforts. The project had strong support from almost every elected official in the state. In particular, the effort was spearheaded by then State Treasurer Jack Markell - the man who is now Governor.
It should come as no surprise then that I have strong feelings about how the Delaware web site is designed, and how well it serves the citizens of Delaware. In my opinion, the new site design has a number of issues, and lags far behind some of the advances being adopted in other states.
Lack of Mobility and Accessibility
Right of the bat, the site runs into issues with mobile devices like the iPad and iPhone. How ironic is it that there is a graphic in the site header of a woman looking into a mobile device…
The iframes that occupy most of the real estate on the new site cause all sorts of problems with these devices, and the state should have explored other ways of displaying the information in these frames if it deemed it critical. Sadly, that is not the only issue caused by the use of iframes on the site.
When you use the site’s translation feature (located at the very bottom), you see that most of the content in these iframes resists translation to different languages, making it useless to non-English speakers. This problem is particularly acute because the non-translatable portions occupy such a large percentage of the real estate on the main page. What is the state trying to say here? Our social media content is so important we need to use the majority of our homepage to display it, but pay no mind if you speak Spanish?
Additionally, the site has some basic accessibility issues that can cause problems for people with disabilities. These issues are easy to fix, and its kind of embarassing that they were overlooked before the changes went live.
It’s troubling to see Delaware take steps backward in disability access and language translation on its official state web site.
Social Media or Propaganda
The social media content that is so prominently displayed on the main page is intrusive and crowds out much of the useful content. People use a state web site because they have a transaction they need to conduct, or information they need to find. There is a shockingly small amount of real estate devoted to things that typically bring most people to a government web site (and that’s the opinion of a social media fan).
In addition, all of the social media content that occupies the bulk of the site’s main page looks to be of the propaganda variety. Most of it looks to be recycled RSS feeds from agencies. (Note to other governments that may be watching, this is how not to do engagement via social networking.)
Show me the Data!
When I look at the new Texas and California web sites, here’s what I like. Both have ample links to their social media directories, but they don’t shove it down your throat like Delaware does - implicit recognition that people typically come to a government web site because they have a problem or need to conduct a transaction with government.
In addition, both have prominently displayed links to their government data catalogs. Both Texas and California recognize that a central element of Gov 2.0 websites is data.
It’s somewhat alarming to see Delaware falling so far behind this trend that is being embraced in so many other parts of the country. A lot of effort and time went into the redesign of the delaware.gov site and not a single open data set is to be found anywhere.
Sad.
Friend Connect:
@mheadd Tweets
- RT @DikshaDua: @mayormiller @311Toronto how empowering is it when the city listens...thanks for all your help! Hope it continues to listen! #
- Most 2010 "Best of Web" finalists prominently display links to #opengov and #transparency data on their portals. http://bit.ly/9eIibl #gov20 #
- RT @Jay_Nath: check out #SF #Open311 API presentation from #sfgf event http://slidesha.re/cFOPRK #
- RT @staceywalker: (California wins best web portal) "Best of the Web and Digital Govt Achievement Awards 2010 Results" http://bit.ly/aph ... #
- RT @corrisinternet: The #opensource Daily is out http://bit.ly/9AGxEI - featuring @HIMSS @kunena @mheadd @AlanRosenblith @twiki #
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 (36)
- Phone Voting (10)
- Standards (38)
- trixbox (4)
- Tropo (6)
- Tutorials (28)
- Twitter (32)
- VoIP (34)