Creating a simple IVR application with Node.js and FlexIO

There are many voice scenarios that can be implemented using the Visual Designer of Proximus FlexIO, however enterprises can reach full flexibility when directly integrating voice into their applications and business processes. This tutorial will teach you the fundamentals of a programmatic usage of FlexIO by building a simple interactive voice response server (IVR) solution in Node.js.

Step 1 – Node.js

Go to https://nodejs.org/en/download/ and download the most recent stable version of Node.js (LTS).

download node.js

Step 2 – Package.json

This file contains various project-relevant metadata. It is used to provide npm with information that helps it to define the project as well as manage the dependencies of the project.

Npm is distributed with Node.js – which means when you download Node.js, you automatically get npm installed on your computer.

Please do the following from your command-line:

  1. Create a folder called test somewhere on your file system (md test on Windows systems);
  2. Open this test folder (cd test on Windows systems);
  3. Type the following command from your test folder and press [Enter]: npm init.

Tip: Windows command-line can be accessed by typing cmd in the Windows Search or Run line and pressing [Enter].

This will create a package.json file.  You will be prompted to provide some values but most of them could be ignored by pressing [Enter].

Standard parameters are version, package name, description, entry point, test command, git repository, keywords, author and license.

Start your javascript editor (current screenshots were taken from Visual Studio Code but any other editor could be used), search for package.json and open it. Following content will be displayed:

{
  "name": "test",
  "version": "1.0.0",
  "description": "A Node.js RESTful API Tutorial for IVR",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "node",
    "restful",
    "api",
    "ivr"
  ],
  "author": "…",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "express": "^4.17.1"
  }
}

Step 3 – Dependencies (express and body-parser)

The initial package.json won’t contain above dependencies which have to be set first. Please do the following:

Type the following commands from the Terminal pane of your JavaScript editor:

  1. npm install –save express : This will install a set of functionalities to create web applications and services;
  2. npm install –save body-parser : This will parse incoming request bodies in a middleware before your handlers, available under the req.body property.

Step 4 – Server.js

Node.js has a built-in HTTP module that makes it possible to transfer data via HTTP.

To do so, the require() method should be used to include the HTTP module. This module will build an HTTP server that listens to server ports and return a response to the client.

To build an HTTP server method createServer() should be used. The function passed to the http.createServer() method will be executed when someone attempts to access the device on port 3006 (or any other port defined in line const port = process.env.port ||<port number>;).

Please do the following:

  1. Add a file called server.js inside your Node.js project;
  2. Copy following code to it:
const http = require('http');
const app = require('./app');
const port = process.env.port || 3006;
const server = http.createServer(app);
server.listen(port);

Step 5 – App.js

Now a route has to be set up (URL handling code). A route is an Express code segment that associates a HTTP verb (GET, POST, PUT, DELETE, etc.), a path/template URL and a function named to deal with that pattern.

The code first imports the Express application object, uses it to get a Router object and then adds a route to it.  Last line of module exports the Router object.

Please do the following:

  1. Create a file called app.js inside your Node.js project;
  2. Copy following code to it:
const express = require('express');
const app = express();
const indexRoutes = require('./api/routes/index');
app.use('/', indexRoutes);
module.exports = app;

Step 6 – Index.js

Index.js manages the application’s start up, routing and some other features like allowing other modules to add functionalities. It can also act as a simple HTTP web server to run web applications.

The code below first imports an Express application object, then uses it to get an object from the Router. The body-parser object the router uses to decode incoming request bodies available under the req.body property is also imported.

The Router object is last exported by the module.

Using the post() method, two routes are established: ‘/’ and ‘/select’.

The ‘/’ route is defined using the Router.post() method which responds only to HTTP POST requests.  In our case, an incoming phone call.  The first argument to this method is the URL path while the second is a call back function that will be invoked in case an HTTP POST request with this path is received.

The call back takes three arguments (usually named as req, res and next) that will contain the HTTP request object, the response and the next function in the middleware chain.

Important: router functions can be considered as the Express middleware.  This means they must either respond to the request or call the next function in the chain.

The router function takes a single call back, but as many call back “arguments” as needed can be specified (or even an array of call back functions). Each function is part of the middleware chain and will be called in the same order it is added to the chain.

The call back function here calls send() on the response to return when we receive a POST request with path ‘/’.  This will send a request body of type application/xml which content is defined by let rsp.

The content is RCML (REST Communications Mark-up language).  RCML is a data exchange format used by applications to tell Proximus FlexIO how to handle inbound or outbound calls. For more information on RCML please check the official documentation.

Example below provides some basic RCML prompting a user to provide a value when calling a specific number associated to the script (see steps 9 and 10).

The /select inside RCML line <Gather action=\”” + initialpath + “/select” + “\” numDigits=\”1\”> redirects to router.post(‘/select’, (req, res, next) => {} where following business logic is set: the caller will get a confirmation message which key he pressed.

Please do the following:

  1. Create folder \api followed by subfolder \routes in your Node.js project;
  2. Add file index.js;
  3. Copy following code to it:
const express = require('express');
const router = express.Router();

var bodyParser = require('body-parser');
router.use(bodyParser.json());
router.use(bodyParser.urlencoded({ extended: true }));

var initialpath = "";

let rsp = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
    "<Response>\n" +
    "    <Gather action=\"" + initialpath + "/select" + "\" numDigits=\"1\">\n" +
    "        <Say voice=\"man\">Welcome to a nodeJS example.</Say>\n" +
    "        <Say voice=\"man\">To post 1, press 1.</Say>\n" +
    "        <Say voice=\"man\">To post 2, press 2.</Say>\n" +
    "        <Say voice=\"man\">To post 3, press 3.</Say>\n" +
    "    </Gather>\n" +
    "    <Say voice=\"man\">Sorry but this is not what I was expecting.</Say>\n" +
    "</Response>";

router.post('/', (req, res, next) => {
    res.status(200).set('Content-Type', 'application/xml').send(rsp);
});

router.post('/select', (req, res, next) => {
    var id = req.body.Digits;

    switch (id) {
        case '1':
            res.status(200).set('Content-Type', 'application/xml').send('<Response><Say>You selected ' + id + '</Say></Response>');
            break;
        case '2':
            res.status(200).set('Content-Type', 'application/xml').send('<Response><Say>You selected ' + id + '</Say></Response>');
            break;
        case '3':
            res.status(200).set('Content-Type', 'application/xml').send('<Response><Say>You selected ' + id + '</Say></Response>');
            break;
    }
});

module.exports = router;


Step 7 – Initiate server.js

Once above files are ready server.js has to be initiated.  Both web services accessible via post ‘/’ and post ‘/select’ should then be running on a local machine.

Please do the following:

  1. Execute following command in your JavaScript Terminal pane: node server.js;
  2. Press [Enter] : Server.js will start up after few seconds.

Step 8 – Access your application from the internet using Ngrok

Ngrok makes a locally hosted web server appear to be hosted on the internet (Ngrok.com subdomain).  This will make it possible to call the IVR script hosted on our local machine!

Please do the following:

  1. Go to https://ngrok.com/download and download the most recent stable version;
  2. Unzip the package somewhere in your file system and type following command from your command-line: ngrok http –host-header=rewrite 3006.
Download and install Ngrok to allow external network access to your IVR application

Ngrok creates a secure URL to the localhost server and makes both web services accessible through an official URL listening to port specified inside server.js (3006 in this case).

Ngrok status information

Step 9 – FlexIO account

To implement this application you will to have a valid subscription to the Proximus FlexIO service. Once this is done, you will need to have a least one available reserved phone number on the platform. To do so, log on Proximus API Solutions, then open a new browser tab to the Proximus FlexIO Number Management microsite and register a new phone number to your account:

For more information on FlexIO, please check official documentation.

We will then link this new number to your IVR script on the FlexIO platform (see Step 10).

Step 10 – FlexIO platform

This is the place where the link will be made between your server.js instance and the phone number registered in step 9.

Please do the following:

Once your subscription is active and a new number is registered, login to https://proximusflexio.enco.io/#/home using the credentials you received by email when subscribing to this service.

First of all, let’s create a new Voice application named test providing the Ngrok URL generated in Step 8. Select “Applications” from the top menu bar of the FlexIO console, then click on “Create a URL application” and fill in the fields accordingly:

Creating a new application in the FlexIO console

Now let’s assign our new number to this new external application: from the top menu bar of the FlexIO console, select “Numbers”. You will get to the list of phone numbers assigned to your FlexIO account. Click on the number you want to use, and select your “test” application from the application drop down list:

Assigning your FlexIO phone number to your new node.js application

After saving the changes, a link between your FlexIO number and the Node.js script will be established through the secured Ngrok URL. Calling then the associated phone number (+32(2)210.15.32 in current example) should return a response from your Node.js script!

Learnings

As we can understand from this tutorial, integrating voice into your own application is only a matter of supporting an information exchange over HTTP requests between the FlexIO platform and your applications. RCML is a simple data format, easy to understand and to generate, which simplifies the manipulation of your voice calls.

Author: API Solutions Team

Biographical Info