A simple masked number example using both Voice and Messaging as well as Node.JS and Express
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
db
models
node_modules
routes
.DS_Store
.gitignore
README.md
package-lock.json
server.js

README.md

Simple Masked Numbers Examples Using Node.JS and Express

A simple masked number example using both Voice and Messaging as well as Node.JS and Express.

Table of Contents

Prereqs

How It Works

This apps masks both the to and from numbers of calls and messages, and routes calls and messages through Bandwidth numbers.

Prep

Make sure you have at least one Bandwidth number registered to your app.bandwidth.com account and that it is set up to receive both Message and Voice callbacks. Be sure that your Application is set to auto-answer. You will also need a Heroku account with JawsDB MySQL installed as an add-on.

Set Up Your MySQL Database

For number masking to work, the masking number is stored in some kind of database with the two numbers it connects stored along with it. There are many ways to do it, but for this example, we are using MySQL.

You can use software like MySQL Workbench to make setting up your database very simple.

The database schema is as follows:

CREATE TABLE masks (
    maskingNum VARCHAR(16) NOT NULL,
    num1 VARCHAR(16) NOT NULL,
    num2 VARCHAR(16) NOT NULL,
    PRIMARY KEY (maskingNum)
);

And to add a masking number and two numbers it connects to the database is as follows:

INSERT INTO masks(maskingNum, num1, num2) VALUES ("{{MASKING_NUM}}", "{{NUM1}}", "{{NUM2}}");

Set Up Server.js

Server.js should look as follows:

//requirements
const express = require("express");
const bodyParser = require("body-parser");
const path = require("path");

//initialize app
const app = express();
const port = process.env.PORT || 3000;

app.use(bodyParser.urlencoded({ extended: false }));

app.use(bodyParser.json());

app.use(express.static(path.join(__dirname, "/public")));

require("./routes/routes.js")(app);

//listen
app.listen(port, function() {
    console.log("App listening on PORT " + port);
});

Set Up Requirements in Routes.js

const bandwidth = require("node-bandwidth");
const mysql     = require("mysql");

Initialize Bandwidth Client

These credentials can be found under the Account tab at app.bandwidth.com.

const client = new bandwidth({
    userId    : "{{USER_ID}}",
    apiToken  : "{{TOKEN}}",
    apiSecret : "{{SECRET}}"
});

Initialize MySQL Connection

These credentials are provided by JawsDB MySQL on Heroku.

const connection = mysql.createConnection({
    host     : "{{JAWSDB_HOST}}",
    user     : "{{JAWSDB_USER}}",
    password : "{{JAWSDB_PASSWORD}}",
    database : "{{JAWSDB_DB}}"
  });
   
connection.connect();

Create Routes That Forward Messages and Calls through the Masking Number Using Callbacks

The /messageCallback route queries the MySQL database for the masking number and forward the message to whichever endpoint number the message did not originate from. The voiceCallback routes does the same thing, but for a call rather than a message.

module.exports = app => {

    //listen for callbacks
    app.post("/messageCallback", (req, res) => {
        if (req.body.eventType == "sms") {
            connection.query("SELECT * FROM masks WHERE maskingNum = " + req.body.to, (error, results, field) => {
                if (results[0].num1 == req.body.from) {
                    client.Message.send({
                        from    : req.body.to,
                        to      : results[0].num2,
                        text    : req.body.text
                    }).then(() => {
                        res.end();
                    });
                } else if (results[0].num2 == req.body.from) {
                    client.Message.send({
                        from    : req.body.to,
                        to      : results[0].num1,
                        text    : req.body.text
                    }).then(() => {
                        res.end();
                    });
                } 
            });
        }
    });

    app.post("/voiceCallback", (req, res) => {
        if (req.body.eventType == "answer") {
            connection.query("SELECT * FROM masks WHERE maskingNum = " + req.body.to, (error, results, field) => {
                if (results[0].num1 == req.body.from) {
                    client.Call.transfer(req.body.callId, {
                        transferTo      : results[0].num2,
                        transferCallerId: req.body.to
                    }).then(() => {
                        res.end();
                    });
                } else if (results[0].num2 == req.body.from) {
                    client.Call.transfer(req.body.callId, {
                        transferTo: results[0].num1,
                        transferCallerId: req.body.to
                    }).then(() => {
                        res.end();
                    });
                } 
            });
        }
    });
}

Deploy

You can now deploy your masking number app to Heroku. Click the button below for more information.

Deploy