Handle an incoming call with Node.js
Now that you know how to call yourself using the Voice API, learn how to handle incoming calls.
In this guide you will learn:
- How to set up your your Node.js app
- How to start your server
- About callbacks
- How to respond to an incoming voice call
What you need to know before you start
Before you can get started, you need the following already set up:
- Set all Voice API configuration settings.
- NPM and a familiarity with how to install packages.
- Node.js and a familiarity with how to create a new app.
Set up your Node.js application
Create and then navigate to a new folder where you want to store your project. Create a new node app with npm.
npm init
Accept the defaults for the application.
Install your dependencies
We will be using Express to create a lightweight webserver that will listen for requests from the Sinch servers to handle incoming calls. Because the webserver is running on your local machine, you will also need a method for making the server accessible over the internet. In this guide we'll be using ngrok to do that, but if you have another way you'd prefer to do it, feel free to use that. Additionally, we'll be using the node-fetch package to make HTTP requests.
Use the following command to install the Express, ngrok, and node-fetch packages:
npm install express ngrok node-fetch
Create your file
In your project folder, create a new file named index.js in the project and paste the provided "index.js" code into the file.
index.js
This file is used to start a lightweight webserver to handle incoming calls.
import fetch from 'node-fetch'
const express = require('express');
const PORT = 3000;
const ngrok = require('ngrok');
const app = express();
app.use(express.json());
app.post('/incoming-call', async (req, res) => {
let svamlResponse;
svamlResponse = {
instructions: [
{
name: 'say',
text: 'Hi, thank you for calling your Sinch number. Congratulations! You just responded to a phone call.',
local: 'en-US'
}
],
action: {
name: 'hangup'
}
};
res.json(svamlResponse);
});
app.listen(PORT, async () => {
const url = await ngrok.connect(PORT);
console.log(`Node.js local server is publicly-accessible at ${url}/incoming-call`);
await updateUrl(url + '/incoming-call');
console.log("Your callbackURL has been updated on your dashboard.")
console.log(`Listening at http://localhost:` + PORT);
});
async function updateUrl(callbackUrl) {
const applicationKey = 'applicationKey';
const applicationSecret = 'applicationSecret';
const resp = await fetch(
`https://callingapi.sinch.com/v1/configuration/callbacks/applications/${applicationKey}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Basic ' + Buffer.from(`${applicationKey}:${applicationSecret}`).toString('base64')
},
body: {
url: [
{
primary: callbackUrl
}
]
}
}
);
const data = await resp.json();
console.log(data);
}
This code starts your webserver, creates an ngrok tunnel, updates your callback URL, and also contains the logic to respond to incoming callbacks from the Sinch servers. We'll come back to what those things are in a moment.
Before you save your file and start your server, there's a couple of values you to need to update.
Update your parameter values
Update the values of the following parameters:
Parameter | Your value |
---|---|
applicationKey | The key found on your Sinch dashboard. |
applicationSecret | The secret found on your Sinch dashboard. |
Start your server
At this point, you can start your server with the following command:
node index.js
You should notice a few things.
- First, your console should show that the server has started on port 3000 of your localhost.
- Second, the ngrok tunnel has started and you should see the URL displayed in the console.
- Additionally, you should see a message in your console that the callback URL was updated automatically. There is code in the sample that makes a request to the Voice API to update the callback URL.
Tip:
You can also update your callback URL in the dashboard yourself. Navigate to your app on your dashboard. Under the Settings section, you'll see a field labeled "Callback URL." Enter your URL into that field and click Save.
Now your server is listening and your callback URL is configured, so you're almost ready to test everything and make a phone call. But before we do, let's take a closer look at callbacks. If you already know about callbacks, skip right to calling your Sinch phone number.
Understanding callbacks
Callbacks (also known as "webhooks") are the method that the Voice API uses to figure out what you want to do with a call. Basically, a callback is a request that the Sinch servers send to your server whenever something happens (otherwise known as an "event") in the call that requires some input from you. There are a few different types of events, but the two we are concerned about for this guide are the Incoming Call Event and the Disconnected Call Event.
An Incoming Call Event happens whenever someone calls one of your Sinch numbers. In essence, someone dials your number and so Sinch servers reach out to you and say "how do you want me to handle this call?"
Most callback events expect a response, depending on the event. The Incoming Call Event expects to receive back a SVAML object in response. You can read more about SVAML here, but just know that SVAML is a markup language Sinch developed to control calls.
The below diagram demonstrates exactly what's happening:
- Someone dials your Sinch number from a handset.
- The Sinch servers create an ICE and send a POST request to your server.
- Your server listens for the request and sends back a SVAML response to tell the Sinch server how to handle the call.
In this sample application, this is the SVAML object that you will use to respond to the callback:
{
"instructions": [
{
"name": "say",
"text": "Hi, thank you for calling your Sinch number. Congratulations! You just responded to a phone call.",
"local": "en-US"
}
],
"action": {
"name": "hangup"
}
}
This SVAML object has two parts: instructions and an action. Instructions are things you want to be done on the call without changing the state of the call. In this case, we want to play a voice that reads out a text message. Actions are things you want to be done to the call to change its state in some way. In this case, we want to hang up and end the call.
And that's it! Now we can test.
Call your Sinch phone number
Look up the free Sinch number assigned to your app and call it using your phone. The call should be picked up by the Sinch servers and you should hear the text from the instruction. Now you know how to handle an incoming call.
Next steps
Learn more about the Voice API: