Tropo WebAPI Development Guide Home  |  Frameset Home

  Behind the Scenes JSON - Favorite Movie Trilogy  |  TOC  |  Behind the Scenes JSON - Recording Example  

Node.js - Voice Recording Example


This example application is written in JavaScript and uses Node and Express for the web server and framework. You will need all three installed on your web server in order for this to work, as well as our Node.js WebAPI Library.

Once everything is installed, you'll need to have the example script saved in the /samples sub folder of the project directory (the directory that also contains the lib and tests folders from the WebAPI library download; by default, this is named tropo-webapi-node, but it can be renamed however you want). You can download a complete copy of the script from our Github; we'll break it up into pieces in this tutorial to make it easier to follow.

The app is specifically built for the voice channel, but that doesn't mean someone won't decide to be a rebel and text your application, just to do it. We added a section to the code that detects the channel from the initial session JSON and changes the application's behavior accordingly.

In Figure 9.0, we start everything off requiring both the WebAPI Node library and Express (lines 6 and 7), then use Express to create the web server (line 8). We then set the script to use bodyParser so we can work with the session object (line 16):

/**
 * Showing with the Express framework http://expressjs.com/
 * Express must be installed for this sample to work
 */

require('../lib/tropo-webapi.js');
var express = require('express');
var app = express.createServer();

/**
 * Required to process the HTTP body
 * req.body has the Object while req.rawBody has the JSON string
 */

app.configure(function(){
    app.use(express.bodyParser());
});

Next, we define what the application will actually do. Line 1 of Figure 9.1 corresponds to our URL in the Tropo UI (check out Creating Your First App for more information on defining URLs); because it's defined as '/', this resource will be used when the base URL is passed to the server, making it essentially our start point. We then create a new instance of the TropoWebAPI object (line 3) and start into the logic:

app.post('/', function(req, res){
    // Create a new instance of the TropoWebAPI object.
    var tropo = new TropoWebAPI();
    if(req.body['session']['from']['channel'] == "TEXT") {
        tropo.say("This application is voice only.  Please call in using a regular phone, SIP phone or via Skype.");
        
        tropo.on("continue", null, null, true);
        
        res.send(TropoJSON(tropo));
    }

As mentioned earlier, we need the application to respond differently depending on the channel, so we start with an if statement that pulls the channel out of the session object (line 4 of Figure 9.1). If the channel is TEXT, the application will respond with "This application is voice only. Please call in using a regular phone, SIP phone or via Skype" (line 5). If the channel isn't TEXT (which only leaves VOICE), then it moves on to the meat of the application (Figure 9.2):

    // Use the say method https://www.tropo.com/docs/webapi/say.htm
    else {

    tropo.say("Welcome to my Tropo Web API node demo.");
    
    // Demonstrates how to use the base Tropo action classes.
    var say = new Say("Please ree cord your message after the beep.");
    var choices = new Choices(null, null, "#");

    // Action classes can be passed as parameters to TropoWebAPI class methods.
    // use the record method https://www.tropo.com/docs/webapi/record.htm
    tropo.record(3, false, null, choices, audio/wav, 5, 60, null, null, "recording", null, say, 5, null, "http://example.com/tropo", null, null);

    // use the on method https://www.tropo.com/docs/webapi/on.htm
    tropo.on("continue", null, "/answer", true);

    tropo.on("incomplete", null, "/timeout", true);
    
    tropo.on("error", null, "/error", true);

    res.send(TropoJSON(tropo));
}});

Line 4 of Figure 9.2 kicks off the initial welcome prompt, then lines 7 and 8 define a couple of parameters for the following record object (line 12). In record, you'll see several parameters defined - these correspond to those defined for the record object in the tropo-webapi.js file we required at the beginning of the script. Here's the relevant portion, to make it easier to understand what values are associated with which parameters:

TropoWebAPI.prototype.record = function(attempts, bargein, beep, choices, format, maxSilence, maxTime, method, minConfidence, name, required, say, timeout, transcription, url, password, username)

In the record object, you'll see several null values. These tell Tropo to use the default defined for the parameter; you can find the defaults by checking out the record page on the Tropo website.

The record object will read out the prompt defined as the say variable (line 7 of Figure 9.2), beep to let the user know when to start talking, accept the # key as the terminator (defined in the choices variable on line 8 of Figure 9.2), then send the file to http://example.com/tropo as recordings.wav (the default format is wav, if you wanted to overwrite it, you could define the format as 'audio/mp3').

If the recording was successful - the website was accessible and accepted the recording, the user didn't hangup before the beep - then the app will move on to the /answer resource (defined by line 15 of Figure 9.2, shown in Figure 9.3):

app.post('/answer', function(req, res){
    // Create a new instance of the TropoWebAPI object.
    var tropo = new TropoWebAPI();
    tropo.say("Recording successfully saved.  Thank you!");

    res.send(TropoJSON(tropo));
});

This resource just tells the user the recording was successfully saved and hangs up. If the user failed to say anything three times (defined by the value set for the attempts parameter in record. On line 12 of Figure 9.2, the first value after record is 3, which corresponds to attempts), then the application will fire the incomplete event and move on to the /timeout resource (defined by line 17 of Figure 9.2, shown in Figure 9.4):

app.post('/timeout', function(req, res){
    var tropo = new TropoWebAPI();
    tropo.say("Sorry, I didn't hear anything.  Please call back and try again.");

    res.send(TropoJSON(tropo));
});

If Tropo receives an error back when it attempts to communicate with your server, such as an http code other than 200 (like a 404) - then the application will move on to the /error resource:

app.post('/error', function(req, res){
    // Create a new instance of the TropoWebAPI object.
    var tropo = new TropoWebAPI();
    tropo.say("Recording failed.  Please call back and try again.");

    res.send(TropoJSON(tropo));
});

This last part of the application is related to the launching of web server itself. In the beginning of the example, we mentioned you should have the example script in the samples sub-directory of the tropo-webapi-node folder; with the file in the correct location, you would launch the application on your server by first opening your command prompt, then switch into the project directory, and then type:

node samples/nodeScript.js

The name of the file doesn't have to be nodeScript.js, you can name it whatever you prefer.

If the server starts properly, you should get this message in the console:

Server running on port:8000

That message and the port number the web server is set to use are both defined by the final portion of the script (it doesn't need to be port 8000, but it's likely to be available):

app.listen(8000);
console.log('Server running on port :8000');

If you do get the message defined by console.log, then the application is successfully running and can now be accessed by Tropo. Give it a call (or a text) and test it out!


Next Step: Developer Examples




If you're interested in the Behind the Scenes JSON, check out this page to see the exchanges:

This blogpost may also be useful:

http://blog.tropo.com/2010/10/01/use-node-js-javascript-to-write-your-tropo-apps/



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

login
  Behind the Scenes JSON - Favorite Movie Trilogy  |  TOC  |  Behind the Scenes JSON - Recording Example  

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