Telestax Blog

SmartDispatch – How I Became a Rockstar at TADHack (Part 2)

Part 1 of this series which introduces the SmartDispatch application is available here.

Assuming you’ve read part 1, you now know what SmartDispatch is and what is it for. So let’s dive into the code! Below, I’ve created a simple diagram that explains how the app works.diagram


  1. User lands on webpage and authenticates using LinkedIn
  2. Webpage launches LinkedIn authentication and retrieves the user info to store in context variable
  3. Webpage uses location info from user to query Agent API based on user location
  4. SIP call to RestcommONE instance with context header passed
  5. RestcommONE directs call to Agent’s SIP client, records call, and sends information gathered to agent on hangup

Here is how the different parts are built:

1. Setting up the Dashboard & API

The dashboard serves as a way for the user to configure his agents with relevant information. It also acts as an API for the WebRTC Call client to consult to know which agent it should call based on the contextual information. I set up the dashboard and API using NodeJS. Just a few routes are needed:

A. Create user

This route is essentially to create the agent based on the appropriate data format.
/* POST to Add User Service */'/adduser', function(req, res) {

    // Set our internal DB variable
    var db = req.db;

    // Get our form values. These rely on the "name" attributes
    var userFirstName = req.body.firstname;
    var userLastName = req.body.lastname;
    var userSegment = req.body.segment;
    var userPhone = req.body.number;
    var userDid = req.body.did;
    var userEmail =;

    // Set our collection
    var collection = db.get('usercollection');

    // Submit to the DB
        "firstname" : userFirstName,
        "lastname" : userLastName,
        "segment" : userSegment,
        "number" : userPhone,
        "did" : userDid,
        "email" : userEmail

    }, function (err, doc) {
        if (err) {
            // If it failed, return error
            res.send("There was a problem adding the information to the database.");
        else {
            // If it worked, set the header so the address bar doesn't still say /adduser
            // And forward to success page

B. Display user (JSON API)

This route essentially accepts a URL-encoded parameter (segment) and searches the database based on the segment passed.
router.get('/userlist:location', function(req, res) {
    var db = req.db;
    var urlParts = url.parse(req.url, true, true);
    var pathname = urlParts.pathname;
    var location = pathname.slice(10);
    var collection = db.get('usercollection');
    collection.findOne({location: location},function(e,docs){
            "userlist" : docs
For instance, the WebRTC Call Client will send and will receive the information returned from the agent database/API for the first available Belgian agent. Example:

C. Other routes

You can also include other routes such as displaying the /dashboard, remove users, modifying users, etc. My dashboard looks like:


dashboard (1)

2. Setting up the WebRTC Call Client

Again, I used NodeJS and here only a few routes and functions are needed:

A. Authenticate with Linkedin, I use passport for that (more info here)

Don’t forget to set the appropriate permissions in order to access all the profile info you will need. I used:
scope: ['r_emailaddress', 'r_basicprofile', 'r_contactinfo’],
profileFields: ['id', 'first-name', 'last-name', 'email-address', 'headline', 'phone-numbers', 'location', 'positions']

Then you can set all your context variables to the profile info like so:

var showprofile = profile,
    displayName = + ' ' +,
    phoneNumber = profile._json.phoneNumbers.values[0].phoneNumber,
    location =,
    email = profile._json.emailAddress,
    position = profile._json.positions.values[0].title,
    company = profile._json.positions.values[0];

B. Set up the getData() function called when authentication is done:

function  getData(location){
        request(""+location, function(error, response, body) {
        body = JSON.parse(body);
        var did = body.userlist.did;
        var agentNumber = body.userlist.number;
        var agentEmail =;
This function sets your context information (agent phone number, DID to call through the WebRTC SDK, and agent email to send the summary to) by passing the location detected from the authenticated LinkedIn user

C. Set up the Voxbone WebRTC-SIP SDK to call

Here’s where you can download the Voxbone WebRTC-SIP SDK which will link the browser to the RestcommONE instance’s IP.
In your init() function, you can now pass all the data taken from LinkedIn and the userlist API to build a context variable:
 var context = {'clientName': userName, 'clientPhone': userPhone, 'agentNum': agentNum, 'userEmailAddress': userEmailAddress, 'userPos': userPos, 'userCo': userCo, 'userLoc': userLoc, 'pageurl': pageurl, 'agentEmailAddress': agentEmailAddress}
You can then set all parameters of the SIP call that are passed to RestcommONE:
//Caller ID
 voxbone.WebRTC.configuration.uri =  userPhone + "";
//Display Name
 voxbone.WebRTC.configuration.display_name = userName;
//Context info
voxbone.WebRTC.context = JSON.stringify(context);
//And finally call the right agent’s SIP URI;

3. Setting up RestcommONE 

Now that you can send a call with context using a Voxbone phone number to a SIP URI, just link the phone number to your RestcommONE’s instance URI (How to configure SIP URI with Voxbone). Here’s what my RestcommONE App look like:
Module 1 receives the call echoes the context header to a REST service (see 3a.) then assigns all context variables to RestcommONE variables, sends the call to the SIP client of the agent. On hang up, the flow is transfered to Module 2 where you can hook up any service you want to send the emails and SMS .
You make the magic, so play around with RestcommONE.

3a. Setting up a context parser

At the time of this write-up RestcommONE was not able to parse the JSON of the context object sent in the SIP call into multiple variables. Therefore, I set up an additional REST service that receives the context object from RestcommONE (using their Hook URL) and echoes the content of the object into different variable for easy parsing. Hopefully RestcommONE will integrate this feature soon!

Code available on the Voxbone Github page.
RestcommONE App Available here.

Get awesome content in your inbox every week.

Give it a try. It only takes a click to unsubscribe.