This is the second in a series of tutorial blog posts covering the use of Twilio’s new helper library for node.js. Last time, we introduced you to the basic features and usage of the Twilio module for node. In this tutorial, we will introduce the APIs necessary for using Twilio Client, turning our browser-based node application into a full-fledged soft phone. Stop by next week, when we’ll learn how to secure a node.js web application with two-factor authentication!
The official node.js helper library documentation is located here.
VoIP in the browser with node.js and Twilio Client
However, your application will also need to have code running on a server to generate what’s called a capability token. At a high level, the capability token gives the client (in the browser, or in a native app on a phone) the authority to use your Twilio account (and credits) to make outbound or accept incoming calls.
Wait what? Clients using my app get to spend my Twilio credits to make calls?
Yup, that’s right – which is why you’ll probably want to have code running on a server to determine whether or not you’re okay with that client using your credits (maybe by making sure they’re logged in and you know who they are). You might also want to limit the amount of time the client can connect to the Twilio infrastructure. When you generate a capability token on the server, that token contains all the permissions and limitations you want to grant a particular user. In the browser, the Client SDK will send this token to the Twilio back-end, where we can verify that your account credentials were used to generate it, and determine what powers you have granted to this particular user.
The node.js module provides (along with all our other helper libraries) a simple, high-level API for generating a capability token to give to a client. Let’s take a look at how this is done, and how to both accept and make calls in the browser.
Generating capability tokens for Twilio Client
As we discussed previously, the capability token is used by the Client SDK to tell Twilio’s back end which powers your browser-based client can have (either or both of accepting inbound and making outbound calls). It will also verify that you, the app developer, have “blessed” that client to consume services. The capability token must be signed with your account SID and auth token to allow this verification. This must happen on the server to avoid exposing your account SID and auth token to your users.
There are more moving parts with Twilio Client than with other parts of the SDK, but it’s easy to get started! Let’s do a simple browser phone right now using express, a popular node.js web framework. Open up a command prompt or terminal window and create a new local directory for this exercise, and go to that directory in the terminal.
To use express, go to the terminal and install it via npm – depending on your system configuration, you may need to install the module using “sudo”:
[sudo] npm install express
Additionally, we will install a template engine to render HTML pages from express, called EJS:
[sudo] npm install ejs
Finally, we will need to install the Twilio module:
[sudo] npm install twilio
Now, create a new file called “server.js”. Inside this file, we will use the Twilio helper library to generate an HTML page with contains a capability token. This capability token will allow our browser-based client to accept inbound calls using the ID “kevin” (this could be any string, however). This ID is like the phone number for our VoIP client in the browser – it should be unique for every user of your application. Open “server.js” with your text editor and enter the following code:
This will respond to a GET request to the root path of our web application, and render an HTML template called “index.ejs”. Back in the terminal, create a directory at the same level of “node_modules” and “server.js” called “views” – express will look here for view templates to render. Inside the “views” directory, create a new file called “index.ejs”. Open this file with your text editor and add the following code:
Now, back in the terminal, fire up your express application by running “node server.js”. Your simple VoIP client will now be available at http://localhost:1337/ to accept inbound calls!
But how do I call my browser?
So glad you asked! When we generated our capability token, we gave that browser-based client an ID (“kevin”). Twilio can route calls to that client in a few ways, but let’s see how we would route a call from a standard mobile phone to the browser based client. First, you will need to buy or select a phone number in your Twilio account. Click on a number your control – we are going to configure the “Voice URL” of this number to call our browser-based client.
The Voice URL for this number must point to a TwiML-generating URL out there on the internet. If you’re not familiar with TwiML, it’s a set of XML instructions which tell Twilio how to handle an incoming call or SMS to a given number. For testing purposes, one little utility we use a lot is the “Echo” Twimlet, which just allows us to post static TwiML on the internet and make it available for call routing instructions. Create a new echo Twimlet call using the XML in this Gist:
Which should look like this:
Copy the “Resulting URL” in the Twimlet, and paste it as the “Voice URL” for your Twilio number. Save your changes in the Twilio web UI to have Twilio use this new URL when a phone call is placed to your number.
Back in your terminal, launch your express app with “node server.js” if you haven’t already. Open your web browser to http://localhost:1337/ – then give your Twilio number a call on any phone! If all goes well, you should be hearing your own voice echoed back on your computer speakers.
Congrats – you just turned your browser into a phone!
Making outbound calls from the client
Alright, so we just accepted an inbound call in the browser – let’s also allow our client to make outbound calls. When a Twilio Client device in the browser wants to make an outbound call, Twilio’s back end will need to fetch TwiML that tells it how to behave during that call. That could be calling another phone, connecting to a conference call, or adding them to a queue for voice-based technical support.
Next, we’ll need to update the capability token we generate on the server to enable this client to also make outbound calls using the “allowClientOutgoing” function. The argument to this function is the identifier of a TwiML application, which has a set of callback URLs associated with it to handle inbound voice and SMS calls.
A TwiML application has a few uses – one common use case is to allow a bunch of Twilio phone numbers to use the same Voice and SMS URLs, so you don’t have to copy/paste your server configuration in the website’s UI over and over again. The other use is handling outbound calls for Twilio Client apps.
The Voice URL for a TwiML app is requested when a client tries to make an outbound call. Twilio Client knows which TwiML app to use because when the capability token is generated, it can be generated with the unique identifier of a TwiML app associated with it. Let’s create a TwiML app right now, which will make use of another Twimlet that simply forwards to a given phone number (using a verified caller ID). You can create a TwiML app here. For the voice URL, configure the URL for the Forward Twimlet:
When your app is created, a new unique identifier will be generated for it. We will need this value in our server-side node.js code:
Take this value, and update “server.js” with the following code, replacing “APP_SID” with the unique identifier of the TwiML application we just created:
Restart your node.js server process to pick up the changes we just made (you can kill it with Control-C). Now visit http://localhost:1337/ in your browser, and enter your phone number. You should now have an outbound call routed from the browser!
With very little code, you can add in-browser calling to your node.js webapps, which is great for apps from call centers to online dating sites. We’re very excited to see what the node.js community can build. Please stop by next week, when we will build a web application that is protected using two-factor authentication. See you then!