Click To Call with Node.js and Express

Download the Code

Wish your users could get in touch as easily as they can surf? It's your lucky day!

Let's go over the steps necessary to implement click-to-call in a Node.js and Express MVC application.

Click to Call

  1. A website visitor submits a web form with a phone number.
  2. Your web application receives the submission and initiates an HTTP request to Twilio asking to initiate an outbound call.
  3. Twilio receives the request and initiates a call to the user's phone number.
  4. The user picks up the call.
  5. After the call connects, we provide TwiML instructions to connect the user to our sales or support teams.

Check out how iAdvize uses Twilio Click-to-call to connect online shoppers with customer support representatives.

What We Will Learn

This tutorial demonstrates how to initialize a call using the Twilio REST API and how to create a call using the TwiML Say verb.

Let's begin!  Click the below button to continue.

Setup Our Environment

To create our click-to-call application we need to setup our environment first.

Let's put our Twilio credentials in a place where our application can access them. For the purposes of this tutorial we'll use environment variables that our application can read.

You can find your Twilio credentials in the console.

Retrieve Your Twilio Credentials

For more instructions on how to run the application refer to the app's readme file.

Loading Code Samples...
Language
{
  "name": "Click To Call: Twilio & Node",
  "description": "An example of implementing click to call functionality in a Node.js application",
  "keywords": [
    "node.js",
    "API",
    "twilio",
    "expressjs",
    "Express",
    "Tutorial",
    "Telephone API",
    "Voice API",
    "REST API",
    "Demo"
  ],
  "website": "https://twilio.com/docs/howto/click-to-call-walkthrough",
  "repository": "https://github.com/TwilioDevEd/clicktocall-node",
  "logo": "https://s3-us-west-2.amazonaws.com/deved/twilio-logo.png",
  "success_url": "/landing.html",
  "env": {
    "TWILIO_ACCOUNT_SID": {
      "description": "Your Twilio account secret ID, you can find at: https://www.twilio.com/user/account",
      "value": "enter_your_account_sid_here"
    },
    "TWILIO_AUTH_TOKEN": {
      "description": "Your secret Twilio Auth token, you can find at: https://www.twilio.com/user/account",
      "value": "enter_your_auth_token_here"
    },
    "TWILIO_NUMBER": {
      "description": "The Twilio phone number you are using for this app. You can get one here: https://www.twilio.com/user/account/phone-numbers/incoming",
      "value": "+15005550006"
    }
  }
}
app.json
Environment configuration

app.json

Next let's build a nice user facing web form.

Make a Web Form

The first step in a click-to-call solution is building the form that your user needs to fill out on your site.

No need to overthink this, the real goal is to POST the user's phone number to your controller.

Loading Code Samples...
Language
doctype html
html(lang="en")
  head
    title Click To Call Tutorial

    // We use Twitter Bootstrap as the default styling for our page
    link(rel='stylesheet', 
      href='//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css')
    link(rel='stylesheet', 
      href='//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css')

    // Include CSS for our third-party telephone input jQuery plugin
    link(rel='stylesheet', href='/vendor/intl-phone/css/intlTelInput.css')
  body
    .container
      h1 Click To Call
      p.
        Click To Call converts your website's users into engaged customers by 
        creating an easy way for your customers to contact your sales and 
        support teams right on your website.

      p Here's an example of how it's done!

      hr

      // C2C contact form
      .row
        .col-md-12
          form(id='contactForm', role='form')
            .form-group
              h3 Call Sales
              p.help-block.
                Are you interested in impressing your friends and confounding 
                your enemies? Enter your phone number below, and our team will 
                contact you right away.
            label Your Number
            .form-group
              input.form-control(type='text', id='phoneNumber', 
                placeholder='(651) 555-7889')
            label Sales Team Number 
            .form-group
              input.form-control(type='text', id='salesNumber', 
                placeholder='(651) 555-7889')
            button(type='submit', class='btn btn-default') Contact Sales

    // Include page dependencies
    script(src='//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js')
    script(src='/vendor/intl-phone/js/intlTelInput.min.js')

    // Our app's front-end JavaScript logic
    script(src='/app.js')
views/index.jade
Build a web form

views/index.jade

So what does this form need?

  • An input for the phone number
  • A submit button.

Since the page doesn't need to render new content after clicking on submit, we've decided to implement the POST action via AJAX using jQuery.

Let's take a look at that, next.

Submit the Form

To make the click to call feature more seamless we used Ajax to send the form asynchronously.

This code shows one way you could implement this functionality using jQuery:

  • Watch for the user submitting the form element.
  • Submit the form's data to our controller.
  • Let the user know if the submission was successful or not.

This is a common implementation of jQuery's $.ajax() method. (Notice that we are returning the response message when the call has connected.)

Loading Code Samples...
Language
// Execute JavaScript on page load
$(function() {
    // Initialize phone number text input plugin
    $('#phoneNumber, #salesNumber').intlTelInput({
        responsiveDropdown: true,
        autoFormat: true,
        utilsScript: '/vendor/intl-phone/libphonenumber/build/utils.js'
    });

    // Intercept form submission and submit the form with ajax
    $('#contactForm').on('submit', function(e) {
        // Prevent submit event from bubbling and automatically submitting the
        // form
        e.preventDefault();

        // Call our ajax endpoint on the server to initialize the phone call
        $.ajax({
            url: '/call',
            method: 'POST',
            dataType: 'json',
            data: {
                phoneNumber: $('#phoneNumber').val(),
                salesNumber: $('#salesNumber').val()
            }
        }).done(function(data) {
            // The JSON sent back from the server will contain a success message
            alert(data.message);
        }).fail(function(error) {
            alert(JSON.stringify(error));
        });
    });
});
public/app.js
Submit the form with AJAX

public/app.js

Now that we have the front end done, let's build the back end that will receive this data and call the user.

Initiate the Client Object

First we initiate a client object with our Account SID and Auth Token.

This is essentially our Javascript REST API handler that we could use to send SMSs (or a myriad of other things). For now, we just need it to get access to a twilio object that we're going to use to create phone calls.

Loading Code Samples...
Language
var path = require('path');
var express = require('express');
var morgan = require('morgan');
var bodyParser = require('body-parser');
var twilio = require('twilio');
var VoiceResponse = twilio.twiml.VoiceResponse;
var config = require('../config');


// Create a Twilio REST API client for authenticated requests to Twilio
var client = twilio(config.accountSid, config.authToken);


// Configure application routes
module.exports = function(app) {
    // Set Jade as the default template engine
    app.set('view engine', 'jade');

    // Express static file middleware - serves up JS, CSS, and images from the
    // "public" directory where we started our webapp process
    app.use(express.static(path.join(process.cwd(), 'public')));

    // Parse incoming request bodies as form-encoded
    app.use(bodyParser.urlencoded({
        extended: true,
    }));

    // Use morgan for HTTP request logging
    app.use(morgan('combined'));

    // Home Page with Click to Call
    app.get('/', function(request, response) {
        response.render('index');
    });

    // Handle an AJAX POST request to place an outbound call
    app.post('/call', function(request, response) {
        // This should be the publicly accessible URL for your application
        // Here, we just use the host for the application making the request,
        // but you can hard code it or use something different if need be
        var salesNumber = request.body.salesNumber;
        var url = 'http://' + request.headers.host + '/outbound/' + encodeURIComponent(salesNumber)

        var options = {
            to: request.body.phoneNumber,
            from: config.twilioNumber,
            url: url,
        };

        // Place an outbound call to the user, using the TwiML instructions
        // from the /outbound route
        client.calls.create(options)
          .then((message) => {
            console.log(message.responseText);
            response.send({
                message: 'Thank you! We will be calling you shortly.',
            });
          })
          .catch((error) => {
            console.log(error);
            response.status(500).send(error);
          });
    });

    // Return TwiML instuctions for the outbound call
    app.post('/outbound/:salesNumber', function(request, response) {
        var salesNumber = request.params.salesNumber;
        var twimlResponse = new VoiceResponse();

        twimlResponse.say('Thanks for contacting our sales department. Our ' +
                          'next available representative will take your call. ',
                          { voice: 'alice' });

        twimlResponse.dial(salesNumber);

        response.send(twimlResponse.toString());
    });
};
routes/index.js
Set up our Twilio client

routes/index.js

Next, let's look at making an outgoing phone call with Twilio.

Make a Phone Call

Next we'll use the twilio object created to make an outgoing phone call which requires us to pass a From number, a To number and the URL Parameter that tells Twilio where to find further instructions.

Loading Code Samples...
Language
var path = require('path');
var express = require('express');
var morgan = require('morgan');
var bodyParser = require('body-parser');
var twilio = require('twilio');
var VoiceResponse = twilio.twiml.VoiceResponse;
var config = require('../config');


// Create a Twilio REST API client for authenticated requests to Twilio
var client = twilio(config.accountSid, config.authToken);


// Configure application routes
module.exports = function(app) {
    // Set Jade as the default template engine
    app.set('view engine', 'jade');

    // Express static file middleware - serves up JS, CSS, and images from the
    // "public" directory where we started our webapp process
    app.use(express.static(path.join(process.cwd(), 'public')));

    // Parse incoming request bodies as form-encoded
    app.use(bodyParser.urlencoded({
        extended: true,
    }));

    // Use morgan for HTTP request logging
    app.use(morgan('combined'));

    // Home Page with Click to Call
    app.get('/', function(request, response) {
        response.render('index');
    });

    // Handle an AJAX POST request to place an outbound call
    app.post('/call', function(request, response) {
        // This should be the publicly accessible URL for your application
        // Here, we just use the host for the application making the request,
        // but you can hard code it or use something different if need be
        var salesNumber = request.body.salesNumber;
        var url = 'http://' + request.headers.host + '/outbound/' + encodeURIComponent(salesNumber)

        var options = {
            to: request.body.phoneNumber,
            from: config.twilioNumber,
            url: url,
        };

        // Place an outbound call to the user, using the TwiML instructions
        // from the /outbound route
        client.calls.create(options)
          .then((message) => {
            console.log(message.responseText);
            response.send({
                message: 'Thank you! We will be calling you shortly.',
            });
          })
          .catch((error) => {
            console.log(error);
            response.status(500).send(error);
          });
    });

    // Return TwiML instuctions for the outbound call
    app.post('/outbound/:salesNumber', function(request, response) {
        var salesNumber = request.params.salesNumber;
        var twimlResponse = new VoiceResponse();

        twimlResponse.say('Thanks for contacting our sales department. Our ' +
                          'next available representative will take your call. ',
                          { voice: 'alice' });

        twimlResponse.dial(salesNumber);

        response.send(twimlResponse.toString());
    });
};
routes/index.js
Route for outbound calls

routes/index.js

In this case Twilio needs to DIAL in the Agent once the call has been placed. We'll discuss this more in the next step.

The Outbound Endpoint

Twilio makes a request to our application when the call is created using the REST API.

This means that we need to create an endpoint that is publicly available for requests.

Loading Code Samples...
Language
var path = require('path');
var express = require('express');
var morgan = require('morgan');
var bodyParser = require('body-parser');
var twilio = require('twilio');
var VoiceResponse = twilio.twiml.VoiceResponse;
var config = require('../config');


// Create a Twilio REST API client for authenticated requests to Twilio
var client = twilio(config.accountSid, config.authToken);


// Configure application routes
module.exports = function(app) {
    // Set Jade as the default template engine
    app.set('view engine', 'jade');

    // Express static file middleware - serves up JS, CSS, and images from the
    // "public" directory where we started our webapp process
    app.use(express.static(path.join(process.cwd(), 'public')));

    // Parse incoming request bodies as form-encoded
    app.use(bodyParser.urlencoded({
        extended: true,
    }));

    // Use morgan for HTTP request logging
    app.use(morgan('combined'));

    // Home Page with Click to Call
    app.get('/', function(request, response) {
        response.render('index');
    });

    // Handle an AJAX POST request to place an outbound call
    app.post('/call', function(request, response) {
        // This should be the publicly accessible URL for your application
        // Here, we just use the host for the application making the request,
        // but you can hard code it or use something different if need be
        var salesNumber = request.body.salesNumber;
        var url = 'http://' + request.headers.host + '/outbound/' + encodeURIComponent(salesNumber)

        var options = {
            to: request.body.phoneNumber,
            from: config.twilioNumber,
            url: url,
        };

        // Place an outbound call to the user, using the TwiML instructions
        // from the /outbound route
        client.calls.create(options)
          .then((message) => {
            console.log(message.responseText);
            response.send({
                message: 'Thank you! We will be calling you shortly.',
            });
          })
          .catch((error) => {
            console.log(error);
            response.status(500).send(error);
          });
    });

    // Return TwiML instuctions for the outbound call
    app.post('/outbound/:salesNumber', function(request, response) {
        var salesNumber = request.params.salesNumber;
        var twimlResponse = new VoiceResponse();

        twimlResponse.say('Thanks for contacting our sales department. Our ' +
                          'next available representative will take your call. ',
                          { voice: 'alice' });

        twimlResponse.dial(salesNumber);

        response.send(twimlResponse.toString());
    });
};
routes/index.js
Return TwiML instructions

routes/index.js

Let's look closer at TwiML in the next pane.

Generating TwiML

TwiML is a set of verbs and nouns written in XML that Twilio reads as instructions. In this case our instructions inform Twilio to SAY something to the user and DIAL a support agent.

In order to make writing TwiML easy, many of the helper libraries have methods that generate TwiML for you. In this case we use twilio-node to create a TwiML response that will instruct Twilio to SAY something.

Loading Code Samples...
Language
var path = require('path');
var express = require('express');
var morgan = require('morgan');
var bodyParser = require('body-parser');
var twilio = require('twilio');
var VoiceResponse = twilio.twiml.VoiceResponse;
var config = require('../config');


// Create a Twilio REST API client for authenticated requests to Twilio
var client = twilio(config.accountSid, config.authToken);


// Configure application routes
module.exports = function(app) {
    // Set Jade as the default template engine
    app.set('view engine', 'jade');

    // Express static file middleware - serves up JS, CSS, and images from the
    // "public" directory where we started our webapp process
    app.use(express.static(path.join(process.cwd(), 'public')));

    // Parse incoming request bodies as form-encoded
    app.use(bodyParser.urlencoded({
        extended: true,
    }));

    // Use morgan for HTTP request logging
    app.use(morgan('combined'));

    // Home Page with Click to Call
    app.get('/', function(request, response) {
        response.render('index');
    });

    // Handle an AJAX POST request to place an outbound call
    app.post('/call', function(request, response) {
        // This should be the publicly accessible URL for your application
        // Here, we just use the host for the application making the request,
        // but you can hard code it or use something different if need be
        var salesNumber = request.body.salesNumber;
        var url = 'http://' + request.headers.host + '/outbound/' + encodeURIComponent(salesNumber)

        var options = {
            to: request.body.phoneNumber,
            from: config.twilioNumber,
            url: url,
        };

        // Place an outbound call to the user, using the TwiML instructions
        // from the /outbound route
        client.calls.create(options)
          .then((message) => {
            console.log(message.responseText);
            response.send({
                message: 'Thank you! We will be calling you shortly.',
            });
          })
          .catch((error) => {
            console.log(error);
            response.status(500).send(error);
          });
    });

    // Return TwiML instuctions for the outbound call
    app.post('/outbound/:salesNumber', function(request, response) {
        var salesNumber = request.params.salesNumber;
        var twimlResponse = new VoiceResponse();

        twimlResponse.say('Thanks for contacting our sales department. Our ' +
                          'next available representative will take your call. ',
                          { voice: 'alice' });

        twimlResponse.dial(salesNumber);

        response.send(twimlResponse.toString());
    });
};
routes/index.js
Command Twilio to say something

routes/index.js

And with that: a wrap!  You've helped us implement click-to-call for our fake application.  Now you can easily add it to your real one.

Next we'll look at some other great features.

Where to next?

We love Node here at Twilio!  Here are a couple other tutorials that prove it:

Automated Survey

Instantly collect structured data from your users with a survey conducted over a voice call or SMS text messages.

SMS and MMS Notifications

Send SMS alerts to a list of system administrators if something goes wrong on your server.

Did this help?

Thanks for checking this tutorial out! Tweet to us @twilio and let us know what you're building!

Kevin Whinnery
Samuel Mendes
Andrew Baker
Jose Oliveros
Paul Kamp
Agustin Camino

Need some help?

We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd browsing the Twilio tag on Stack Overflow.

1 / 1
Loading Code Samples...
{
  "name": "Click To Call: Twilio & Node",
  "description": "An example of implementing click to call functionality in a Node.js application",
  "keywords": [
    "node.js",
    "API",
    "twilio",
    "expressjs",
    "Express",
    "Tutorial",
    "Telephone API",
    "Voice API",
    "REST API",
    "Demo"
  ],
  "website": "https://twilio.com/docs/howto/click-to-call-walkthrough",
  "repository": "https://github.com/TwilioDevEd/clicktocall-node",
  "logo": "https://s3-us-west-2.amazonaws.com/deved/twilio-logo.png",
  "success_url": "/landing.html",
  "env": {
    "TWILIO_ACCOUNT_SID": {
      "description": "Your Twilio account secret ID, you can find at: https://www.twilio.com/user/account",
      "value": "enter_your_account_sid_here"
    },
    "TWILIO_AUTH_TOKEN": {
      "description": "Your secret Twilio Auth token, you can find at: https://www.twilio.com/user/account",
      "value": "enter_your_auth_token_here"
    },
    "TWILIO_NUMBER": {
      "description": "The Twilio phone number you are using for this app. You can get one here: https://www.twilio.com/user/account/phone-numbers/incoming",
      "value": "+15005550006"
    }
  }
}
doctype html
html(lang="en")
  head
    title Click To Call Tutorial

    // We use Twitter Bootstrap as the default styling for our page
    link(rel='stylesheet', 
      href='//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css')
    link(rel='stylesheet', 
      href='//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css')

    // Include CSS for our third-party telephone input jQuery plugin
    link(rel='stylesheet', href='/vendor/intl-phone/css/intlTelInput.css')
  body
    .container
      h1 Click To Call
      p.
        Click To Call converts your website's users into engaged customers by 
        creating an easy way for your customers to contact your sales and 
        support teams right on your website.

      p Here's an example of how it's done!

      hr

      // C2C contact form
      .row
        .col-md-12
          form(id='contactForm', role='form')
            .form-group
              h3 Call Sales
              p.help-block.
                Are you interested in impressing your friends and confounding 
                your enemies? Enter your phone number below, and our team will 
                contact you right away.
            label Your Number
            .form-group
              input.form-control(type='text', id='phoneNumber', 
                placeholder='(651) 555-7889')
            label Sales Team Number 
            .form-group
              input.form-control(type='text', id='salesNumber', 
                placeholder='(651) 555-7889')
            button(type='submit', class='btn btn-default') Contact Sales

    // Include page dependencies
    script(src='//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js')
    script(src='/vendor/intl-phone/js/intlTelInput.min.js')

    // Our app's front-end JavaScript logic
    script(src='/app.js')
// Execute JavaScript on page load
$(function() {
    // Initialize phone number text input plugin
    $('#phoneNumber, #salesNumber').intlTelInput({
        responsiveDropdown: true,
        autoFormat: true,
        utilsScript: '/vendor/intl-phone/libphonenumber/build/utils.js'
    });

    // Intercept form submission and submit the form with ajax
    $('#contactForm').on('submit', function(e) {
        // Prevent submit event from bubbling and automatically submitting the
        // form
        e.preventDefault();

        // Call our ajax endpoint on the server to initialize the phone call
        $.ajax({
            url: '/call',
            method: 'POST',
            dataType: 'json',
            data: {
                phoneNumber: $('#phoneNumber').val(),
                salesNumber: $('#salesNumber').val()
            }
        }).done(function(data) {
            // The JSON sent back from the server will contain a success message
            alert(data.message);
        }).fail(function(error) {
            alert(JSON.stringify(error));
        });
    });
});
var path = require('path');
var express = require('express');
var morgan = require('morgan');
var bodyParser = require('body-parser');
var twilio = require('twilio');
var VoiceResponse = twilio.twiml.VoiceResponse;
var config = require('../config');


// Create a Twilio REST API client for authenticated requests to Twilio
var client = twilio(config.accountSid, config.authToken);


// Configure application routes
module.exports = function(app) {
    // Set Jade as the default template engine
    app.set('view engine', 'jade');

    // Express static file middleware - serves up JS, CSS, and images from the
    // "public" directory where we started our webapp process
    app.use(express.static(path.join(process.cwd(), 'public')));

    // Parse incoming request bodies as form-encoded
    app.use(bodyParser.urlencoded({
        extended: true,
    }));

    // Use morgan for HTTP request logging
    app.use(morgan('combined'));

    // Home Page with Click to Call
    app.get('/', function(request, response) {
        response.render('index');
    });

    // Handle an AJAX POST request to place an outbound call
    app.post('/call', function(request, response) {
        // This should be the publicly accessible URL for your application
        // Here, we just use the host for the application making the request,
        // but you can hard code it or use something different if need be
        var salesNumber = request.body.salesNumber;
        var url = 'http://' + request.headers.host + '/outbound/' + encodeURIComponent(salesNumber)

        var options = {
            to: request.body.phoneNumber,
            from: config.twilioNumber,
            url: url,
        };

        // Place an outbound call to the user, using the TwiML instructions
        // from the /outbound route
        client.calls.create(options)
          .then((message) => {
            console.log(message.responseText);
            response.send({
                message: 'Thank you! We will be calling you shortly.',
            });
          })
          .catch((error) => {
            console.log(error);
            response.status(500).send(error);
          });
    });

    // Return TwiML instuctions for the outbound call
    app.post('/outbound/:salesNumber', function(request, response) {
        var salesNumber = request.params.salesNumber;
        var twimlResponse = new VoiceResponse();

        twimlResponse.say('Thanks for contacting our sales department. Our ' +
                          'next available representative will take your call. ',
                          { voice: 'alice' });

        twimlResponse.dial(salesNumber);

        response.send(twimlResponse.toString());
    });
};
var path = require('path');
var express = require('express');
var morgan = require('morgan');
var bodyParser = require('body-parser');
var twilio = require('twilio');
var VoiceResponse = twilio.twiml.VoiceResponse;
var config = require('../config');


// Create a Twilio REST API client for authenticated requests to Twilio
var client = twilio(config.accountSid, config.authToken);


// Configure application routes
module.exports = function(app) {
    // Set Jade as the default template engine
    app.set('view engine', 'jade');

    // Express static file middleware - serves up JS, CSS, and images from the
    // "public" directory where we started our webapp process
    app.use(express.static(path.join(process.cwd(), 'public')));

    // Parse incoming request bodies as form-encoded
    app.use(bodyParser.urlencoded({
        extended: true,
    }));

    // Use morgan for HTTP request logging
    app.use(morgan('combined'));

    // Home Page with Click to Call
    app.get('/', function(request, response) {
        response.render('index');
    });

    // Handle an AJAX POST request to place an outbound call
    app.post('/call', function(request, response) {
        // This should be the publicly accessible URL for your application
        // Here, we just use the host for the application making the request,
        // but you can hard code it or use something different if need be
        var salesNumber = request.body.salesNumber;
        var url = 'http://' + request.headers.host + '/outbound/' + encodeURIComponent(salesNumber)

        var options = {
            to: request.body.phoneNumber,
            from: config.twilioNumber,
            url: url,
        };

        // Place an outbound call to the user, using the TwiML instructions
        // from the /outbound route
        client.calls.create(options)
          .then((message) => {
            console.log(message.responseText);
            response.send({
                message: 'Thank you! We will be calling you shortly.',
            });
          })
          .catch((error) => {
            console.log(error);
            response.status(500).send(error);
          });
    });

    // Return TwiML instuctions for the outbound call
    app.post('/outbound/:salesNumber', function(request, response) {
        var salesNumber = request.params.salesNumber;
        var twimlResponse = new VoiceResponse();

        twimlResponse.say('Thanks for contacting our sales department. Our ' +
                          'next available representative will take your call. ',
                          { voice: 'alice' });

        twimlResponse.dial(salesNumber);

        response.send(twimlResponse.toString());
    });
};
var path = require('path');
var express = require('express');
var morgan = require('morgan');
var bodyParser = require('body-parser');
var twilio = require('twilio');
var VoiceResponse = twilio.twiml.VoiceResponse;
var config = require('../config');


// Create a Twilio REST API client for authenticated requests to Twilio
var client = twilio(config.accountSid, config.authToken);


// Configure application routes
module.exports = function(app) {
    // Set Jade as the default template engine
    app.set('view engine', 'jade');

    // Express static file middleware - serves up JS, CSS, and images from the
    // "public" directory where we started our webapp process
    app.use(express.static(path.join(process.cwd(), 'public')));

    // Parse incoming request bodies as form-encoded
    app.use(bodyParser.urlencoded({
        extended: true,
    }));

    // Use morgan for HTTP request logging
    app.use(morgan('combined'));

    // Home Page with Click to Call
    app.get('/', function(request, response) {
        response.render('index');
    });

    // Handle an AJAX POST request to place an outbound call
    app.post('/call', function(request, response) {
        // This should be the publicly accessible URL for your application
        // Here, we just use the host for the application making the request,
        // but you can hard code it or use something different if need be
        var salesNumber = request.body.salesNumber;
        var url = 'http://' + request.headers.host + '/outbound/' + encodeURIComponent(salesNumber)

        var options = {
            to: request.body.phoneNumber,
            from: config.twilioNumber,
            url: url,
        };

        // Place an outbound call to the user, using the TwiML instructions
        // from the /outbound route
        client.calls.create(options)
          .then((message) => {
            console.log(message.responseText);
            response.send({
                message: 'Thank you! We will be calling you shortly.',
            });
          })
          .catch((error) => {
            console.log(error);
            response.status(500).send(error);
          });
    });

    // Return TwiML instuctions for the outbound call
    app.post('/outbound/:salesNumber', function(request, response) {
        var salesNumber = request.params.salesNumber;
        var twimlResponse = new VoiceResponse();

        twimlResponse.say('Thanks for contacting our sales department. Our ' +
                          'next available representative will take your call. ',
                          { voice: 'alice' });

        twimlResponse.dial(salesNumber);

        response.send(twimlResponse.toString());
    });
};
var path = require('path');
var express = require('express');
var morgan = require('morgan');
var bodyParser = require('body-parser');
var twilio = require('twilio');
var VoiceResponse = twilio.twiml.VoiceResponse;
var config = require('../config');


// Create a Twilio REST API client for authenticated requests to Twilio
var client = twilio(config.accountSid, config.authToken);


// Configure application routes
module.exports = function(app) {
    // Set Jade as the default template engine
    app.set('view engine', 'jade');

    // Express static file middleware - serves up JS, CSS, and images from the
    // "public" directory where we started our webapp process
    app.use(express.static(path.join(process.cwd(), 'public')));

    // Parse incoming request bodies as form-encoded
    app.use(bodyParser.urlencoded({
        extended: true,
    }));

    // Use morgan for HTTP request logging
    app.use(morgan('combined'));

    // Home Page with Click to Call
    app.get('/', function(request, response) {
        response.render('index');
    });

    // Handle an AJAX POST request to place an outbound call
    app.post('/call', function(request, response) {
        // This should be the publicly accessible URL for your application
        // Here, we just use the host for the application making the request,
        // but you can hard code it or use something different if need be
        var salesNumber = request.body.salesNumber;
        var url = 'http://' + request.headers.host + '/outbound/' + encodeURIComponent(salesNumber)

        var options = {
            to: request.body.phoneNumber,
            from: config.twilioNumber,
            url: url,
        };

        // Place an outbound call to the user, using the TwiML instructions
        // from the /outbound route
        client.calls.create(options)
          .then((message) => {
            console.log(message.responseText);
            response.send({
                message: 'Thank you! We will be calling you shortly.',
            });
          })
          .catch((error) => {
            console.log(error);
            response.status(500).send(error);
          });
    });

    // Return TwiML instuctions for the outbound call
    app.post('/outbound/:salesNumber', function(request, response) {
        var salesNumber = request.params.salesNumber;
        var twimlResponse = new VoiceResponse();

        twimlResponse.say('Thanks for contacting our sales department. Our ' +
                          'next available representative will take your call. ',
                          { voice: 'alice' });

        twimlResponse.dial(salesNumber);

        response.send(twimlResponse.toString());
    });
};