© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2021
R. StringerReal-Time Twilio and Flybasehttps://doi.org/10.1007/978-1-4842-7074-5_1

1. Building a Real-Time SMS Call Center

Roger Stringer1  
Penticton, BC, Canada

We’re going to build a handy SMS call center for our first project.

This call center will handle incoming SMS messages from users; it won’t handle voice, just SMS. We’ll look at voice in a couple other chapters.

Do you want to know one of the beautiful things about Flybase? It integrates really easily with other services.

In this chapter, we are going to walk through using Flybase and Twilio together to build a real-time SMS call center.

This could be used as a customer help desk where customers send a text message for help and an agent sends a reply back from their web browser.

The actual phone work will be handled by Twilio, and Flybase will store the data and display the chats in real time. We’ll use Node.js to send and receive the text messages and an HTML frontend to handle the actual chatting.

The Setup

We’ll be using a few tools to build this app. You’ll want to have these set up before you continue on:
  • Twilio (http://twilio.com): To send and receive SMS messages. Don’t have a Twilio account? Sign up for free (www.twilio.com/try-twilio).

  • Flybase (www.flybase.io/): A real-time database API. We’ll be using it to store our incoming and outgoing messages.

  • Node.js (http://nodejs.org/): A platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications.

If you haven’t already, sign up (https://app.flybase.io/signup) for a free Flybase account now and then create a new app. You’ll use your app for your call center.

Getting Started

We first need to set up our Node.js app.

Besides the Twilio and Flybase modules, we’ll be using the Express framework (http://expressjs.com/) to set up our node web server to receive the POST request from Twilio, so we’ll need to install the express package. We’ll also be using the body-parser module, so we are going to install that as well.

Let’s create our package.json file:
      "name": "sms-contact-center",
      "version": "0.0.1",
      "description": "SMS Contact Center powered by Flybase, Twilio and Node.js",
      "main": "app.js",
      "repository": "https://github.com/flybase/sms-contact",
      "scripts": {
              "test": "echo "Error: no test specified" && exit 1"
      "keywords": [
      "author": "Roger Stringer",
      "license": "MIT",
      "dependencies": {
            "twilio": "~1.6.0",
            "ejs": "~0.8.5",
            "express": "~3.4.8",
            "flybase": "~1.7.8",
            "node-buzz": "~1.1.0",
            "moment": "~2.5.1",
            "less-middleware": "~0.2.1-beta",
            "body-parser" : "~1.4.2",
            "method-override" : "~2.0.2"
      "engines": {
            "node": "0.10.26"
Save this file, and from the terminal, run the following command:
npm install

This will create a node_modules folder containing all of the modules we want to use.

Let’s set up our folder structure; create a folder called views. This is where we will keep our frontend.

Now, create a folder called “public.” This will host our static files. Inside that folder, create a css folder and a js folder; we’ll come back to these later.

At the beginning of our app.js file, we’ll need to require express and initialize it into a variable called app.

We’re also going to use the bodyParser middleware (https://github.com/expressjs/body-parser) to make it easy to use the data we’ll be getting in our POST request.

Create a new file called app.js and require the twilio, express, and flybase packages:
var express = require('express');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var twilio = require('twilio');
var  path = require('path');
var app = express();
app.set('views', path.join(process.cwd(), 'views'));
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(__dirname + '/public'));
var port = process.env.PORT || 8080; // set our port
var client = twilio('ACCOUNTSID', 'AUTHTOKEN');
var twilio_number = 'YOUR-NUMBER';
var api_key = "YOUR-API-KEY";
var appname = "YOUR-FLYBASE-APP";
var collection = "smscontact";
var messagesRef = require('flybase').init(appname, collection, api_key);
// backend routes =========================

Replace ACCOUNTSID, AUTHTOKEN, and YOUR-NUMBER with your Twilio credentials and a phone number in your Twilio account that you’ll be using.

Then, replace YOUR-API-KEY, YOUR-flybase-APP, and smscontact with your Flybase API Key, and create a collection to use. If you haven’t already created a collection, one will be automatically created for you when you first save data, so you can leave the collection name set to smscontact if you want.

Flybase uses collections to organize data inside apps, so one app could have several collections. If you’re familiar with relational databases, this is the equivalent of a table.

This is the start of our app. Next, we’ll tell it what to do when new texts come in and when an agent replies to a text.

Sending and Receiving Texts

Twilio uses webhooks (https://en.wikipedia.org/wiki/Webhook) to let your server know when an incoming message or phone call comes into our app. We need to set up an endpoint that we can tell Twilio to use for the messaging webhook.

We’re going to add a route for /message that responds with some TwiML (Twilio Markup Language, www.twilio.com/docs/api/twiml). TwiML is a basic set of instructions you can use to tell Twilio what to do when you receive an incoming call or SMS message. Our code will look like this:
app.post('/message', function (request, response) {
      var d = new Date();
      var date = d.toLocaleString();
            sid: request.param('MessageSid'),
            direction: "inbound",
            tstamp: date,
      var resp = new twilio.TwimlResponse();
      resp.message('Thanks for the message, an agent will get back to you shortly.');
      response.writeHead(200, {

This will listen for any incoming SMS messages and store them inside your Flybase app.

Once a message has been received, we use the Twilio node library to initialize a new TwimlResponse. We then use the message keyword (www.twilio.com/docs/api/twiml/sms/message) to set what we want to respond to the message with. In this case, we’ll just say “Thanks for the message, an agent will get back to you shortly.” Then we’ll set the content-type of our response to text/xml and send the string representation of the TwimlResponse we built.

Whenever a customer sends a message to the phone number we’ve set up, it will send them the response and store the message inside Flybase. If an agent is watching the client, then they will see the message appear instantly and can send a reply back.

Now, let’s add a route called /reply. This is what we will call via AJAX when our agents want to reply to a message:
app.post('/reply', function (request, response) {
      var d = new Date();
      var date = d.toLocaleString();
            direction: "outbound",
            tstamp: date,
      client.sendMessage( {
      }, function( err, data ) {
            console.log( data.body );

This will store the reply in our Flybase app as an outbound reply and send the message to the customer.

Finally, let’s set our server to listen on port 8080 and tell it what to do when we view it from a browser:
// frontend routes =========================
// route to handle all angular requests
app.get('*', function(req, res) {
    res.render('home', {
var server = app.listen(port, function() {
      console.log('Listening on port %d', server.address().port);

Now that we’ve built our server, we need to tell Twilio to use this messaging URL as our Message Request URL.

Send an SMS message to your Twilio number, and you should get a response back. If you don’t, take a look at the Twilio App Monitor (www.twilio.com/user/account/developer-tools/app-monitor) to help determine what went wrong.

This is the backend portion of our call center; it listens for incoming text messages, stores them in our Flybase app, and then sends replies when an agent replies.

Now, we need to build our agent system, where an agent can watch incoming messages and reply to them.

We’ll build that now.

The Client

We’ve got our Node.js app listening for messages to send and receive. Now let’s set up our client, which is what agents will see from their web browser.

When a message comes in, we’ll display a chat box showing the message and then send a reply.

First, let’s create our view. In the /views folder, create a file called home.ejs:
<!doctype html>
      <link href='http://fonts.googleapis.com/css?family=Lato:400,300italic,400italic&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
      <link rel="stylesheet" type="text/css" href="http://angular-ui.github.com/ng-grid/css/ng-grid.css" />
      <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
      <link rel="stylesheet" type="text/css" href="/css/style.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
      <script src="https://cdn.flybase.io/flybase.js?latest=1"></script>
      <script src="/js/chat.js"></script>
      <title>SMS Contact Center, powered by Flybase and Twilio</title>
      <div class='container'>
            <br />
            <div class="well">
                  <p class='homefont'>Welcome to your SMS Contact Center</p>
                  <p class='homefont'>This call center is the start of a modern day call center.</p>
                  <p class='homefont'>Take a look around and give us a try.</p>
            <h3>Incoming messages</h3>
            <div id="templateContainer"></div>
// initializes our Flybase object
                   var flybaseRef = new flybase("<%= apikey %>", "<%= appname %>", "<%= collection %>");
// start our chatManager.
                   var myChatManager = new chatManager( flybaseRef );

This file will act as our HTML file, and we are using EJS so we can pass our Flybase settings and not have to configure them in multiple places. EJS is handy for adding template functionality to your Node.js apps.

Now, let’s create our CSS. In the /public/css folder we created earlier, create a new file called style.css:
.chatWindow{float:left;margin:20px;border:1px solid #000;width:300px;background:#e5e5e5;border-radius:5px}
.tstamp{font-size:9px;padding:2px;margin-bottom:10px;border-bottom:1px dotted #666;color:#666}
.messageForm textarea{float:left;width:220px;margin:5px}

Lastly, we want to set up the brains of our app. We’ve saved the biggest file for last.

In the public/js folder, create a new file called chat.js:
var chatManager = function(flybaseRef) {
      this.flybaseRef = flybaseRef;
chatManager.prototype = {
      chats: [],
      getChat: function(fromNumber) {
            var foundChat = null;
            for (c = 0; c < this.chats.length; c++) {
                  if (this.chats[c].from == fromNumber) {
                        foundChat = this.chats[c];
            if (foundChat == null) {
                  foundChat = new chat( this.flybaseRef );
            return foundChat;
      updateChats: function() {
            var _this = this;
            this.flybaseRef.once('value', function (data) {
                  data.forEach( function(message){
                        var row = message.value();
                        _this.getChat( row.fromNumber ).addMessage(
            this.flybaseRef.on('added', function (data) {
                  var row = data.value();
                  _this.getChat( row.fromNumber ).addMessage(
var chat = function(flybaseRef) {
      this.flybaseRef = flybaseRef;
chat.prototype = {
      init: function(name) {
            this.from = name;
            this.chatName = 'chat-' + this.from;
            this.buttonName = 'submit-' + this.from;
            this.textName = 'reply-' + this.from;
      replyMessage: function(message) {
            var _this = this;
                  type: "POST",
                  url: "/reply",
                  data: {
                        'To': this.from,
                        'Body': message,
                        'From': this.from
                  dataType: "json",
                  success: function(data) {
                        // your message was sent
      displayTemplate: function() {
            var content = '<div class="chatName">Chat with ' + this.from + '</div>
            <div class="messages" id="' + this.chatName + '"></div>
            <div class="messageForm"><textarea id="' + this.textName + '"></textarea><button id="' + this.buttonName + '">Reply</button></div>
            content = '<div class="chatWindow" id="' + this.tmplName + '">' + content + '</div>';
            var _this = this;
            $('#' + this.buttonName).click(function() {
                  _this.replyMessage($('#' + _this.textName).val());
                  $('#' + _this.textName).val('');
      addMessage: function(message, tstamp, direction) {
            $('#' + this.chatName).append("<div class='message_" + direction + "'>" + message + "<div class='tstamp'>" + tstamp + "</div></div>");

Our chatManage class is set up so that when it loads, it first grabs a list of saved text messages using the value event trigger and displays them by the phone number they were sent from.

We treat all messages to and from the same number as one session, so for each chat session, we would see a box displaying the messages between the agent and the customer and a textbox to use to send new messages.

We then listen for any new messages to come in using the added event trigger, and we then display them inside the proper chat box.

The chat class tells our app how to display the chat boxes and how to handle sending new replies.

In this case, when a message is sent by an agent, we post it to our backend /reply route, where it is saved to our Flybase app and then sent to the customer as a text message.

We’re also storing the direction a message came from, either inbound or outbound . This way we can style each message to appear similar to when you view a chat log on your phone. The customer’s texts will appear on the left side, and the agent’s replies will appear on the right side.

Now let’s fire up our app:
node app.js

We’ve told our app to run on port 8080, so if you go to your web browser and type in http://localhost:8080/, you should see your call center.

Just an aside, if you’re running this locally, you’ll want to make sure you’ve got ngrok running before you go to the next step. If you haven’t used ngrok (https://ngrok.com/) before, Kevin Whinnery over at Twilio has put together a great tutorial (www.twilio.com/blog/2013/10/test-your-webhooks-locally-with-ngrok.html) to help you get started.


We did it! Now that you’ve built a simple SMS call center app (https://github.com/flybaseio/sms-contact), it’s your chance to create something with it.

Take this project and roll with it. Some ideas are you could actually completely remove the /reply AJAX call and instead create an outbound text queue that would store the message and then add an added listener to the outbound collection that would both send the reply to the customer and add it into the message collection so it would appear in the chat window.

This would eliminate the need for that /reply AJAX call and also add some queue support in cases of sending out multiple replies to several customers at once.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.