Track Usage Across Your Vonage Numbers

Gain insight into the effectiveness of your customer communications by keeping track of the calls received by your Vonage numbers. By registering a different number for each of your marketing campaigns, you can see which one performs the best and use that information to improve your future marketing efforts.

Today's example uses NodeJS and all the code is available on GitHub, however the same approach could be used for any other technology stack.

Prerequisites

In order to work through this guide you need:

  • A Vonage account
  • The Vonage CLI installed and set up.
  • A publicly accessible web server so Vonage can make webhook requests to your app. If you're developing locally we recommend ngrok.

Get Started

Before you grab the code and dive in, you will to set up a Vonage application and get some numbers to use with it. When you create a Vonage application, you specify some webhook endpoints; these are URLs in your own application and are the reason that your code must be publicly accessible. When a caller calls your Vonage number, Vonage will make a web request to the answer_url endpoint you specify and follow the instructions it finds there.

There is also an event_url webhook, that receives updates whenever the call state changes. In this application the code outputs the events to the console to provide useful information during development.

To create the initial application, use the Vonage CLI to run the command below, replacing your URL in two places:

vonage apps create 'Your application'

βœ… Creating Application
Saving private key ... Done!
Application created

Name: Your application
Application ID: 00000000-0000-0000-0000-000000000000
Improve AI: Off
Private/Public Key: Set

Capabilities:
  None Enabled

This command returns the UUID (Universally Unique Identifier) that identifies your application. With the Application id, you can now add the voice capability to your application:

Be sure to set the voice-answer-url, voice-event-url to point to your domain. You do not have to set the fallback URL.

vonage apps capabilities update 00000000-0000-0000-0000-000000000000 voice `
  --voice-answer-url='https://example.com/webhooks/voice/answer' `
  --voice-event-url='https://example.com/webhooks/voice/event' `
  --voice-fallback-url='https://example.com/webhooks/voice/fallback'
  
βœ… Fetching Application
βœ… Adding voice capability to application 00000000-0000-0000-0000-000000000000

Name: Your application
Application ID: 00000000-0000-0000-0000-000000000000
Improve AI: Off
Private/Public Key: Set

Capabilities:
 VOICE:
    Uses Signed callbacks: On
    Conversation TTL: 41 hours
    Leg Persistence Time: 6 days
    Event URL: [POST] https://example.com/webhooks/voice/event
    Answer URL: [POST] https://example.com/webhooks/voice/answer
    Fallback URL: [POST] https://example.com/webhooks/voice/fallback

You will need a couple of Vonage numbers to try this application. You can use the Vonage CLI to search for and buy a number using the commands shown below; when searching for a number, enter any country code in ISO 3166-1 alpha-2 format.

vonage numbers search US

βœ… Searching for numbers

There is 1 number available for purchase in United States

Number       Type    Features         Monthly Cost  Setup Cost
-----------  ------  ---------------  ------------  ----------
16127779311  Mobile  MMS, SMS, VOICE  €0.90         €0.00

Use vonage numbers buy to purchase.
vonage numbers buy US 16127779311 
βœ… Searching for numbers
Are you sure you want to purchase the number 16127779311 for €0.90? [y/n] y

βœ… Purchasing number
Number 16127779311 purchased

Number: 16127779311 
Country: πŸ‡ΊπŸ‡Έ United States
Type: Mobile
Features: MMS, SMS, VOICE
Monthly Cost: €0.90
Setup Cost: €0.00
Linked Application ID: Not linked to any application
Voice Callback: Not Set
Voice Callback Value: Not Set
Voice Status Callback: Not Set

You can use any country code in ISO 3166-1 alpha-2 format for this command. The result is the number you have bought so copy that (you can always get a list with vonage numbers) and link it the application you created:

vonage apps numbers link 00000000-0000-0000-0000-000000000000 16127779311

βœ… Fetching Application
Fetching Owned numbers [===============================================] 1/1 100%

Number linked

Number: 16127779311
Country: πŸ‡ΊπŸ‡Έ United States
Type: Toll-free
Features: MMS, SMS, VOICE
Monthly Cost: Not Set
Setup Cost: Not Set
Linked Application ID: 00000000-0000-0000-0000-000000000000
Voice Callback: app
Voice Callback Value: 00000000-0000-0000-0000-000000000000
Voice Status Callback: Not Set

Repeat the buying and linking step for as many numbers as you'd like to use.

For new users, you will need to top up your account before you can buy a number.

Set Up and Run the Application

First, get the code from this repository. You can either clone the repository to your local machine or download the zip file.

Install the dependencies with this command: npm install

Then copy the config template .env-example to a file called .env. In this file you will need to configure the phone number that Vonage should connect out to, so this can be any phone that you are nearby and can answer.

You can also set the port number in the .env file by adding a PORT setting

To start the webserver: npm start

Check everything is working as expected by visiting http://localhost:5000. You should see "Hello Vonage" as the response.

Handle inbound voice calls

When Vonage receives an inbound call to your Vonage number it makes a request to the webhook endpoint you set when you created a Voice application.

CallerVonageAppCallerVonageAppCaller calls one ofthe tracking numbersCalls Vonage numberInbound Call(from, to)

When the caller makes the call, the application receives the incoming webhook. It extracts the number that the caller is calling from (the to number) and the number that they dialled (the from number) and passes these values to the call tracking logic.

The incoming webhook is received by the /track-call route:

app.get('/track-call', (req, res) => {
    const from = req.query.from;
    const to = req.query.to;

    const ncco = callTracker.answer(from, to);
    return res.json(ncco);
});

Track the Call Before Connecting the Caller

The logic for actually tracking the call is separate in the example application. Please note, the app loses the data when you restart the server! For your own applications you may extend this part to write to a database, logging platform, or something else to suit your own needs. After tracking the call, the application returns a Nexmo Call Control Object (NCCO) to tell Vonage's servers what to do next with the call.

You'll find this code in lib/CallTracker.js:

class CallTracker {

  config;

  trackedCalls;

  constructor(config) {
    this.config = config;

    this.trackedCalls = {};
  }

  /**
   * Track the call and return an NCCO that proxies a call.
   */
  answer (from, to) {
    if(!this.trackedCalls[to]) {
      this.trackedCalls[to] = [];
    }

    this.trackedCalls[to].push({
      timestamp: Date.now(),
      from: from,
    });

    return [
      {
        action: 'connect',
        from: to,
        endpoint: [
          {
            type: 'phone',
            number: this.config.proxyToNumber,
          },
        ],
      },
    ];
  };
}

The NCCO uses the connect action to connect the incoming caller with another call to the number you specified in the config file. The from number has to be a Vonage number, so the code uses the tracked number as the caller ID for the outgoing call. Check the NCCO documentation for the connect action for more detail on the call control object.

Conclusion

With this approach you have been able to link some Vonage numbers to your node.js application, make a record of incoming calls to those numbers and connect the callers to an outbound number. By recording the timestamp as well as the from and to numbers, you can go ahead and perform any analysis that you need to on this data to get the best results for your business.

Where Next?

Here are a few more suggestions of resources that you might enjoy as a next step after this guide: