JavaScript Trick for Voice Applications

There are times when it is desirable to change the behavior of a VoiceXML application based on a specific setting.

For example, the GreenPhone application that I have mentioned in several previous posts has a setting that can be used to control whether special audio files are played. I personally find these audio files funny and somewhat endearing — others may not. To control whether they are played, there is a variable in the application root document called (cleverly) playAudio.

<var name="playAudio" expr="true"/>

It’s default setting is true, and this can be changed to false to prevent these files from playing. The typical method for checking a variable like this one to determine if an audio file should be played looks something like this:

<if cond="playAudio">
  <audio src="myFile.wav"/>
</if>

There isn’t anything wrong with this, and since there isn’t a “cond” attribute on the <audio/> tag there aren’t very many good alternatives. There is one alternative method that I rather fancy that uses the JavaScript conditional operator to distill this to a single line of code:

<audio expr="playAudio ? 'myRealAudioFile.wav' : 'myFakeAudioFile.wav'"/>

This shortcut allows us to assign a value to the audio file reference via the “expr” attribute, instead of using an explicit URI to the location of an audio file. The way the operator behaves is to first evaluate the condition on the far left side — if it evaluates to true then the first expression is assigned as the URI of the audio file. If it evaluates to false, then the second expression is used.

The trick here is that the second expression resolves to a bogus audio file — it doesn’t exist. This will not cause a fatal error in your application, it will simply cause Prophecy not to play an audio file (it can’t because the file doesn’t exist).

The JavaScript conditional operator can come in very handy in CCXML as well. For example, there are times in CCXML where I want to use <dialogterminate/> to end a call, but I may not be certain which dialog a caller is in — the JavaScript conditional operator can come in handy here:

<dialogterminate dialogid="loggedIn ? voiceMailDialog : loginDialog"/>

Since the “dialogid” attribute is an expression, we can use the JavaScript conditional operator to check and see if a caller has logged into a voice mail system to retrieve their voicemail. If there loggedIn status is true, we assume that they are in the voiceMailDialog and yank them from that. Otherwise, we assume they are in the first dialog and yank from there.

There are surely other ways to do these things, but in my humble opinion the JavaScript conditional operator deserves some attention as a powerful shortcut for doing things in CCXML or VoiceXML using the Voxeo Prophecy platform.

Virtualize Some Savings

There is a great article over on the Government Technology Magazine site discussing the virtues of virtualization. It includes some great examples of how governments are using this technology to reduce the footprint of their data centers, use less energy and simplify the maintenance of aging, unwieldy fleets of servers.

Sadly, it looks like governments have not led the charge on this:

“Although virtualization has entered the mainstream, the transition process is still in the beginning stage. About 75 percent of large organizations have started down the path to some degree, Goldworm said, but only about 5 percent of those organizations’ servers have been virtualized. She estimated that only 20 percent to 40 percent of government organizations have begun the process.”

What is especially interesting is that the trend towards the use of virtualization seems to favor smaller governments like counties and cities, that typically lag behind the federal and state governments in implementing new technologies:

“…smaller groups like city governments, because they tend to be in a homogeneous environment that is not as complex, are able to achieve results more quickly than larger organizations.”

It would be interesting to find out home many government agencies in my state have looked at virtualization, and how many have started down this road. I may have to look into how to conduct a survey on this issue.

Accessing Web Services From CCXML

This is the first in a series of posts that will highlight how to accomplish specific things using the Voxeo Prophecy platform. All of the examples that will be discussed draw directly from the GreenPhone project discussed in a previous post.

The first issue that will be discussed – accessing web services from CCXML using PHP.

One of the very cool things about Prophecy is that it comes bundled with the PHP scripting language. In fact, I have on occasion referred to PHP as Prophecy’s “embedded scripting language.” PHP 5 comes with an abundance of features that will be of interest to IVR developers – chief among them, the ability to create SOAP clients to interact with web services, and the ability to easily work with data in XML format using the SimpleXML extension.

If you’ve read my previous post on the GreenPhone Project, you will know that I am using a collection of web services from StrikeIron that includes a web service to provide information on U.S. area codes. If we pass this web service an area code, it will return the U.S. state that area code is in. Ultimately, what the GreenPhone application will do is look up E85 and bio-diesel stations by state. So when a person calls the application, we want to use their area code to look up what state they are in – thereby saving them the trouble of entering this information manually.

In CCXML, we can access the caller’s ANI via the Connection Object:

<transition state="initial" event="connection.alerting">
 <log expr="'*** Call is coming in. Lookup area code information. ***'"/>
 <assign name="ani" expr="event$.connection.remote"/>
 <assign name="areacode" expr="ani.substring(0,3)"/>
 <send target="'php/areaCodeLookup.php'" name="'lookupEvent'" targettype="'basichttp'" namelist="areacode"/>
</transition>

This block of code show how to set up a transition to access the ANI on an incoming call. When an incoming call is detected by Prophecy, the “connection.alerting” event is delivered and we have access to the Connection Object’s “remote” property – this property exposes the telephone URL for the device that is calling into the platform. Note – in my previous post, I explained the process of setting up the Prophecy SIP phone to deliver a specific ANI. This is how we access the value that is set in the Prophcy SIP phone.

We assign the ANI value to a variable we have previously declared and (very cleverly) called “ani”, and then we grab the first 3 characters of this string (using the ECMAScript substring method) and assign them to another variable called “areacode”. We then pass the area code value to a PHP script that will interact with the StrikeIron area code web service.

Using the CCXML <send/> element in this fashion is identical to an HTTP GET with the areacode variable appended to the URL of the PHP script, like this:

http://myserver/php/areaCodeLookup.php?areacode=123

There several possible outcomes of this HTTP request:

  1. Our PHP script was able to successfully interact with the StrikeIron web service and lookup the U.S. state information for the submitted area code;
  2. Our PHP script was able to successfully interact with the StrikeIron web service but was not able to lookup the state information for the submitted area code (bad area code);
  3. Something went wrong (an exception occurred) while trying to interact with the web service; or,
  4. Something really went wrong and our HTTP request resulted in a bad response from the server.

We need to set up handlers for each possible outcome – we won’t discuss them in detail until after we look more closely at the PHP components that are interacting with the StrikeIron web service, but to summarize what we’ll need, here they are:

<transition state="lookup" event="areaCodeLookupSuccess">
</transition>

<transition state="lookup" event="areaCodeLookupFailure">
</transition>

<transition state="lookup" event="error.send.failed">
</transition>

The first two handlers react to custom events that we will toss into the CCXML event stream (more on that shortly), and the last will take care of instances where we get an invalid response back from the server (e.g., a 404 response). Now lets look at the PHP components that interact with the StrikeIron web services.

When the HTTP request from Prophecy that holds our area code information is received in PHP, we can access the submitted value by using the PHP $_REQUEST superglobal:

$areacode = (int) $_REQUEST['areacode'];

You’ll notice that we also typecast the value as a way of cleansing the input – as with any other kind of web application, never trust user input. Even though we’re not using the submitted information in a SQL query, this is a really good habit to get into. There are certainly other ways to achieve this, but type casting is simple and effective for our purposes.

The PHP version that comes bundled with Prophecy has support for PHP’s SOAP extension right out of the box. Since we’re going to be accessing several different web services over the course of one telephone call, I decided to set up a very simple class to handle all of the interactions with the StrikeIron web services.

class greenSoapClient {

  private $client;
  private $headers;

  function __construct($type) {
    global $WSDL, $USER, $PSWD;
    $this->client = new SoapClient($WSDL[$type], array('trace' => 1,
                                          'exceptions' => 0));
    $headerArray = array("RegisteredUser" => array("UserID" => $USER,
                                          "Password" => $PSWD));
    $this->headers = new SoapHeader("http://ws.strikeiron.com",
                                          "LicenseInfo", $headerArray);
  }

  function makeSoapCall($name, $params) {
    $result = $this->client->__call($name, array($params), NULL, $this->headers);
    return $this->client->__getLastResponse();
  }

  function __destruct() {
    unset($this->client);
  }

}

This class has only three functions – a constructor, a destructor and a function to make the call to the SOAP method we want information from.

When we instantiate the greenSoapClient class, we pass in a reference to a WSDL file for the service we want to invoke. In this case, we will pass in a reference to the WSDL file for the U.S. Area Code Information Web Service. (Actually, the string “areaCode” is used to access the WSDL reference from a pre-established associative array holding the URL references for all of the WSDL files used by the greenPhone application.)

$mySoapClient = new greenSoapClient("areacode");

Now that we have our area code information, and a shiny new greenSoapClient object to work with, we can make our SOAP call:

$param = array('AreaCode' => $areacode);
$response = $mySoapClient->makeSoapCall('GetAreaCode', $param);

The variable $response now holds the XML response that was returned from the web service. We’ll need to process this response in order to properly format the information we want to return to CCXML.

One of the very cool things about the Voxeo implementation of CCXML is that developers can toss custom events into the CCXML event stream using simple HTTP responses. Prophecy lets us send back a custom event, as well as any data that we want to access in CCXML as properties of that event. We do this by formatting our response as follows:

First line of body of HTTP response = custom event name.
Data to be returned to CCXML = name value pair appearing on successive lines of the HTTP body, one pair per line.

The U.S. Area Code Information Web Service returns two pieces of information that we want to access in CCXML – a count of the number of locations identified for each area code (typically 1), and the name of the U.S. state that area code belongs to. A snippet of the raw response returned from the web service might look something like this (for the 610 area code):

<ServiceResult>
 <Count>1</Count>
 <AreaCodes>
  <AreaCodeInfo>
   <AreaCode>610</AreaCode>
   <Location>Pennsylvania</Location>
  </AreaCodeInfo>
 </AreaCodes>
</ServiceResult>

We want to format our raw XML response like so:

areaCodeLookupSuccess
count=1
location=Pennsylvania

The easiest way to do this in PHP is to use the SimpleXML extension:

$xml = new SimpleXmlElement($response);
$result = $xml->soapBody->GetAreaCodeResponse->GetAreaCodeResult;
$output = "areaCodeLookupSuccessn";
$output .= "count=".$result->ServiceResult->Count."n";
$output .= "location=".$result->ServiceResult->AreaCodes->AreaCodeInfo->Location."nn";

We take the response from the StrikeIron web service and use it to create a new SimpleXML object. We can then access the values we want and build our HTTP response.

How do we deliver our response once we’re done constructing it, we simply use the PHP “echo” language construct to write it out:

echo $output;

Now that we’ve returned our values to CCXML, how do we access them? For the answer to that,we need to go back to the handlers we set up previously, most importantly the handler for the custom “areaCodeLookupSuccess” event:

<transition state="lookup" event="areaCodeLookupSuccess">
 <assign name="count" expr="event$.count"/>
 <if cond="count == 1">
  <assign name="location" expr="event$.location"/>
  <assign name="stateCode" expr="getStateCode(event$.location)"/>
  <assign name="myState" expr="'accepting'"/>
  <accept connectionid="connection_id"/>
 <else/>
  <log expr="'*** Could not look up area code. ***'"/>
  <reject/>
 </if>
</transition>

When we write out our web service response in PHP, we can cause a custom event to drop into the CCXML event stream – the name of this event is the first line of the HTTP response we just constructed – areaCodeLookupSuccess.

We access the values we just returned to CCXML as properties of the areaCodeLookupSuccess event using the “event$.” vernacular. This allows us to assign these values to ECMAScript variables that we have previously declared. It also lets us decide how we want our application to react, based on certain conditions (e.g., if count = 0).

Similarly, our other event handlers can be used if we get an unexpected response form the web service – we could send back a “areaCodeLookupFailure” event. If something really bad happens – like an invalid response from the web server we will get an “error.send.failed” event, so we’ll want to have a handler ready for that as well.

Now that you have a flavor for how to access web services using CCXML and PHP, we’ll look at two different techniques for returning information from a web service to VoiceXML. We’ll cover these two techniques in the next two posts. Stay tuned…

Earth Day Special Project: GreenPhone

Earth Day 2008 is fast approaching, so I wanted to try and build something that would help the environment and also be a cool demonstration of telephone applications generally, and the Voxeo Prophecy platform in particular.

I decided to whip up a simple application that would allow a caller to search for E85 and Bio-diesel fuel stations in their state. Some of the specific goals that I had in mind when I got started were:

  • To make use of the Voxeo Prophecy platform, the premiere VoiceXML/CCXML platform for building voice applications (at least in my opinion).
  • To code the application entirely in VoiceXML, CCXML, ECMAScript and PHP (that’s right, no database!).
  • To integrate with SOAP-based web services to obtain data on E85 and Bi-Diesel station locations, and to do other cool stuff like send an SMS message from VoiceXML.
  • To make use of interesting and unique audio files for prompts and to signal specific types of outcomes.

The fruits of one weekend of labor can be downloaded here. To set up and test this application, you will need the following:

  • An account with StrikeIron to use the web services that drive the GreenPhone application.
  • A copy of Voxeo Prophecy.
  • A good headset and microphone (to place test calls using Prophecy).
  • A cell phone (preferably one with a liberal text messaging contract).

Sign Up With StrikeIron:

Create an account with StrikeIron and sign up for the Super Data Pack Web Service. This is a collection of web services that allow for up to 10,000 hits / month at no charge (where are you going to get a better deal than that?). You’ll also want to sign up for the Global SMS Pro Web Service – this is the service that is used to send SMS messages from the GreenPhone application. Note – this service is priced quite differently than the Super Data Pack Web Service – only 10 free hits before you start paying. If you want to use this service for anything more than just testing out how to send an SMS message from Voxeo Prophecy, you’ll need to get your wallet out.

Make note of the user ID (email address) and password used to create your StrikeIron account – these will be needed momentarily.

Download and install Voxeo Prophecy:

Download and install the Voxeo Prophecy software. Follow all of the instructions for installing and obtaining a license – a two-port license (which will support 2 concurrent phone calls) is free. Right now, prophecy only runs on Windows, but a Linux version is in the pipeline.

Download and Configure GreenPhone:

Download the GreenPhone application and extract it to a new directory under c:{Prophecy install path}www. (For example, on my Windows machine I’ve extracted to c:Program FilesVoxeowwwGreenPhone). You don’t have to run the GreenPhone application on the same machine as Prophecy – if you decide to deploy it on another machine, it must support PHP 5 – GreenPhone makes use of the PHP SOAP and SimpleXML extensions.

Once this is complete, navigate to the directory where you just extracted the GreenPhone application files. Go to the directory called “php”, and open the file called common.php. At the top of this file, enter the credentials from your StrikeIron account. Save and close the file.

Creating a Call Route for GreenPhone:

Open the Prophecy Management Console in your web browser (http://127.0.0.1:9995/mc.php) – the default user ID and password are admin/admin. Click on the “Call Routing” option on the left hand menu – this is where you will set up a call route to the GreenPhone application.

Pick one of the numbered route Ids (e.g., Route 1 ID) and make the following changes:

  • Change the route ID to green
  • Change the Route Type to CCXML W3C
  • Change the URL to http://127.0.0.1:9990/{ GreenPhone Install Directory}/greenPhoneStart.xml
  • Scroll to the bottom of the page and click “Save Changes”

Making a test call:

Now that Prophecy is installed, fire up the SIP Phone that it is bundled with – you should see the Prophecy icon in your system tray. Click on it, and select “SIP Phone” from the menu. When the SIP Phone launches, select Options. In the SIP Proxy / Registrar Options section, enter your cell phone number in the Local Username field (e.g., 2125551234). Click OK, and restart your SIP Phone. This last step allows your cell phone number to be delivered as the caller ID (or ANI) on the test call you are about the make, even though your initiating the call from a SIP phone.

GreenPhone is built to use ANI to look up E85 and Bio-Diesel stations in the caller’s home state. We do this by invoking the U.S. Area Code Information Web Service that is part of the StrikeIron Super Data Pack to determine which state a caller is calling from. There are additional web services in the StrikeIron Super Data Pack that we can invoke to locate Bio-Diesel stations and E85 Stations — the methods invoked on these last two services require us to identify the state we want a listing of stations for.

The caller’s ANI is also used to send the details on a particular E85 or Bio-Diesel station via text message to the caller’s phone – so if you enter your cell phone number in the Voxeo SIP Phone as described above, you can get details on a station that may be near you sent directly to your cell phone.

As an aside, you’ll notice that a single phone call can result in up to 4 web service invocations — not really sure if that’s “too many” but there are probably some opportunities for caching that I’ll be discussing in the next couple of posts on this, as I describe in more detail how to interact with web services via Voxeo Prophecy.

Now you are ready to place a test call. When your SIP Phone restarts, go to the field called Dial String and enter “sip:green@127.0.0.1” (without the quotes). Click dial and you are now interacting with the GreenPhone application!

You’ll notice (and hopefully enjoy) the unique sounds I’ve tried to used throughout the application. All of them were obtained from the FreeSound Project and modified to conform to the Prophecy standard for audio files with Audacity.

There are some obvious limitations to how this application currently works, and the VUI clearly needs some refinement (DTMF only at this point).

In the next several posts, I’ll point to this application to discuss examples on how to accomplish things in VoiceXML and CCXML using the Voxeo Prophecy Platform.

Have a happy Earth Day on 4/22!!

Government Technology Mistakes

One of the things that makes government agencies unique is that they are repositories for vast amounts of information — some of which is highly sensitive (i.e., tax data), or that could be damaging if it fell into the wrong hands (i.e., social security numbers).

Accounts of government agencies exposing sensitive data, like social security numbers, are shockingly common. Many of these stories share an underlying theme or two. One of the most frustrating — poor web programming.

The State of Oklahoma’s Department of Corrections is the latest to join this embarrassing fraternity of government entities that have completely overlooked the most basic tenets of good web development and exposed sensitive information.

One of the cardinal rules of computer programming is to never trust your input. This holds especially true when your input comes from users, and even more so when it comes from the anonymous, general public. Apparently, the developers at Oklahoma’s Department of Corrections slept through that day in computer science class, and even managed to skip all of Common Sense 101. You see, not only did they trust anonymous user input on their public-facing website, but they blindly executed it and displayed whatever came back.

The result of this negligently bad coding has some rather serious consequences: the names, addresses, and social security numbers of tens of thousands of Oklahoma residents were made available to the general public for a period of at least three years.

Including an SQL statement as a URL parameter and then blindly allowing your web application to execute said parameter is a recipe for disaster.

After reading this, I thought it might be interesting to see how common this problem might be with other government website. I decided to run a quick check using one of the advanced search features of Google to look for SQL keywords in web site URLs that have “.gov” in them. The results? Very, very Depressing.

The fact that the Oklahoma DOC allowed the social security numbers of individuals to be displayed through SQL manipulation masks a deeper issue — why are these social security numbers being stored in unencrypted form in their database? If there isn’t a legitimate reason to store this data in an unencrypted form, then it should be avoided at all costs. (And the database that holds the unencrypted version should be nowhere near a web server.) One way encryption works just fine for most authentication needs.

This same issue was the cause of a breach at the University of Delaware a few years back — wonder if they learned their lesson?

Telephone Links in Web Pages

Have you ever hovered over a hyperlink on a web page and noticed that it uses the mysterious tel: protocol? What happens when you click on a link like this in your browser?

The answer to that question can depend a lot on how your browser is set up. If your using Firefox, you can associate specific applications with different protocols by opening a new tab and entering about:config in the address bar.

In the configuration settings you’ll need to add two entries, or modify the existing ones if these are already there:

  • network.protocol-handler.external.tel (boolean – set to true).
  • network.protocol-handler.app.tel (string – the path to the application you want to launch)

Not exactly sure if this works the same way on Windows, but on my Linux machine I set the second value to the path to my Gizmo softphone (/usr/bin/gizmo) and it automatically launches and dials the number. Pretty neat!

There is a standard for telephone URIs out there, but there doesn’t seem to be a lot of good information on how different browsers / platforms deal with this type of link.

This might be a good area for some standards, especially since lots of web content is now being consumed on mobile devices (like iPhones) that are more tightly coupled with phones.

If anyone is aware of some standards in this area, or even where better information on different browsers / platforms can be obtained, please call me. 😉

A Look at Google’s FCC Auction Strategy

The NY Times has a really interesting article detailing the strategy of Google executives bidding on wireless spectrum in the recent FCC auction.

Google’s legacy from this historic auction is that it helped ensure that a portion of the spectrum purchased would be subject to specific requirements of openness. The “C Block” of spectrum that the FCC will require be managed under the tenants of openness was ultimately won by Verizon Wireless.

Even though Google didn’t “win” the auction for the C Block outright, there are those that believe that their strategy of opening up the world of wireless communication may have been served nonetheless:

“If Google had won a license, there was only downside risk for them,” said Gregory L. Rosston, a former F.C.C. official and senior fellow at the Stanford Institute for Economic Policy Research. “Now they can just spend $1 million a year on a law firm to ensure Verizon lives up to the openness requirements.”