Skip to contentSkip to navigationSkip to topbar
On this page

Respond to Incoming Phone Calls in Node.js


In this guide, we'll show you how to use Programmable Voice(link takes you to an external page) to respond to incoming phone calls in your Node.js web application. Code on your server can decide what a caller hears when they dial the number you've bought or ported to Twilio. The code snippets in this guide are written using modern JavaScript language features in Node.js version 6 or higher, and make use of the following modules:

Let's get started!


Respond to incoming calls in your web application

respond-to-incoming-calls-in-your-web-application page anchor
Incoming Voice.

When a Twilio phone number receives an incoming call, Twilio will send an HTTP request to your web application, asking for instructions on how to handle the call. Your web application will respond with an XML document containing TwiML. That TwiML contains the instruction that Twilio will follow to say some arbitrary text, play an MP3 file, make a recording and much more.

To start answering phone calls, you must:

(warning)

Warning

If you are sending SMS messages to the U.S. or Canada, before proceeding further, be aware of updated restrictions on the use of Toll-Free numbers for messaging, including TF numbers obtained by purchasing them. These restrictions do not apply to Voice or other uses outside of SMS messaging. See this support article(link takes you to an external page) for details.


Buy and configure a phone number

buy-and-configure-a-phone-number page anchor

In the Twilio Console, you can search for and buy phone numbers in countries around the world. Numbers that have the Voice capability can make and receive voice phone calls from just about anywhere on the planet.

Search for voice capable numbers.

Once you purchase a number, you'll need to configure that number to send a request to your web application. This callback mechanism is called a webhook(link takes you to an external page). This can be done in the number's configuration page.

configure an incoming phone number URL.

Webhooks are user-defined HTTP(link takes you to an external page) callbacks. They are usually triggered by some event, such as receiving an SMS message or an incoming phone call. When that event occurs, Twilio makes an HTTP request (usually a POST or a GET(link takes you to an external page)) to the URL configured for the webhook.

To handle a webhook, you only need to build a small web application that can accept the HTTP requests. Almost all server-side programming languages offer some framework for you to do this. Examples across languages include ASP.NET MVC(link takes you to an external page) for C#, Servlets(link takes you to an external page) and Spark(link takes you to an external page) for Java, Express(link takes you to an external page) for Node.js, Django(link takes you to an external page) and Flask(link takes you to an external page) for Python, and Rails(link takes you to an external page) and Sinatra(link takes you to an external page) for Ruby. PHP(link takes you to an external page) has its own web app framework built in, although frameworks like Laravel(link takes you to an external page), Symfony(link takes you to an external page) and Yii(link takes you to an external page) are also popular.

Whichever framework and language you choose, webhooks function the same for every Twilio application. They will make an HTTP request to a URI that you provide to Twilio. Your application performs whatever logic you feel necessary - read/write from a database, integrate with another API or perform some computation - then replies to Twilio with a TwiML response with the instructions you want Twilio to perform.

What is TwiML?

what-is-twiml page anchor

TwiML is the Twilio Markup Language, which is just to say that it's an XML(link takes you to an external page) document with special tags defined by Twilio to help you build your SMS and voice applications. TwiML is easier shown than explained. Here's some TwiML you might use to respond to an incoming phone call:

1
<?xml version="1.0" encoding="UTF-8"?>
2
<Response>
3
<Say>Thanks for calling!</Say>
4
</Response>

And here's some TwiML you might use to respond to an incoming SMS message:

1
<?xml version="1.0" encoding="UTF-8"?>
2
<Response>
3
<Message>We got your message, thank you!</Message>
4
</Response>

Every TwiML document will have the root <Response> element and within that can contain one or more verbs. Verbs are actions you'd like Twilio to take, such as <Say> a greeting to a caller, or send an SMS <Message> in reply to an incoming message. For a full reference on everything you can do with TwiML, refer to our TwiML API Reference.


Write node.js code to handle the incoming phone call

write-nodejs-code-to-handle-the-incoming-phone-call page anchor

Now comes the fun part - writing code that will handle an incoming HTTP request from Twilio! Our code will dictate what happens when our phone number receives a call by responding with TwiML.

Respond to an incoming call with TwiMLLink to code sample: Respond to an incoming call with TwiML
1
const express = require('express');
2
const VoiceResponse = require('twilio').twiml.VoiceResponse;
3
4
const app = express();
5
6
// Create a route that will handle Twilio webhook requests, sent as an
7
// HTTP POST to /voice in our application
8
app.post('/voice', (request, response) => {
9
// Use the Twilio Node.js SDK to build an XML response
10
const twiml = new VoiceResponse();
11
twiml.say('Hello world!');
12
13
// Render the response as XML in reply to the webhook request
14
response.type('text/xml');
15
response.send(twiml.toString());
16
});
17
18
// Create an HTTP server and listen for requests on port 3000
19
app.listen(3000, () => {
20
console.log(
21
'Now listening on port 3000. ' +
22
'Be sure to restart when you make code changes!'
23
);
24
});

The TwiML generated by our server code

the-twiml-generated-by-our-server-code page anchor

The Helper Libraries help you generate an XML string that looks like this.

1
<?xml version="1.0" encoding="UTF-8"?>
2
<Response>
3
<Say>Hello world!</Say>
4
</Response>

In order for the webhooks in this code sample to work, Twilio must be able to send your web application an HTTP request over the Internet. Of course, that means your application needs to have a URL or IP address that Twilio can reach.

In production you probably have a public URL, but you probably don't during development. That's where ngrok(link takes you to an external page) comes in. ngrok gives you a public URL for a local port on your development machine, which you can use to configure your Twilio webhooks as described above.

Once ngrok is installed, you can use it at the command line to create a tunnel to whatever port your web application is running on. For example, this will create a public URL for a web application listening on port 3000.

ngrok http 3000

After executing that command, you will see that ngrok has given your application a public URL that you can use in your webhook configuration in the Twilio console.

ngrok screen.

Grab your ngrok public URL and head back to the phone number you configured earlier. Now let's switch it from using a TwiML Bin to use your new ngrok URL. Don't forget to append the URL path to your actual TwiML logic! ("http://<your ngrok subdomain>.ngrok.io/voice" for example)

configure an incoming phone number URL.

Create node.js responses to incoming phone calls

create-nodejs-responses-to-incoming-phone-calls page anchor

In the example above, we returned pre-defined TwiML in response to the incoming call. The real power of using webhooks like this is executing dynamic code (based on the information Twilio sends to your application) to change what you present to the user on the other end of the phone call. You could query your database, reference a customer's phone number in your CRM, or execute any kind of custom logic before determining how to respond to your user.

Create a dynamic response to an incoming callLink to code sample: Create a dynamic response to an incoming call
1
const express = require('express');
2
const VoiceResponse = require('twilio').twiml.VoiceResponse;
3
const urlencoded = require('body-parser').urlencoded;
4
5
const app = express();
6
7
// Parse incoming POST params with Express middleware
8
app.use(urlencoded({ extended: false }));
9
10
// Create a route that will handle Twilio webhook requests, sent as an
11
// HTTP POST to /voice in our application
12
app.post('/voice', (request, response) => {
13
// Get information about the incoming call, like the city associated
14
// with the phone number (if Twilio can discover it)
15
const city = request.body.FromCity;
16
17
// Use the Twilio Node.js SDK to build an XML response
18
const twiml = new VoiceResponse();
19
twiml.say(`Never gonna give you up ${city}.`);
20
twiml.play({}, 'https://demo.twilio.com/docs/classic.mp3');
21
22
// Render the response as XML in reply to the webhook request
23
response.type('text/xml');
24
response.send(twiml.toString());
25
});
26
27
// Create an HTTP server and listen for requests on port 3000
28
app.listen(3000);
(warning)

Protect your webhooks

Twilio supports HTTP Basic and Digest Authentication. Authentication allows you to password protect your TwiML URLs on your web server so that only you and Twilio can access them.

Learn more about HTTP authentication here, and check out our full guide to securing your Express application by validating incoming Twilio requests.


If this guide was helpful, you might also want to check out these tutorials for Programmable Voice and Node.js. Tutorials walk through full sample applications, implementing Twilio use cases like these:

Happy hacking!

Need some help?

Terms of service

Copyright © 2024 Twilio Inc.