EppsNet Labs: VoiceXML RSS Reader

7 Oct 2007 /

The Big Picture

We’re going to build application that takes RSS data — specifically the EppsNet.com feed — as input, and outputs a VXML file that can be read and spoken by a VoiceXML browser.

The RSS Source Format

The general structure of the EppsNet feed — or any RSS 2.0 feed — looks like this:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- generator="wordpress/2.2.2" -->
  3. <rss version="2.0"
  4.     xmlns:content="http://purl.org/rss/1.0/modules/content/"
  5.     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  6.     xmlns:dc="http://purl.org/dc/elements/1.1/"
  7.     >
  8.  
  9.   <channel>
  10.     <title>EppsNet: Notes from the Golden Orange</title>
  11.     <link>http://eppsnet.com</link>
  12.     <description>Online journal based in Orange County, CA.
  13.         Hilarious anecdotes tempered by the icy chill of certain
  14.         death.</description>
  15.     <pubDate>Fri, 05 Oct 2007 03:51:21 +0000</pubDate>
  16.     <generator>http://wordpress.org/?v=2.2.2</generator>
  17.     <language>en</language>
  18.     <item>
  19.       ...
  20.     </item>
  21.     <item>
  22.       ...
  23.     </item>
  24.       ...
  25.   </channel>
  26. </rss>

Each item within the RSS feed has a format that looks (slightly simplified) like this:

  1. <item>
  2.       <title>Post Title</title>
  3.       <link>http://eppsnet.com/2007/10/post-title</link>
  4.       <pubDate>Fri, 05 Oct 2007 03:51:21 +0000</pubDate>
  5.       <dc:creator>PE</dc:creator>
  6.  
  7.       <category><![CDATA[Category1]]></category>
  8.  
  9.       <category><![CDATA[Category2]]></category>
  10.  
  11.       <description>
  12.         <![CDATA[
  13.        Item summary
  14.        ]]>
  15.       </description>
  16.       <content:encoded>
  17.         <![CDATA[
  18.        Full item content
  19.        ]]>
  20.       </content:encoded>
  21.     </item>

VXML Output

Consult the VoiceXML 2.1 specification for more details, but the output we want will look like this:

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <vxml version="2.1">
  3.   <form id="MainMenu">
  4.     <field name="select_num" type="digits">
  5.       <prompt>
  6.         EppsNet: Notes from the Golden Orange
  7.         <break size="small"/>
  8.       </prompt>
  9.       <prompt>Please select a story from the following list.</prompt>
  10.       <prompt>
  11.         1: Post Title 1
  12.         <break size="small"/>
  13.       </prompt>
  14.       ...
  15.       <prompt>
  16.         5: Post Title 5
  17.         <break size="small"/>
  18.       </prompt>
  19.       <noinput>
  20.         Please select a number.
  21.         <reprompt/>
  22.       </noinput>
  23.       <nomatch>
  24.         Please select a valid number.
  25.         <reprompt/>
  26.       </nomatch>
  27.     </field>
  28.     <filled>
  29.       <assign name="selection" expr="select_num"/>
  30.       <if cond="selection =='1'">
  31.         <prompt>
  32.           Post Title 1. Post summary goes here [...]
  33.           <break size="small"/>
  34.         </prompt>
  35.         ...
  36.         <elseif cond="selection =='5'"/>
  37.         <prompt>
  38.           Post Title 5. Post summary goes here [...]
  39.           <break size="small"/>
  40.         </prompt>
  41.       </if>
  42.       <clear namelist="select_num"/>
  43.       <reprompt/>
  44.     </filled>
  45.   </form>
  46. </vxml>

What this will do when processed by a VoiceXML browser is:

  1. Say the title of the RSS feed.
  2. Offer the listener a numbered list of post titles to select from.
  3. Parse the user’s selection, by either voice or touch-tone input.
  4. Read out the selected post summary.
  5. Clear the input variable and offer the opportunity to select another item.

Generating VoiceXML from RSS

Because this is a WordPress site, we’re going to use PHP for the task of converting RSS input to VXML output. To simplify the task of parsing the input, we’ll use MagpieRSS, an RSS parser written in PHP.

The main loop in the code below processes up to 5 RSS items and simultaneously builds up two strings, one for the selection prompts and one for the item details.

  1. <?php
  2. /* We need this for MagpieRSS */
  3. require_once 'rss_fetch.inc';
  4.  
  5. /* Read the RSS feed */
  6. $url = 'http://eppsnet.com/feed';
  7. $feed = fetch_rss($url);
  8.  
  9. $selection = '';
  10. $detail = '';
  11. $counter = 0;
  12.  
  13. $selection .= '<form id="MainMenu">';
  14. $selection .= '<field name="select_num" type="digits">';
  15. $selection .= '<prompt>';
  16. $selection .= $feed->channel['title'] . '<break size="small"/>';
  17. $selection .= '</prompt>';
  18. $selection .= '<prompt>';
  19. $selection .= 'Please select a story from the following list.';
  20. $selection .= '</prompt>';
  21.  
  22. foreach ($feed->items as $item ) {
  23.     /* Limit output to 5 items */
  24.     if ($counter++ >= 5)
  25.         break;
  26.  
  27.     if ($counter == 1)
  28.     {
  29.         $detail .= '<filled>';
  30.         $detail .= '<assign name="selection" expr="select_num"/>';
  31.         $detail .= "<if cond=\"selection =='$counter'\">";
  32.     }
  33.     else
  34.     {
  35.         $detail .= "<elseif cond=\"selection =='$counter'\"/>";
  36.     }
  37.     $detail .= sprintf('<prompt>%s. %s<break size="small"/></prompt>',
  38. $item[title],$item[description]);
  39.  
  40.     $selection .= sprintf('<prompt>%d: %s<break size="small"/></prompt>',
  41. $counter,$item[title]);
  42. }
  43.  
  44. $selection .= '<noinput>Please select a number.
  45.                              <reprompt/></noinput>';
  46. $selection .= '<nomatch>Please select a valid number.
  47.                              <reprompt/></nomatch>';
  48. $selection .= '</field>';
  49.  
  50. $detail .= '</if>';
  51. $detail .= '<clear namelist="select_num"/><reprompt/>';
  52. $detail .= '</filled></form>';
  53.  
  54. /* Output the VXML */
  55. echo '<vxml version="2.1">';
  56. echo $selection;
  57. echo $detail;
  58. echo '</vxml>';
  59. ?>

Try It

I put the PHP script at http://eppsnet.com/lab/vxml but the output is not very interesting in a regular browser. Fortunately, Voxeo offers a free service that maps voice applications to phone numbers. You give them the URL of your voice app and they’ll point a phone number to it.

So — if you pick up the phone, call 800-289-5570 and enter PIN 9992002320, the Voxeo application will fetch the VXML output from our PHP script and read selected excerpts from the EppsNet feed to you over the phone.

Try it!

Limitations

The VXML output doesn’t contain the entire contents of each post, just the truncated version from the RSS <description> field. I tried using the <content:encoded> field instead but some markup constructs choked the Voxeo application. I think I could get it to work if I spent enough time on it, but for now, I’ve decided to leave it as an exercise for the reader.


One Comment on EppsNet Labs: VoiceXML RSS Reader »

  1. 7 Nov 2007 @ 4:04 pm


    Now… that’s bitchen!!!
    Good work.

TrackBack URI

RSS feed for comments on this post

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

%d bloggers like this: