Moving away from single-file VXML
- So far, we've been using a single file in the BeVocal Cafe for our applications
- Most times, we'll want to break up each state into a separate file
- This keeps your files more modular and makes it easier to develop your applications
Another use of the goto tag
- the goto tag doesn't have to point to another form in your document
- ...it can point to another file entirely
- Example:
<goto next="1001_choose_category.vxml"/>
Multiple Files
- I'd suggest using a single file per state
- This allows many niceties:
- 1) You can have multiple people working on different parts of the application at the same time
- 2) Debugging is easier -- your entire app doesn't break, just a single state
- 3) Its easier to manage, less code in one file is more readable
- Try to limit it to one form per file - doesn't have to necessarily be one per state
Generating your VXML
- For most of your projects, you'll have to generate your VXML based on some data
- There are many ways to do this, using any number of programming languages
- Today, we'll go over the architecture and an example using Ruby
Architecture of Generational VXML
No more .vxml files
- When generating VXML, we don't write VXML files directly
- Scripts will generate our VXML for us
- Today, we'll go over a couple examples of Ruby and its Builder library generating VXML
Hello World, from Ruby
#!/usr/bin/env ruby
require 'rubygems'
require 'cgi'
require 'builder'
cgi = CGI.new
output = ""
vxml = Builder::XmlMarkup.new(:indent=>2, :target=>output)
vxml.instruct! :xml, :version=>"1.0"
vxml.declare! :DOCTYPE, :vxml,
:PUBLIC, "-//BeVocal Inc//VoiceXML 2.0//EN",
"http://cafe.bevocal.com/libraries/dtd/vxml2-0-bevocal.dtd"
vxml.vxml(:version=>"2.0", :xmlns=>"http://www.w3.org/2001/vxml") {
vxml.form(:id=>"form") {
vxml.block {
vxml.prompt("Hello world!")
}
}
}
cgi.out("application/xml") {
output
}
That produces...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE vxml PUBLIC "-//BeVocal Inc//VoiceXML 2.0//EN" "http://cafe.bevocal.com/libraries/dtd/vxml2-0-bevocal.dtd">
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml">
<form id="form">
<block>
<prompt>Hello world!</prompt>
</block>
</form>
</vxml>
But why do this at all?
- We can insert the returns from functions into our VXML
- Suppose we wanted to say a random phrase, from a set of predefined random phrases, to the caller
- We could write a function to give us a random phrase, and call that in the Builder code
Random Phrase
#!/usr/bin/env ruby
require 'rubygems'
require 'cgi'
require 'builder'
cgi = CGI.new
output = ""
vxml = Builder::XmlMarkup.new(:indent=>2, :target=>output)
phrases = ["Hello World", "Hello Matz!", "Hey Chris!"]
def randomPhrase(phraseSet)
return phraseSet[rand(phraseSet.length)]
end
vxml.instruct! :xml, :version=>"1.0"
vxml.declare! :DOCTYPE, :vxml,
:PUBLIC, "-//BeVocal Inc//VoiceXML 2.0//EN",
"http://cafe.bevocal.com/libraries/dtd/vxml2-0-bevocal.dtd"
vxml.vxml(:version=>"2.0", :xmlns=>"http://www.w3.org/2001/vxml") {
vxml.form(:id=>"form") {
vxml.block {
vxml.prompt(randomPhrase(phrases))
}
}
}
cgi.out("application/xml") {
output
}
URL Parameters and goto
- goto has a expr attribute
- you can use it to generate the URL to go to
- for example, goto could look like this:
<goto expr="'http://web.mit.edu/esd.951/www/apps/1001_get_callerid.cgi?callerid=' + session.telephone.ani"/>
cgi = CGI.new
callerid = cgi['callerid']
In-class example
<field name="myfield">
<prompt>Say a number</prompt>
<grammar>
Digit [1 2 3 4 5 6 7 8 9 0]
</grammar>
<filled>
<goto expr="'myrubyfile.cgi?numberChosen=' + myfield + '&othernum1=' + myfield + '&othernum2=' + myfield + '&othernum3=' + myfield"/>
</filled>
</field>
Scraping the Internet for Prompts
- Many of you would like to use data collected from the internet in your applications
- Using Ruby (or the language of your choice), you can do this
- Imagine we had the randomPhrase method go out and get a phrase from wikipedia
- It'd act the same, still output VXML, but use some of Ruby's conveniences and libraries to do this
Architecture of Scraping Application
Screen Scraping Libraries
- There are screen scraping libraries for many languages
- Ruby has Hpricot, RubyfulSoup, and open-uri
- PHP has a built in DOMDocument, and a library called Simple HTML DOM Parser
- Python has ElementSoup and urllib
- Java has many options
Screen Scraping and You
- I will not be going over any of these libraries in class
- ...nor do I know how to use all of them
- Choose a language you're comfortable programming in and is suited to your project
- Use Google - simple queries yield powerful results and code examples
- 'ruby screen scraping example'
- 'php generate xml'
- 'python elementsoup scraping tutorial'
Some links to get you started