This application powers the support site for the Birchwood Bicycle Polo Co., which sells equipment to those who play "the sport of kings." It has three main features:
- Unsatisfied customers can submit support tickets with their phone number and their problem
- Support agents can call customers' phones from their browser to follow up on support tickets
- Customers can also use their browser to speak with support agents live when available
In this tutorial, we'll point out the key bits of code that make this application work. Check out the project README on GitHub to see how to run the code yourself.
The home page of our app displays a form for customers to submit support tickets. We use one of Flask's community components to create forms, Flask-WTF to power the page.
class SupportTicket(db.Model): """ Represents a support ticket """ __tablename__ = "tickets" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, nullable=False) phone_number = db.Column(db.String, nullable=False) description = db.Column(db.String, nullable=False) timestamp = db.Column(db.DateTime) @property def international_phone_number(self): parsed_number = phonenumbers.parse(self.phone_number) return phonenumbers.format_number( parsed_number, PhoneNumberFormat.INTERNATIONAL)
Now we can create a ticket. Next up, let's work on the dashboard for the support agent.
When a support agent visits the
/dashboard, they see all of the support tickets that have been submitted.
callCustomer(). That function kicks off a Twilio Client call to the phone number passed as its sole parameter.
Great, now we have an interface good enough for our support agents. Next up, in order to let our agents make calls to their customers through the browser, we need to provide them a capability token.
We use the Twilio Python helper library to generate and configure our capability tokens. To allow our support agents to call the phone numbers on our tickets, we use the
That method requires an identifier for a TwiML Application. Twilio will send a POST request to our backend every time a user makes a Twilio Client call — the TwiML Application tells Twilio which URL to send that request to.
Once we are equipped with our Capability Token, the next step is to set up the Twilio Device Client in the browser.
To use the Twilio Device Client in a web browser we use the twilio.js library.
We start by retrieving a capability token from the view we defined in the previous step with a POST request through AJAX. Then we enable the Twilio Device Client for this page by passing our token to
After that the
Twilio.Device.ready() callback will let us know when the browser is ready to make and receive calls.
Now that we have almost everything in place, it's time to see the core of this tutorial. Let's look at how we can let our agents start a call from their browsers.
When our support agents click on the Call Customer button on a support ticket, the function highlighted on the code snippet will initiate the call.
Twilio.Device.connect() to begin a new outgoing call. Our backend will tell Twilio how to handle this call, so we include a
phoneNumber parameter that we'll use on our
Great! Now our agents are able to make calls to their customers. Next up, let's look at how to connect that call to a phone number.
Whenever one of our users makes a call, Twilio will send a POST request to the URL we set on our TwiML Application - in this example it's
We use TwiML to respond to the request and tell Twilio how to handle the call. Twilio will pass along the
phoneNumber parameter from the previous step in its request, which we will then Dial in our TwiML.
call view responds, Twilio completes the connection between our support agent's browser and the customer's phone. Let's go back to the browser code and look at how to notify the agent of a call in progress.
And that's all for our browser-to-phone example. Next up, we will go even further and show a browser-to-browser example.
Support tickets are useful, but sometimes a customer needs help right now. With just a little more work we let customers talk to a support agent live via a browser-to-browser call.
When a customer clicks the Call support button on the home page we again use
Twilio.Device.connect() to initiate the call. This time we don't pass any additional parameters — our backend will route this call to our support agent.
Setting up the browser-to-browser call was rather simple right? Now let's look at how our backend will route this call to our support agent.
To allow our support agents to accept incoming calls we use the
allow_client_incoming() method when generating their capability token. We have to also pass
support_agent as the client's name to this method.
When Twilio sends a POST request to our
call view, we can connect the call to our support agent by responding with a <Client> TwiML noun and the
That's how we prepare everything for accepting incoming calls. Now we should go back in the browser and see how to handle the connection this time.
When our support agent's client receives an incoming call, it will trigger the function we defined on the
connection will be in a pending state until we invoke its
.accept() method, which we do in a function bound to the Answer Call button.
We also set a
.accept() callback to update the UI once the call is live.
Great! Now we know how to work on both cases: browser-to-phone and browser-to-browser calls! Next up, we will see what happens when they decide to hang up the call.
That's it! Our Flask application now powers browser-to-phone and browser-to-browser calls using Twilio Client.
If you're a Python developer working with Twilio, you might also enjoy these tutorials:
ETA notifications implementation with Python - Flask and Twilio.
Use Twilio to track the effectiveness of your different marketing campaigns.
Thanks for checking this tutorial out! If you have any feedback to share with us please contact us on Twitter, we'd love to hear it