How to Make and Receive Phone Calls with Python, Bottle and Twilio Voice

Python, Bottle and Twilio Voice logos

Python web applications that combine the Bottle web framework with the Twilio Voice API can easily make and receive phone calls. Our calls will read a snippet of text then play an MP3 file. The call instructions can be modified to provide other useful actions such as gathering input from the number pad or putting all callers together in a conference call.

Our Project Tools

Our Bottle application will need either Python 2 or 3 to be installed. Python 3 is recommended for new applications. We will also need the following tools throughout this walkthrough:

You can snag all the code for this tutorial in the python-twilio-example-apps GitHub repository. Copy and modify the code however you want – it is all open sourced under the MIT license.

Install Dependencies

Before we write our Python code we will create a new virtual environment to isolate our application dependencies. Open your terminal and execute the virtualenv command to create a new virtualenv:

Execute the activate script within the virtualenv, which activates this Python installation for the shell we are working in. Be aware that you need to explicitly activate the virtualenv in each terminal window where you want to execute the Bottle application.

The command prompt will change when the virtualenv is activated. You should see (bottlephone) $. The following screenshot is what my environment looks like after I ran the activate script:

bottlephone-virtualenv.png

Next use the pip command to install the Bottle and Twilio Python packages into your virtualenv.

Our two required dependencies will be locally installed once the installation script finishes. Time to write some Python code!

Python Coding with Bottle

The Bottle web application will have three endpoints:

  • / – returns a simple message to let us know our Bottle app is running
  • /twiml – responds with TwiML (a set of instructions written in XML) that instructs Twilio what to do with phone calls
  • /dial-phone/<outbound_phone_number>, where “outbound_phone_number” is a phone number in the format ” 12025551234″

With that overview out of the way, we can proceed to writing the code for our initial Bottle application. Create a new file named app.py with the following lines of code:

Save the file. Make sure your virtualenv is still activated so our code can rely on the Bottle code library. Run the app via the Bottle development server with the following command:

Our development server should boot up successfully:

Test out the app by going to localhost:5000 in a web browser. We should get a simple success message that the app is running and responding to requests.

bottle-dev-server.png
Next we need to obtain a phone number that our Bottle app can use to call other phone numbers.

Getting Our Twilio Number

Our basic Bottle web app runs but what we really want to do is make some phone calls.
In your web browser go to the Twilio website and sign up for a free account. You can also sign into your existing Twilio account if you already have one.

console-phone-numbers.png

The Twilio trial account allows you to dial and receive phone calls to your own validated phone number. To dial and receive calls from any phone number then you need to upgrade your account. Trial accounts are great for initial development before your application goes live but upgraded accounts are where the real power of Twilio is revealed.

Once you are signed into your Twilio account, go to the manage phone numbers screen. On this screen you can buy one or more phone numbers or click on an existing phone number in your account to configure it.

number-config-screen.png

There is nothing for us to configure right now on the phone number configuration page but we will come back to it shortly. Now that we have a phone number in hand, let’s add the final bit of code to our Bottle app to get this app working.

Filling in Our Bottle App

We need to add two new routes to our Bottle app so it can dial outbound phone calls. Modify your existing app.py file with the two new functions below, twiml_response and outbound_call:

Make sure to replace the phone number listed above with your Twilio phone number. Also modify the placeholders for the Twilio credentials to properly instantiate the TwilioRestClient.

There is one issue with our local development environment configuration: Twilio won’t be able to reach that /twiml route. We need to deploy our app to a reachable server or use a localhost tunneling tool like Ngrok. Ngrok provides an external URL that connects to a port running on your machine. Download and install the Ngrok application for your operating system.

Run the following command to make our Bottle app on port 5000 available publicly on the Internet.

Ngrok will start up and provide us with a Forwarding URL, with both HTTP and HTTPS versions.

The Forwarding URL plus the route will instruct Twilio to handle the phone call when someone answers. Insert the Ngrok forwarding URL into the app.py file where NGROK_BASE_URL is specified:

ngrok-forwarding-url.png

One bit to be aware of when using Ngrok is that your Forwarding URL will change whenever you restart the application, so you’ll need to update your code with the latest Forwarding URL.
To get even more out of Ngrok after finishing your Bottle project, make sure to read this 6 awesome reasons to use Ngrok when testing webhooks post.

Making Calls

Make sure your Bottle development server is still running or re-run it with the python app.py command in a shell where your virtualenv is still activated.

Bring up your application in the web browser. Go to “localhost:5000/dial-phone/my-phone-number”, where “my-phone-number” is a number in the ” 12023350173″ E.164 format. For example, here is what happens when I get the call on my iPhone:

success.png

When we pick up the phone call we also see the /twiml route get called via Ngrok.

post-twiml.png

With only a couple of Bottle routes plus Twilio’s Voice API we were able to make phones ring!

Dialing Our Application

Outbound calls are handy, but what about if someone dials our application’s phone number? We have done all the hard work to make inbound calls possible. We just need to copy our Ngrok forwarding URL plus TwiML endpoint into the phone number configuration screen for the phone number we want to dial.

ngrok-number-config.png

Click “Save” and dial your application’s number. You should get the same message and MP3 played as when you dialed the outbound phone call.

Next Steps

We can make and receive phone calls from our Bottle web application using our Twilio phone number. Next you could try to add even more features to your app by going through one of these tutorials:

Questions? Contact me via