How to Receive a Phone Call in Python Using Flask and Twilio

March 16, 2021
Written by
Diane Phan
Twilion

How to Receive a Phone Call in Python Using Flask and Twilio

Twilio Voice is a highly customizable and convenient service that allows you to automate your telephone workflows. In this tutorial you are going to learn how to create a Python application based on the Flask web framework that can answer phone calls.

Prerequisites

To follow this tutorial you need the following items:

Project setup

In this section you are going to set up a brand new Flask project. To keep things nicely organized, open a terminal or command prompt, find a suitable place and create a new directory where the project you are about to create will live:

mkdir phone-answer
cd phone-answer

Create a virtual environment

Following Python best practices, you are now going to create a virtual environment, where you are going to install the Python dependencies needed for this project.

If you are using a Unix or Mac OS system, open a terminal and enter the following commands to do the tasks described above:

python3 -m venv venv
source venv/bin/activate
pip install flask twilio pyngrok python-dotenv

If you are following the tutorial on Windows, enter the following commands in a command prompt window:

python -m venv venv
venv\Scripts\activate
$ pip install flask twilio pyngrok python-dotenv

The four Python packages that this project uses are:

  • The Flask framework, to create the web application that will receive message notifications from Twilio
  • The Twilio Python Helper library, to work with SMS messages.
  • Pyngrok, to make the Flask application temporarily accessible on the Internet
  • The python-dotenv package, to read a configuration file.

Set up a development Flask server

Make sure that you are currently in the virtual environment of your project’s directory in the terminal or command prompt. Since we will be utilizing Flask throughout the project, we will need to set up the development server. Add a .flaskenv file (make sure you have the leading dot) to your project with the following lines:

FLASK_APP=app.py
FLASK_ENV=development

These incredibly helpful lines will save you time when it comes to testing and debugging        your project.

  • FLASK_APP tells the Flask framework where our application is located.
  • FLASK_ENV configures Flask to run in debug mode.

These lines are convenient because every time you save the source file, the server will reload and reflect the changes.

Then, run the command flask run in your terminal to start the Flask framework.

flask run command

The screenshot above displays what your console will look like after running the command flask run. The service is running privately on your computer’s port 5000 and will wait for incoming connections there. You will also notice that debugging mode is active. When in this mode, the Flask server will automatically restart to incorporate any further changes you make to the source code.

However, since you don't have an app.py file yet, nothing will happen. Though, this is a great indicator that everything is installed properly.

Feel free to have Flask running in the background as you explore the code. We will be testing the entire project at the end.

Start an ngrok tunnel

The problem with the Flask web server is that it is local, which means that it cannot be accessed over the Internet. To be able to answer phone calls, Twilio needs to be able to send web requests to this server, so during development, a trick is necessary to make the local server available on the Internet.

On a second terminal window, activate the virtual environment and then run the following command:

ngrok http 5000

The ngrok screen should look as follows:

ngrok

Answer the phone with a message

In order to answer the phone call with a custom message, a webhook needs to be defined. Webhooks are HTTP callbacks that are triggered by an event, which in this case, is the phone call.

With the help of Twilio Markup Language, also known as TwiML, the twilio package that is installed in the virtual environment provides helper classes that make generating these responses very quick and possible.

Create an app.py file in your project directory and paste the following code below:

from flask import Flask
from twilio.twiml.voice_response import VoiceResponse

app = Flask(__name__)

@app.route("/answer", methods=['GET', 'POST'])
def voice():
    response = VoiceResponse()
    response.say('Hello world, and thank you for your call from the Flask application.')
    return str(response)

if __name__ == "__main__":
    app.run(debug=True)

This updated implementation of the endpoint uses the VoiceResponse class from the twilio package. In particular, the say() method will instruct Twilio to use a text-to-speech engine to answer the phone call with the message given as an argument.

Get a Twilio phone number

The final step is to configure a Twilio phone number to forward incoming calls to the answer() endpoint created above.

Buy a phone number

Log in to the Twilio Console, select Phone Numbers, and then click on the red plus sign to buy a Twilio number. Note that if you are using a free account you will be using your trial credit for this purchase.

In the Buy a Number screen you can select your country and check Voice in the capabilities field. If you’d like to request a number from your region, you can enter your area code in the Number field.

Buy a phone number

Click the Search button to see what numbers are available, and then click “Buy” for the number that you like from the results. After you confirm your purchase, click the “Close” button.

Congratulations, you now have your very own Twilio phone number!

Configuring the voice webhook

While on the Twilio Console, click on Phone Numbers again and select the phone number that you purchased above. Scroll down to the Voice & Fax section and enter the following settings:

  • For Accept Incoming, select "Voice Calls".
  • For Configure with, select "Webhooks, TwiML Bins, Functions, Studio or Proxy.
  • For A call comes in, select "Webhook" in the left dropdown. Enter the ngrok forwarding URL with /answer at the end in the text field. Select "HTTP POST" in the dropdown on the right side.

Configure Twilio Voice webhook

Don’t forget to click the Save button at the bottom of the page to record these changes.

Test your Twilio phone line

And now the moment of truth! Make sure the Flask server and ngrok are still running. Call the Twilio phone number that you purchased earlier from your own phone. After a few rings, the call should be answered and you should hear a voice that speaks the text that you passed as an argument to the say() method.

What's next for receiving phone calls in Python using Flask and Twilio

I hope you found this tutorial useful. The TwiML language is extremely rich and provides a large variety of options to automate incoming phone calls. If you would like to explore some of these options, here are some example commands you can use:

  • Play: instead of text-to-speech, play a message that is recorded in an audio file
  • Dial: connect the call to another phone number or conference call
  • Enqueue: put the caller on hold and add it to a queue
  • Gather: accept spoken or keyed digits from the caller
  • Record: record a message
  • Reject: reject the call

I’d love to see what you build with Twilio Voice!

Diane Phan is a Developer Network editor on the Developer Voices team. She loves to help programmers tackle difficult challenges that might prevent them from bringing their projects to life. She can be reached at dphan [at] twilio.com or LinkedIn.