Handle an Inbound Phone Call with Python
Published on September 7, 2023

Table of Contents

A. Getting Started

B. How to Set up a Vonage Voice Application

C. How to Implement a Python Flask Voice Application

Getting Started

Introduction

Companies can improve their customer experience by enabling customer support via phone calls. Voice applications enable companies to create such custom phone lines to best suit end users. In this article, you will learn to build a Python Flask application in to develop a voice application to receive inbound phone calls. We will explore a few different scenarios that you can build to receive a phone call, all inside a Flask application!

About Vonage Call Control Objects

Vonage voice applications build upon the concept of Vonage Call Control Objects (NCCOs). A Call Control Object comprises a JSON array of actions that can control inbound calls. An NCCO tells you 3 things:

  • action: tells what is to be done on the call

  • options: describes how to modify the action

  • type: describes the option, for instance, type=phone for an endpoint option

The actions listed in an NCCO are executed on a first-in, first-out (FIFO) basis. The 3 actions that we will use in this article are:

Stage 1: action = talk.

Stage 2: action = connect.

Stage 3: - actions = talk and then stream. Then when the agent can take the call transfer (via REST call) and connect the caller.

You can perform other actions which we won't cover here, such as recording calls or downloading recorded calls. Learn more here.

Prerequisites

Vonage API Account

To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.

Install Python3

Learn how to install Python3 here.

Install Ngrok

  • Ngrok: helps you run a web server to quickly and easily test your web applications. You can install Ngrok by following the installation instructions on the official website. You can run ngrok after installing it with the following command:

ngrok http 9000

The running ngrok instance will generate a URL that tunnels localhost server. The Ngrok-generated URL will look like the following:

https://3eab-197-210-8-199.ngrok.io

Note the URL that Ngrok generates for you. You will need it later in this tutorial to configure your application capabilities.

Open a new tab in your terminal. All further terminal commands will be in the new terminal tab as we will leave ngrok running in the background

Install Flask

  • Flask: a lightweight web framework for building web applications in Python. You can install Flask with the pip package manager that comes pre-installed with Python. Use the following command on your terminal:

pip install flask

How to Set up a Vonage Voice Application

Set Up Vonage CLI

The Vonage CLI is a nice tool for your Vonage account management and administrative tasks. You can use it instead of the Vonage dashboard UI for tasks like creating applications, purchasing virtual phone numbers, and more. You can install it with the npm package manager. Use the following command in your terminal:

npm install -g @vonage/cli

You need your account API key and API Secret to configure the Vonage CLI. Login into your Vonage account in the API developer dashboard and you'll see both values at the top of the page.

Then, set the two values in your terminal as shown in the following code:

vonage config:set --apiKey=XXXXXX --apiSecret=XXXXXX

Install the Vonage Python SDK

  • Vonage Python SDK: This is a great CLI toolkit that makes it easy to work with Vonage while building Python applications. You can install it with the pip package manager

pip install vonage

Create a Vonage Voice Application

You will use the Vonage CLI to create a new Vonage app. Create a new directory and use the Vonage CLI to create a Vonage app as shown by the following terminal commands.

To create a new directory named project:

mkdir project && cd project

To create a new Vonage application:

vonage apps:create voice_app

You should get an output that looks like this:

Creating Application... done Application Name: voice_app Application ID: b9e9223e-xxxx-47e5-8759-de455744xxxx Public Key cobranding_allowed: false -----BEGIN PUBLIC KEY----- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX cobranding_allowed: false -----END PUBLIC KEY----- App Files Vonage App File: /User/project/vonage_app.json Private Key File: /User/project/voice_app.key Improve AI: false

2 Things To Note

  • The APPLICATION_ID that is returned, you will need it later as you follow this guide.

  • a private.key file created in your project

Set Application Capabilities

Ngrok creates tunnels to allow your application to be accessed publicly and safely. However, you need to connect your running Python script with the Vonage application that you created from the terminal earlier in the article.

Steps to activate the Voice feature on your Vonage application.

  1. Go to your dashboard's Applications section and select the application you created.

  2. Click the Edit button to open the application settings page.

  3. On the settings page, scroll down to the Capabilities section to see the Voice feature card.

  4. Click the toggle button on the Voice feature card to activate the Voice capability on the application. This makes the feature card expand and shows the fields for the needed URLs.

  5. You can input your Answer and Event URLs in their respective fields.

  • The Answer URL is where Vonage relays the calls that come in on the Vonage number

  • The Event URL is where event information about calls comes in through. You can use events to monitor or confirm your call requests.

Your URLs should look similar to this:

Answer URL: https://3eab-197-210-8-199.ngrok.io/webhooks/answer

Event URL: https://3eab-197-210-8-199.ngrok.io/webhooks/event

  1. Scroll down the page and click the Save changes button.

You need to search for a Vonage virtual number before you can purchase it. Use the following terminal command to search for a number.

vonage numbers:search [COUNTRY_CODE]

You can replace [COUNTRY_CODE] in the above command with the alpha-2 country code of any country you want the number domiciled in. This is demonstrated in the following bash command:

vonage numbers:search US

The terminal output should be like the following:

Country Number Type Cost Features ─────── ─────────── ────────── ──── ───────────── US 12035864290 mobile-lvn 0.90 VOICE,MMS,SMS US 12035864291 mobile-lvn 0.90 VOICE,MMS,SMS US 12035864293 mobile-lvn 0.90 VOICE,MMS,SMS US 12035864294 mobile-lvn 0.90 VOICE,MMS,SMS US 12035864295 mobile-lvn 0.90 VOICE,MMS,SMS US 12035864296 mobile-lvn 0.90 VOICE,MMS,SMS US 12035864297 mobile-lvn 0.90 VOICE,MMS,SMS US 12035864299 mobile-lvn 0.90 VOICE,MMS,SMS US 12035864317 mobile-lvn 0.90 VOICE,MMS,SMS US 12035864318 mobile-lvn 0.90 VOICE,MMS,SMS

Select a suitable number and purchase it with the following terminal command:

vonage numbers:buy [NUMBER] [COUNTRY_CODE]

An example:

vonage numbers:buy 12035864290 US

You will get an output like this:

Number 12035864290 has been purchased.

Use the following command to assign the newly purchased number to the Vonage application you created earlier.

vonage apps:link [APPLICATION_ID] --number=[PURCHASED_NUMBER]

You should get a bash output similar to the following:

Number '12035864290' is assigned to application 'b9e9223e-xxxx-47e5-8759-de455744xxxx'.

How to Implement a Python Flask Voice Application

Scenario One: Playing a Text-To-Speech Message

When an Inbound Call is received, a text-to-speech message can be played to the caller. This scenario will involve writing the code for the implementation.

Create a new file inside the project directory and name it scenario-1.py. Add the following code inside it:

from flask import Flask, request, jsonify

app = Flask(__name__)

ncco = [
    {
        "action": "talk",
        "text": "Hello, our office hours are Monday to Friday nine until five-thirty. Please call back then.",
        "language": "en-GB"
    }
]

@app.route("/webhooks/answer")
def answer_call():
    return jsonify(ncco)

@app.route("/webhooks/event")
def events():
    return ("200")

if __name__ == '__main__':
    app.run(host="localhost", port=9000)

In the above code:

  • you specified an Answer webhook URL where a callback is generated when your Vonage number receives a call. An NCCO is then returned as a response.

  • The NCCO controls the call by the action of playing a text-to-speech message into the call. The NCCO consists of the message that the caller hears and Vonage terminates the call at the end of the message.

  • You also have a webhook event for listening to events.

Test Run The Code

In a separate tab from your ngrok tunnel, use the following terminal command to run the code

python scenario-1.py

Try It Out:
Call the Vonage virtual number and you should hear the message.

Scenario Two: Connecting a Caller to an Agent

In this scenario, we will include a new NCCO action, connect to connect the caller to an agent after playing the talk NCCO message.

Create a new file can save it as scenario-2.py. Add the following code and save the file.

from flask import Flask, request, jsonify

VONAGE_NUMBER = "1**********" # Replace with your virtual Vonage number
YOUR_SECOND_NUMBER = "1**********" #Replace with your number


app = Flask(__name__)

ncco = [
    {
        "action": "talk",
        "text": "Hello, one moment please, your call is being forwarded to our agent."
    },
    {
        "action": "connect",
        "from": VONAGE_NUMBER,
        "endpoint": [{
           "type": 'phone',
           "number": YOUR_SECOND_NUMBER
         }]
    }
]


@app.route("/webhooks/answer")
def answer_call():
    return jsonify(ncco)

@app.route("/webhooks/event")
def events():
    return ("200")

if __name__ == '__main__':
    app.run(host="localhost", port=9000)

In the above code:

  • Vonage receives a call in the virtual number and generates a callback on the answer webhook URL.

  • The NCCO which controls the call firsts plays the text-to-speech message into the call. That is the first action, talk.

  • Upon completion of the talk action, the connect action is invoked which forwards the call to another number which could be your agent in a call, until one of them hangs up.

Try It Out:
Call your Vonage number. You will hear the message and then your call will be forwarded to the second number you specified.

Scenario Three: Playing On Hold Music

The implementation here puts the caller on hold (listening to music) until an agent is available. Then, the call is transferred to the agent.

The implementation goes by the following steps:

  1. A call comes in and a test-to-speech message is played

  2. Since an agent is unavailable, the call is played a music

  3. When an agent becomes available (after a simulated 30 seconds time delay), the call is then forwarded to the new NCCO, ncco2

  4. When ncco2 receives the forwarded call, it plays a message and then forwards the call to the now-available agent.

You can create a new file called scenario-3.py and add the following code to it:

from flask import Flask, request, jsonify
from threading import Timer
import vonage

UUID = ""
APPLICATION_ID = "YOUR_APP_ID"
PRIVATE_KEY = "voice_app.key"
TIMEOUT = 30 # Agent becomes available after this period
VONAGE_NUMBER = "1**********" # Replace with your virtual number
YOUR_SECOND_NUMBER = "1**********" #Replace with your number

# audio_url = "https://your_domain.com/your_music.mp3"
audio_url = "https://download.samplelib.com/mp3/sample-12s.mp3"
ncco_url = "https://1234abcd.ngrok.io/ncco"

ncco = [
    {
        "action": "talk",
        "text": "Hello, I'm sorry, but all our agents are helping customers right now. Please hold, and we will put you through as soon as possible."
    },
    {
        "action": "stream",
        "streamUrl": [audio_url],
        "loop": 0
    }
]

ncco2 = [
    {
        "action": "talk",
        "text": "Now connecting you. Thanks for waiting."
    },
    {
        "action": "connect",
        "from": VONAGE_NUMBER,
        "endpoint": [{"type": 'phone',"number": YOUR_SECOND_NUMBER}]
    }
]

def transfer_call ():
    print ("Transferring call...")
    client = vonage.Client(application_id = APPLICATION_ID, private_key=PRIVATE_KEY)
    dest = {"type": "ncco", "url": [ncco_url]}
    response = client.update_call(UUID, action="transfer", destination=dest)

def register_timer_callback():
    t = Timer(TIMEOUT, transfer_call)
    t.start()

register_timer_callback()

app = Flask(__name__)

@app.route("/webhooks/answer")
def answer_call():
    global UUID
    UUID = request.args['uuid']
    print("UUID:====> %s" % UUID)
    return (jsonify(ncco))

@app.route("/webhooks/event", methods=['POST'])
def events():
    return ("200")

@app.route("/ncco")
def build_ncco():
    return jsonify(ncco2)

if __name__ == '__main__':
    app.run(host="localhost", port=9000)

The Vonage Python library enables us to make a REST API call with the update_call function. The REST API call uses the transfer action to transfer the call, identified by a unique id UUID to a specified destination NCCO.

Instead of specifying a static NCCO here, we call an endpoint, build_ncco which returns the new controlling NCCO in JSON format.

The new NCCO then performs a connect action to connect the caller, currently listening to soothing music, to an agent.

Try It Out Call your Vonage number. You will hear a message and then music. After a short delay you will hear a message saying you will be connected to the agent. You are then connected to the agent in a call.

Summary

We have seen how to build Python voice applications with the help of Vonage. We used the method of playing a text-to-speech message, forwarding a call to another number, and even playing audio to a caller who kept waiting. You also saw how to transfer control to a new NCCO. With this foundation, you can program much more complicated Python applications.

Now you can also add more advanced actions like recording the call and more.

Further Resources

  • Check out the Voice API reference for an exhaustive list of things you can build into your voice applications

  • You can also read more about NCCO actions in the official guide.

If you have questions or feedback, join the Vonage Developer Slack or send Vonage a message on X, formerly known as Twitter!

Jekayinoluwa Olabemiwo

Jẹ́káyinOlúwa is a software craftsman and product manager passionate about technology and its impact on people. He works on product management, backend development, DevOps, technical writing, and community strategy. He enjoys dealing in the intersection of software, design, and human interaction. He likes reading and music.

Ready to start building?

Experience seamless connectivity, real-time messaging, and crystal-clear voice and video calls-all at your fingertips.

Subscribe to Our Developer Newsletter

Subscribe to our monthly newsletter to receive our latest updates on tutorials, releases, and events. No spam.