How I Built a Way for My Mum to Talk to Her Children Using Twilio Voice Conference

December 01, 2022
Written by
Aina Rakotoson
Contributor
Opinions expressed by Twilio contributors are their own
Reviewed by
Mia Adjei
Twilion

How I Built a Way for My Mum to Talk to Her Children Using Twilio Voice Conference

It is crucial for my mum to talk to her children every day.  She loves talking with us, even if it’s just to listen to our voices.

Now that we are grown up, and we don’t live in the same house anymore, she continues her ritual. She takes time every evening to call us one by one with her phone. Sometimes it’s not easy for her, but she never misses a single day without doing it.

One day I asked her why she didn’t call us in a group like on Facebook or Zoom. She answered that it would take time for her to configure the internet, login into her account, etc. Then I started to imagine a way for her to reach all of her children with a single phone call.

If you face the same problem as my mum, or you just want to call multiple people with a single phone call, stay tuned because this tutorial is for you.

In this article, I will show you how I built a conference application for my mum, so she can, with a single touch, call all of her children.

The main idea

The main idea is to reach multiple people with a single call, without typing each person's number.

Let me explain it using the scenario with my mum. She has four children and wants to call them all without the tedious task of calling one number at a time. When she calls one number, all four of her children's phones will ring, and she can talk to them all. This will be like if everyone is in the same place and talking together. In phone technology, it is called a “conference call”.

Generally, you can do this with your traditional cell phone by starting to call one person and then adding another participant when you are on the line with someone. This requires many steps, as you must add participants manually every time you start a conference call.

What if we could automatically add a list of participants when the conference starts, so we don’t have to add them manually?

Here is where the Twilio Voice conference can join the action. When a call arrives on a Twilio number, you can create a conference and add participants. This can be done via the Twilio API and with any programming language that the API supports. In this tutorial, we'll be using Python.

How to make conference calls with Twilio Voice

A Twilio Voice conference is like a hub where multiple people can communicate, but with more control.

When calling a Twilio number, Twilio can redirect the call information to a web application.

The web application then decides what to do with the call. It can start a conference by putting in this first caller.

Twilio conference on incoming call

When the conference starts, there is also a webhook that Twilio can call with an HTTP request. It is in this webhook that we can start adding participants to the conference. Then voila!! Everyone is in the same conference call, and all of it starts with a single phone call at the beginning.

The control is seamless for the end user, as the web application delegates all of the actions.

Twilio webhook on conference start

How the system works

Now that you understand how it is possible to make conference calls with Twilio Voice, let’s see how the whole system works.

Again, with the scenario of my mum calling:

  1. Mum dials a number — it should be a Twilio number.
  2. Twilio sends information to a web application via a webhook.
  3. The web application uses the Twilio helper library to create a new conference call.
  4. Twilio starts the conference, and puts the caller in.
  5. When mum joins the conference, a participant-join event is triggered by Twilio, and information about the event is sent to the web application using a status callback.
  6. The web application reacts to the participant-join event by adding participants via the Twilio API. In this scenario, the participants are my mum's children. It is only when mum first joins the conference that each child will be added.

Here is the schema showing the whole process:

How the system works

Realization

What you need

Let’s dig into the realization now. Here are the things you need to build the system:

  • One Twilio account with voice capability: You should have a Twilio number that can receive calls. Here is a link where you can create a Twilio account if you don't have one: Twilio | Try Twilio Free
  • Python 3 and some programming skills with Python. The web application will be written with Python.
  • Ngrok: This tool allows your web application to be accessible from the internet when running it locally.

The code for the web application

All automation and controls reside in the web application. It will initiate the conference and also add participants.

Basically, we need to create two routes in it: one for handling the conference creation and one for handling the addition of participants.

The Flask web framework is used to build the web application.

Before trying out the application for yourself, let's walk through what each part of the code will do.

The route to handle the conference creation is /voiceconference.

Here is the code.

@app.route("/voiceconference", methods=['GET', 'POST'])
def call():
    """Return TwiML for a moderated conference call."""
    base_url = request.url_root

    # Start our TwiML response
    response = VoiceResponse()

    # Start with a <Dial> verb
    with Dial() as dial:
        # If the caller is our MODERATOR, then start the conference when they
        # join and end the conference when they leave
        if request.values.get('From') == MODERATOR:
            dial.conference(
                CONFERENCE_NAME,
                start_conference_on_enter=True,
                end_conference_on_exit=True,
                status_callback=f"{base_url}confstatus",
                status_callback_event='start end join leave mute hold',
            )

    response.append(dial)
    return str(response)

This route will be called by Twilio when an incoming call arrives. It checks if the call is from the moderator (in this case, my mum), then starts the conference immediately.

The route that handles the addition of participants is /confstatus because all events that occur during the conference call will be received on this route.

Here is the code.

def add_participant(number, conference_name, label=""):
    participant = TWILIO_CLIENT.conferences(
        conference_name
    ).participants.create(
        label=label,
        early_media=True,
        beep='onEnter',
        from_=TWILIO_NUMBER,
        to=number)
    return participant


@app.route("/confstatus", methods=['POST', 'GET'])
def status():
    global IS_CONFERENCE_START
    event = request.args.get("StatusCallbackEvent")

    if event == "participant-join" and IS_CONFERENCE_START is False:
        for child_number in CHILDREN_NUMBERS:
            label, number = child_number
            add_participant(number, CONFERENCE_NAME, label)
    if event == "conference-start":
        IS_CONFERENCE_START = True
    if event == "conference-end":
        IS_CONFERENCE_START = False
    return ""

This route checks if the event is participant-join and if the conference has not yet started.

The first time mum enters the conference, she is the first participant inside. The conference has not yet started at this time; it only starts when at least two participants join. It is there that we add each participant one by one to the conference, using the add_participant() function.

conference-start is the event corresponding to the start of the conference, and we set the variable IS_CONFERENCE_START to True to show that the conference has already started.

When the event conference-end occurs, we reset this variable to False.

You can see the complete code in the following step, or download it from this repository: https://github.com/Aimage/twilio_mum_conference

Run the web app

Start by creating a directory called twilio_mum_conference then create a new file named webapp.py inside it:

mkdir twilio_mum_conference
cd twilio_mum_conference
touch webapp.py  

Inside webapp.py, add the following code:

import os
from flask import Flask, request
from twilio.twiml.voice_response import VoiceResponse, Dial
from twilio.rest import Client

TWILIO_NUMBER = '+XXXXXXXXXX'  # twilio number from which you can make an outgoing call
MODERATOR = '+ZXXXXXXXXXXX'  # mum's phone number
CONFERENCE_NAME = "Mum_conference"
CHILDREN_NUMBERS = [("Toto", "YXXXXXXXXXX")
                    ]  # set of label and number for each of the children

IS_CONFERENCE_START = False

ACCOUNT_SID = os.environ.get('TWILIO_ACCOUNT_SID')
AUTH_TOKEN = os.environ.get('TWILIO_AUTH_TOKEN')

TWILIO_CLIENT = Client(ACCOUNT_SID, AUTH_TOKEN)

app = Flask(__name__)


@app.route("/voiceconference", methods=['GET', 'POST'])
def call():
    """Return TwiML for a moderated conference call."""
    base_url = request.url_root

    # Start our TwiML response
    response = VoiceResponse()

    # Start with a <Dial> verb
    with Dial() as dial:
        # If the caller is our MODERATOR, then start the conference when she
        # joins and end the conference when she leaves
        if request.values.get('From') == MODERATOR:
            dial.conference(
                CONFERENCE_NAME,
                start_conference_on_enter=True,
                end_conference_on_exit=True,
                status_callback=f"{base_url}confstatus",
                status_callback_event='start end join leave mute hold',
            )

    response.append(dial)
    return str(response)


def add_participant(number, conference_name, label=""):
    participant = TWILIO_CLIENT.conferences(
        conference_name).participants.create(label=label,
                                             early_media=True,
                                             beep='onEnter',
                                             from_=TWILIO_NUMBER,
                                             to=number)
    return participant


@app.route("/confstatus", methods=['POST', 'GET'])
def status():
    global IS_CONFERENCE_START
    event = request.args.get("StatusCallbackEvent")
    # print(f"event: {event}")
    if event == "participant-join" and IS_CONFERENCE_START is False:
        for child_number in CHILDREN_NUMBERS:
            label, number = child_number
            add_participant(number, CONFERENCE_NAME, label)
    if event == "conference-start":
        IS_CONFERENCE_START = True
    if event == "conference-end":
        IS_CONFERENCE_START = False
    return ""


if __name__ == "__main__":
    app.run(debug=False, port=5000)


At the start of the file webapp.py, you have to set variables according to your specifications. Replace the placeholders for the phone numbers (TWILIO_NUMBER, MODERATOR, CHILDREN_NUMBERS) with your own phone number values, in E.164 format. For CHILDREN_NUMBERS, you can also change the name label for each person, and add as many phone numbers as are needed:

TWILIO_NUMBER = '+XXXXXXXXXX'  # twilio number from which you can make an outgoing call
MODERATOR = '+ZXXXXXXXXXXX'  # mum's phone number
CONFERENCE_NAME = "Mum_conference"
CHILDREN_NUMBERS = [("Toto", "YXXXXXXXXXX")
                    ]  # set of label and number for each of the children


ACCOUNT_SID = os.environ.get('TWILIO_ACCOUNT_SID') # your Twilio account SID
AUTH_TOKEN = os.environ.get('TWILIO_AUTH_TOKEN') # your Twilio AUTH_TOKEN

Before running the web application, you need to install some requirements.

First, create and activate a virtual environment with any version of Python 3.

python3 -m venv ./env
source ./env/bin/activate

Install the Python dependencies:

pip3 install twilio
pip3 install flask

Log in to your Twilio Console and find your values for TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN.

Twilio Console, showing Account SID and Auth Token

Then set them as environment variables by running the following commands, replacing the placeholder text with your actual values:

export TWILIO_ACCOUNT_SID="XXXXXXXXXXXXXXXXX"
export TWILIO_AUTH_TOKEN="XXXXXXXXXXXXXXXXX"

Now you can run the web application:

python webapp.py

The web application is running on port 5000 by default. (See at the end of the file to change the port if needed.)

Running web application with flask

If you have not done so before, install ngrok to make your local web application accessible from the internet.

Download it from here: https://ngrok.com/download. Then follow the instructions for your operating system to install the program and set your ngrok auth token.

Expose your application over the internet with ngrok by running the following command in a new terminal window or tab.

ngrok http 5000

ngrok console output

Set up the webhook URL on your Twilio Console

The web application is ready to receive requests. Now you need to tell Twilio how it can be contacted.

Login to your Twilio Console. Then go to the menu Phone numbers > Manage > Active number and select the number that you will use for the conference call.

In the section “A CALL COMES IN”, set the dropdown value as “webhook” and the URL with the value of the public URL shown on your ngrok terminal, followed by /voiceconference. The full URL will look something like this: https://XXXX-XXX-XX-XXX-XX.ngrok.io/voiceconference.

Set webhook URL in Twilio Console

Don’t forget to click the Save button to apply your changes.

Test and troubleshoot

Time to check if the system works. Take the phone with the number you set in the MODERATOR variable (my mum's phone number, in my case), then call the Twilio number where you set the webhook URL.

All phone numbers you put in the variable CHILDREN_NUMBERS should now ring and be in a conference if you answer the call.

In your Twilio Console, you can see what happened in the conference by looking at the menu Monitor -> Logs -> Conferences.

By clicking on one conference SID, you can see details about the conference: what events happened during it, which participants joined it, and what caused it to stop.

Conclusion

Now my mum can call all her children with one single call and talk to each of us. The environment is as if we are in the same place again, talking to each other.

I gave the Twilio number to my beloved mother on her birthday, and she was very happy. Then she added: “I never regret sending you to a school of engineering!!”

Now that you understand the key to how I built a way for my mum to talk to her children using Twilio Voice conference, you can build a similar application. For extension, you can add more control like recording all conversations, muting some participants, etc.

The knowledge is in your pocket now — maybe you can build a way to make someone else's life easier and make them happy.

About me: I’m a lead Python developer with 8 years of experience, passionate about electronics, IoT, and vintage mechanics. You can find me on Twitter or read my blog here: http://www.curiousmanjournal.ml/.