Tropo WebAPI Development Guide Home  |  Frameset Home

  Quickstart  |  TOC  |  Behind the Scenes JSON - Quick Start Example  

The Example


Here is the entire code for the example application. As mentioned before, it's written in Ruby and utilizes Sinatra. Our 'resources', in this case index.json, your_age.json and age_fail.json, are defined in our Sinatra application through the use of post (line 7, line 27 and line 45 of Figure 2.0):

require 'rubygems'
require 'sinatra'
require 'tropo-webapi-ruby'

use Rack::Session::Pool

post '/index.json' do
  
    v = Tropo::Generator.parse request.env["rack.input"].read
    t = Tropo::Generator.new
        
    if v[:session][:initial_text].to_i > 0
        t.ask :name => 'initial_text', :choices => { :value => "[ANY]"}
        session[:year] = v[:session][:initial_text]        
    else
        t.ask :name => 'year', :bargein => true, :timeout => 60, :required => true, :attempts => 3,
                 :say => [{:event => "timeout", :value => "Sorry, I did not hear anything."},
                               {:event => "nomatch:1 nomatch:2", :value => "Don't think that was a year. "},
                               {:value => "What is your birth year?"}],
                 :choices => {:value => "[4 DIGITS]"}
    end
    t.on :event => 'continue', :next => '/your_age.json'
    t.on :event => 'incomplete', :next => '/age_fail.json'
    t.response
end

post '/your_age.json' do

    t = Tropo::Generator.new

    v = Tropo::Generator.parse request.env["rack.input"].read

    session[:year] = v[:result][:actions][:year][:value].gsub(" ","") unless session[:year]
    today = Date.today
    agecalc = today.year - session[:year].to_i
    lowdate = agecalc - 1
    highdate = agecalc + 1

    t.say "Your age is between #{lowdate} and #{highdate}", {:name => 'test'}
    t.hangup

    t.response
end

post '/age_fail.json' do
  
    t = Tropo::Generator.new

    v = Tropo::Generator.parse request.env["rack.input"].read

    t.say "Gotta use numbers!  Please try again."
    t.hangup

    t.response
end

To start, Tropo sends the initial session JSON to the index.json resource at your Sinatra application whenever someone calls, texts, or IMs your app (or launches it using an external event, such as a link on a website; more info on external events can be found in the Sessions & Tokens section of the Guide); you saw something similar in the How It Works section earlier. The script then converts this to a hash using this line of code in the Ruby application (line 9 of both Figure 2.0 and 2.1)


The session hash is then interpreted by the Sinatra application and moves to the appropriate resource as defined by our URL. The hash contains a lot of information, including the caller ID, the network the call came across, and specifically useful in the case of this app, the initial_text sent in a text message.

The application starts off requiring the various external programming elements, which includes Sinatra and our Ruby WebAPI Library (lines 1 through 3 in Figure 2.1), then enables the web session's information to be stored for later use (line 5 in Figure 2.1). It then defines our initial resource, index.json (line 7 of Figure 2.2), which we set in the URL earlier:

require 'rubygems'
require 'sinatra'
require 'tropo-webapi-ruby'

use Rack::Session::Pool

post '/index.json' do
  
v = Tropo::Generator.parse request.env["rack.input"].read

    t = Tropo::Generator.new
        if v[:session][:initial_text]
            t.ask :name => 'initial_text', :choices => { :value => "[ANY]"}
            session[:year] = v[:session][:initial_text]
        else
            t.ask :name => 'year', :bargein => true, :timeout => 60, :required => true, :attempts => 2,
                :say => [{:event => "timeout", :value => "Sorry, I did not hear anything."},
                    {:event => "nomatch:1 nomatch:2", :value => "Don't think that was a year."},
                    {:value => "What is your birth year?"}],
                     :choices => {:value => "[4 DIGITS]"}
  end
  t.on :event => 'continue', :next => '/your_age.json'
  t.response
end

The application interprets the session hash to see whether it's on the text or voice channel (line 12 of Figure 2.1) by looking for initial_text (which won't exist if it's the voice channel). If initial_text exists, Tropo will attempt to use the value in the logic of the application immediately. By only accepting values that are greater than zero, this ensures Tropo doesn't try to use something like "Hello" as a valid number.

Since we're working with voice, however, the application instructs Tropo to ask the caller for their birth year (line 19 of Figure 2.1). It also provides instructions telling Tropo what to do if the user doesn't enter correct input. If the caller enters nothing, it will trigger the timeout event; if that happens, the application tells Tropo to say "Sorry, I did not hear anything" (line 17 of Figure 2.1). If the caller says or enters something invalid, like letters or too many/too few digits, the application instructs Tropo to say "Don't think that was a year" (line 18 of Figure 2.1). The application also defines how many times to ask for the input, through the use of the attempts parameter (line 16 of Figure 2.1).

Tropo relays the request for the birth year to the caller using an ask with speech recognition, then sends back the received value (1980 in our example). The application takes the value and redirects it to the your_age.json resource, as defined by t.on :event => 'continue', :next => '/your_age.json' in the previous resource (line 22 in Figure 2.1). If the caller didn't response with a valid choice after 3 attempts, Tropo will redirect to age_fail.json, defined by t.on :event => 'incomplete', :next => '/age_fail.json' (line 23 in Figure 2.1).

The following section of the script extracts the value (line 7 of Figure 2.2), subtracts it from the current year (line 9), subtracts 1 from the resulting value to get the low value of the age range (line 10), adds 1 to get the high value of the range (line 11) and then instructs Tropo to recite the values back to the user (line 12):

post '/your_age.json' do

    t = Tropo::Generator.new

    v = Tropo::Generator.parse request.env["rack.input"].read

    session[:year] = v[:result][:actions][:year][:value].gsub(" ","") unless session[:year]
    today = Date.today
    agecalc = today.year - session[:year].to_i
    lowdate = agecalc - 1
    highdate = agecalc + 1

    t.say "Your age is between #{lowdate} and #{highdate}", {:name => 'test'}
    t.hangup

    t.response
end

Tropo reads off the text to the caller (or sends it as an SMS or an IM) and since there's nothing else to do in the application, Tropo just hangs up. That's it, with only one piece of error handling left in the code. If the caller didn't respond with valid input, however, Tropo would have redirected to the following resource instead:

post '/age_fail.json' do
  
    t = Tropo::Generator.new

    v = Tropo::Generator.parse request.env["rack.input"].read

    t.say "Gotta use numbers!  Please try again."
    t.hangup

    t.response
end

Next Step: Sessions & Tokens




Want to see the JSON Behind the Scenes? It's all right here.

Interested in a more complicated example? Check out the Volunteer Opportunities section of the guide.



  ANNOTATIONS: EXISTING POSTS
0 posts - click the button below to add a note to this page

login
  Quickstart  |  TOC  |  Behind the Scenes JSON - Quick Start Example  

© 2011 Voxeo Corporation  |  Voxeo IVR  |  VoiceXML & CCXML IVR Developer Site