Advanced IVR

In this guide, you will create a bot answering an inbound phone call. The bot will ask for your location and share your actual weather conditions in response. You will implement this using the express web application framework, Weatherstack API and Vonage Automatic Speech Recognition (ASR) feature.

Prerequisites

To complete this guide, you need:

Install the dependencies

Install the express web application framework and body-parser packages:

npm install express body-parser

Create a Voice application

Use the CLI to create a Voice API application with the webhooks that will be responsible for answering a call on your Vonage number (/webhooks/voice/answer) and logging call events (/webhooks/voice/event), respectively.

These webhooks need to be accessible by Vonage's servers, so in this guide you will use ngrok to expose your local development environment to the public Internet. This article explains how to install and run ngrok and configure Vonage to send requests.

If you do not have an application, you can create one using the CLI

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

The command returns an application ID (which you should make a note of) and your private key information (which you can safely ignore for the purposes of this guide).

Run ngrok using the following command:

ngrok http 3000

Make a note of the temporary host name that ngrok provides and use it in place of example.com in the following command:

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

Buy a phone number

To handle inbound calls to your application, you need a number from Vonage. If you already have a number to use, jump to the next section to associate the existing number with your application.

You can use the Vonage CLI to buy the phone number:

Search for a Number

You can purchase a number using the Vonage CLI. The following command searches for a number a purchase (specify an alternate two-character country code to purchase a number in another country).

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.900.00

Use vonage numbers buy to purchase.

Purchase a number

Once you have found a number you are satisfied with, you can purchase that using the vonage numbers buy command:

vonage numbers buy US 16127779311 
✅ Searching for numbers
Are you sure you want to purchase the number 16127779311 for0.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're now ready to write your application code.

Sign up Weatherstack account

In this guide, you will use Weatherstack API to get weather info. To make a request, you have to sign up for a free account to get the API key.

Write your answer webhook

When Vonage receives an inbound call on your virtual number, it will make a request to your /webhooks/voice/answer route. This route should accept an HTTP GET request and return a Nexmo Call Control Object (NCCO) that tells Vonage how to handle the call.

Your NCCO should use the talk action to greet the caller, and the input action to start listening:

const express = require('express')
const bodyParser = require('body-parser')
const app = express()
const http = require('http')

app.use(bodyParser.json())

app.get('/webhooks/voice/answer', (request, response) => {

  const ncco = [{
      action: 'talk',
      text: 'Thank you for calling Weather Bot! Where are you from?'
    },
    {
      action: 'input',
      eventUrl: [
        `${request.protocol}://${request.get('host')}/webhooks/asr`],
      type: [ "speech" ]
    },
    {
      action: 'talk',
      text: 'Sorry, I don\'t hear you'
    }
  ]

  response.json(ncco)
})

Write your event webhook

Implement a webhook that captures call events so that you can observe the lifecycle of the call in the console:

app.post('/webhooks/voice/events', (request, response) => {
  console.log(request.body)
  response.sendStatus(200);
})

Vonage makes a POST request to this endpoint every time the call status changes.

Write your ASR webhook

Speech recognition results will be sent to the specific URL you set in the input action: /webhooks/asr. Add a webhook to process the result and add some user interaction.

In case of a successful recognition, the request payload will look as follows:

You can use the confidence element of the speech.results array for further analysis. To get the weather conditions data, make a HTTP GET request to the following URL:

Here, access_key is your Weatherstack API key and query is the location the user said (or at least what is expected them to say). Weatherstack provides a lot of interesting data in the response body:

In the app, you will use parameters like description (“Sunny”) and temperature. It’d be nice to get weather forecast rather than the actual temperature, however since the free Weatherstack account allows to get only current conditions - that’s what you will use.

Once you have received the response from Weatherstack, you need to return a new NCCO with the talk action to say “Today in New York: it’s sunny, 9 degrees Celsius”.

The following code shows how to handle the ASR callback and return your NCCO:

app.post('/webhooks/asr', (request, response) => {

  console.log(request.body)

  if (request.body.speech.results) {

    const city = request.body.speech.results[0].text

    http.get(
      'http://api.weatherstack.com/current?access_key=WEATHERSTACK_API_KEY&query=' +
      city, (weatherResponse) => {
        let data = '';

        weatherResponse.on('data', (chunk) => {
          data += chunk;
        });

        weatherResponse.on('end', () => {
          const weather = JSON.parse(data);

          console.log(weather);

          let location = weather.location.name
          let description = weather.current.weather_descriptions[0]
          let temperature = weather.current.temperature          

          console.log("Location: " + location)
          console.log("Description: " + description)
          console.log("Temperature: " + temperature)

          const ncco = [{
            action: 'talk',
            text: `Today in ${location}: it's ${description}, ${temperature}°C`
          }]

          response.json(ncco)

        });

      }).on("error", (err) => {
      console.log("Error: " + err.message);
    });

  } else {

    const ncco = [{
      action: 'talk',
      text: `Sorry I don't understand you.`
    }]

    response.json(ncco)
  }

})

You could add some additional logic to the bot, for example to convert the temperature to Fahrenheit if the location provided is in the US. To do so, add this code snippet before creating the NCCO:

if (weather.location.country == 'United States of America') {
  temperature = Math.round((temperature * 9 / 5) + 32) + '°F'
} else {
  temperature = temperature + '°C'
}

and don't forget to remove degrees symbol from the message text since it’s now included to the temperature variable value:

text: `Today in ${location}: it's ${description}, ${temperature}`

Create your Node.js server

Finally, write the code to instantiate your Node.js server:

const port = 3000
app.listen(port, () => console.log(`Listening on port ${port}`))

Test your application

  1. Run your Node.js application by executing the following command:
node index.js
  1. Call your Vonage number and listen to the welcome message.

  2. Say your city name.

  3. Hear your actual weather conditions back.

Conclusion

In this guide, you created an application that uses the Voice API to interact with a caller by asking them a question and answering with a voice message.

The bot you created was able to listen to the caller and respond with some relevant information. You may use it as a basis for your IVR or some customer self-service app by adding appropriate business logic relevant to your case and the services you are using.

As you see, automatic speech recognition (ASR) is an effortless way to implement dialogue-style voice bot or IVR ( Interactive Voice Response)/IVA (Interactive Voice Assistant) quickly. If you need more flexibility or almost real- time interaction, try our WebSockets feature, which is extremely powerful and can empower some very sophisticated use cases, such as artificial intelligence, analysis and transcription of call audio.

Where Next?

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