
Creating VoiceXML Applications With Perl
Introduction
VoiceXML is an XML-based language used to create Web content and services that can be accessed over the phone. Not just those nifty WAP-enabled "Web phones", mind you, but the plain old clunky home models that you might use to order a pizza or talk to your Aunt Mable. While HTML presumes a graphical user interface to access information, VoiceXML presumes an audio interface where speech and keypad tones take the place of the screen, keyboard, and mouse. This month we will look at a few samples that demonstrate how to create dynamic voice applications using VoiceXML, Perl, and CGI.
A rigorous introduction to VoiceXML and how it works is beyond the scope of this tutorial. For more complete introductions to VoiceXML's moving parts see Didier Martin's Hello, Voice World or the The VoiceXML Forum's FAQ.
Reach Out and Surf Somewhere
To demonstrate how easy it can be to make existing Web content available over the phone we will create a simple Perl CGI script that fetches an RSS channel file containing a list of the most recent uploads to CPAN and converts parts of it to VoiceXML so that it may be accessed over the phone via a VoiceXML gateway.
use strict; use XML::XPath; use LWP::UserAgent;
After loading the necessary module we begin our script by creating
new HTTP::Request and LWP::UserAgent
objects. We then call LWP::UserAgent's
simple_request method to ask the remote server for the
RSS file.
my $news_url = 'http://search.cpan.org/recent.rdf';
my $request = HTTP::Request->new('GET', $news_url);
my $ua = LWP::UserAgent->new();
my $response = $ua->simple_request($request);
Now that the request has been made, we will begin the VoiceXML
output. We start by creating the mandatory vxml root
element and a minimal form that contains a single
block element. Inside the block element we
put an audio element that asks the user to be patient
while the RSS file is processed and a goto element that
tells the VoiceXML browser to jump to the section of the current
document labeled "headlines".
print qq*
<?xml version="1.0"?>
<vxml>
<form id="greeting">
<block>
<audio>
Please wait while I process the c pan news feed.
</audio>
<goto next="#headlines"/>
</block>
</form>
*;
Also in Perl and XML |
|
OSCON 2002 Perl and XML Review PDF Presentations Using AxPoint |
Next we test the response object to ensure that we received the
remote RSS file. If the file was successfully fetched, we create a new
XML::XPath instance and pass it the content section of
the response object for parsing. If anything goes awry during the
request, or while parsing the returned content, we trap the error in
the scalar $error for later processing. Although the
eval block that wraps the initial call to
XML::XPath adds a fair bit of overhead to the script, it
nevertheless gives us a way to fail gracefully in the event of a
parsing error. Without the surrounding eval, a parser
error would cause the script to die unexpectedly.
my ($error, $xp);
if ($response->is_success) {
eval {
$xp = XML::XPath->new(xml => $response->content);
$xp->find('/');
};
$error = 'Error parsing RSS file ' . $@ if $@;
}
else {
$error = 'Remote server returned ' . $response->message();
}
If an error does occur along the way, we return a simple
audio message that describes the error,
disconnect (hang up on) the current user, and close the
VoiceXML document.
if ( defined($error) ) {
print qq*
<form id="headlines">
<block>
<audio>
I'm sorry. The following error occurred while fetching
the headlines file. $error Please try again later.
</audio>
<disconnect/>
</block>
</form>
</vxml>
*;
}
|
|
| Post your comments |
If the RSS file has been fetched and parsed successfully we create
a new form element; then, using an audio
element inside a block wrapper, we tell the caller about
the success and prepare them to hear the list of modules.
else {
print qq*
<form id="headlines">
<block>
<audio>
The RSS file has been fetched and processed successfully. The
following modules have recently been up loaded to c pan.
</audio>
</block>
<block>
*;
Next we loop through all the item elements in the RSS
document. For each item element encountered we print a
corresponding audio element for our VoiceXML document
using the value of each item's title child element as the
text.
foreach my $news_item ($xp->findnodes('//item')) {
print "<audio>" .
$news_item->findvalue('title') .
"</audio>\n";
}
Finally we signal the caller that the entire list has been read,
invite them to call again the next day, disconnect, and
close the VoiceXML document.
print qq*
<audio>
This completes the latest c pan up loads. Please call again tomorrow.
</audio>
<disconnect/>
</block>
</form>
</vxml>
*;
}
While this script is not terribly useful in and of itself, think for a moment about just exactly what we have done here. In a few lines of code we have taken a resource from a distant part of the Web, extracted the information that we care about, and made that information available from any phone anywhere in the world.
Pages: 1, 2 |