Skip to content

The high level interface

geuis edited this page Aug 12, 2011 · 7 revisions

node-twilio High-Level REST Interface

Introduction and Explanation (Yes, an Explanation is Required)

The Old Way, The Slow Way, The Boring Way

Typically when developing a Twilio application, there is an ugly and confusing separation between the response handlers and the requests sent to Twilio's REST API to, well, make your application go. Here's an example of what I mean, borrowed from the Python Twilio helper library:

# Instrantiate a Twilio REST account object
account = twilio.Account(SID, AUTH_TOKEN);

# Call my parents
req_data = {
    'From': MY_CALLER_ID,
    'To': '905-892-6737',
    'Url': 'http://hostname/path/to/my/love/filled/parental/greeting'
}
print account.request('/2010-04-01/Accounts/%s/Calls' % \
    ACCOUNT_SID, 'POST', req_data)

Now, all the above does is make the HTTP POST request to the Twilio resource /API_VERSION/Accounts/ACCOUNT_SID/Calls. The variable req_data contains the information about the actual call to be made, and within, it contains a Url parameter. This is the URL that Twilio will request once the call is answered. The response to Twilio's request, that is, whatever is at http://hostname/path/to/my/love/filled/parental/greeting, is what will instruct Twilio to do stuff with the call, in Twiml.

But, see, the actual provisioning of the aforementioned URL happens somewhere else entirely. Perhaps you've got Apache running and you have a directory in there called 'twilio-requests', and inside that is a bunch of static files that contain various greetings you may want to give to different people your Twilio app is contacting. Or maybe they aren't static; maybe they're PHP files that read information from Twilio's request's POST variables, and you respond differently based on any of the parameters therein. The point is, the actual creation of the call and what to do when the call answered are separated completely; To find out what you're actually instructing Twilio to do when you initiate that call, you have to find out where your webserver's hosted files are, you have to futz about with its configuration, maybe, or maybe you don't even have a webserver running yet, and you just want to build a Twilio app without messing with nginx.conf or whatever, and worst of all, you don't have right in front of you what you're going to respond with while you're writing the code. That sucks.

The New Way, The Fast Way, The Better Way

Wouldn't it be great if you could instantiate a call, and then right after you've written the line of code that makes the call start, begin to write out what happens when the call is answered? Boy, howdy!

But, how? Well, what if we made some sort of OutgoingCall object, and that object was smart enough to run a webserver transparently, and then it was able to make up some URLs whenever you needed them, and tell Twilio about those as it's telling Twilio about the call you want to make, and then when Twilio makes the call and goes and requests those URLs, the OutgoingCall object would fire an Event to let you know? We don't have to wonder 'What If', because truly I tell you, today this is a real possibility.

Basics

To start, you'll need to instantiate a node-twilio object.

First, you are required to require:

var TwilioClient = require('twilio').Client,
      Twiml = require('twilio').Twiml,
      sys = require('sys');

Next, you must instantiate a TwilioClient object:

var client = new TwilioClient('MY_ACCOUNT_SID', 'MY_AUTH_TOKEN', 'MY_HOSTNAME');

Hey, that was easy! So, what good is this client thing? Can it, say, create for me a PhoneNumber object with which I can do useful, potentially profitable, things? You bet!

var phone = client.getPhoneNumber('+16067777777');

Hey, cool! You should note that getPhoneNumber is a function that returns a new PhoneNumber object. It accepts a string parameter. This may either be a string representation of a phone number that has already been provisioned within your Twilio account, or the SID of such a phone number. (See The Lower-Level REST Interface for how to go about finding and provisioning phone numbers.)

That's pretty great, how, can I make a call to my parents with this phone number? You bet! But first, you have to call the PhoneNumber object's setup() method. This method makes a request to Twilio's REST API to find out some details about the number you provided. It also provisions a couple of URIs behind-the-scenes, and then instructs Twilio to use those URIs for the incoming voice and incoming SMS status callbacks such that it can begin to emit events for 'incomingCall' and 'incomingSms', and then once it's done with all that setup, it calls a callback function with no parameters. After that, you're ready to make a phone call with the PhoneNumber object's makeCall method. Let's see how that's done:

phone.setup(function() { phone.makeCall('+19058926737', null, function(call) {});

Pretty cool, hey? The makeCall method accepts three paremeters: The phone number to dial (substitute YOUR parents number there--you don't want to be calling my parents, do you? Or maybe you do--that's cool too! They like to talk about movies and politics, in case you want to be prepared with some conversational starter points), a map of options (described below in the method-by-method documentation), and a callback function.

The callback function is called when the REST request to instantiate the call has been sent, but the call has not yet been initiated. The argument to the callback is an OutgoingCall object. This object is an EventEmitter, and it emits two events: 'answered', and 'ended'. So you can listen for those events, and then respond to them appropriately (or inappropriately, if you're certain the callee can stomach it, and you're doubly-certain the callee isn't my parents). Let's try listening for the answered event and maybe tell my parents something nice:

phone.setup(function() {
    phone.makeCall('+19058926737', null, function(call) {
        call.on('answered', function(callParams, response) {
            response.append(new Twiml.Say('Howdy mom and or dad! I hope you are well! I know you know your son loves you!'));
            response.send();
        });
    });
});

The 'answered' event handler accepts two arguments: callParams and response. callParams is a map of Twilio's request's POST variables. For outgoing calls, when Twilio requests your handler URI, it contains stuff like CallSid (the SID that identifies this call), and CallStatus, and many other stuff. Check out Twilio's Request documentation for more details.

The response argument of the answered event is a Twiml.Response object. This object is responseible (ay-oh!) for helping you easily generate valid TwiML responses and then sending them on their way to Twilio. See The TwiML Interface for more details.

See how great that was? You can instantiate the call and generate your response to it all in the same spot! And you don't have to worry about provisioning a webserver and all that tiresome nonsense, and further, when you go to debug, everything to do with the call is right there on the screen in front of you, not spread throughout your filesystem! Pretty cool!

Object Documentation

The TwilioClient object

Instantiation

var TwilioClient = require('twilio/client');

var client = new TwilioClient(sid, authToken, hostname, opts);

sid: Your Twilio account SID

authToken: Your Twilio account authToken

hostname: The hostname (or ip) of the server running your app

opts: Optional parameters. opts.port: The port which Node-Twilio will start a webserver to accept incoming Twilio requests. Default: 31337 opts.basePath: The base path with which Node-Twilio will construct URIs for provisioning with Twilio. Default: 'autoprovision'.

Note: If left to default, the URLs Node-Twilio generates will be of the form http://hostname/autoprovision/:n where n is an integer

Object Methods

getPhoneNumber
TwilioClient.getPhoneNumber(num);

Create a new PhoneNumber object.

num may be either a phone number of the form +19054451795 or a Twilio phone number SID. num must be a number or SID associated with your account.

See the PhoneNumber object documentation below.

Note

The TwilioClient object also contains all of the low-level REST API wrapper methods. The getPhoneNumber method (as well as the PhoneNumber and OutgoingCall objects) wrap the low-level REST API methods, however, they are still available as object methods of the TwilioClient object. See The Lower-Level REST interface for more information.

The PhoneNumber object

Represents a Twilio phone number.

Methods

setup

The setup method requests the phone number instance resource from Twilio and populates a data structure with the phone number's details. Additionally, the setup method provisions three URLs and updates the phone number resource to use those URLs for the SmsUrl, VoiceUrl, and StatusCallback URLs. As soon as setup completes, it begins listening for requests to those URLs and emits events upon request.

PhoneNumber.setup(fn);

fn: Callback function called on setup completion.

Events

incomingSms

This event is fired when Twilio requests the SmsUrl provisioned during setup, which happens when an SMS is sent to your number.

phoneNumber.on('incomingSms', function(smsParams, response) {
    // smsParams is the body of Twilio's request
    // response is a Twiml.Response object
});
incomingCall

This event is fired when Twilio requests the VoiceUrl provisioned during setup, which happens when somebody calls your phone number.

phoneNumber.on('incomingCall', function(callParams, response) {
    // callParams is the body of Twilio's request
    // response is a Twiml.Response object
});
callStatus

This event is fired when Twilio requests the StatusCallback URL provisioned during setup, which happens when a call completes.

phoneNumber.on('callStatus', function(callParams, response) { ... }

The OutgoingCall object

The OutgoingSms object