Make Phone Calls with Code Using Twilio
Web applications are better than old school applications that get installed on your hard drive because you can access them from anywhere using the web. They do however suffer from the same limited communication channel as typical software because they can only interact with users via the computer. Users provide input via the keyboard and the app provides output via the screen. Wouldn’t it be cool if we could take advantage of other communication channels like phone and text messages to communicate with our users? Well now we can with the help of Twilio. In this post I’ll walk you through building an application that can make phone calls and send text messages using the Twilio API.
For those of you who don’t know, Twilio is a web service API that empowers programmers with the ability to make phone calls and send SMS text messages programmatically. I first came across the service a while back and have been keeping an eye on it ever since because I think it has a lot of potential uses in modern web applications. In the past, having your application make a phone call used to entail a lot of programming and hardware overhead ($$$). Twilio makes it as simple as one single API call (that doesn’t break the bank) and you’re done.
In this post I’m going to be building a sample application to illustrate some of what Twilio is capable of. Have you ever used a website or other service that required you to confirm your phone number by receiving a call and then entering a code given to you over the phone? Well that’s what we’re going to build. The concept is that a user fills out a generic registration form on your site and includes their phone number. Upon submission we will leverage Twilio to call the user and recite a 4 digit confirmation code that they will then have to enter in step 2 of the registration process. Upon validating the entered code from step 2 we will either send the user a SMS text message confirming a successful activation or display an error.
For the purposes of this example I am leveraging the CodeIgniter framework simply for the sake of development speed. The code that actually interacts with the API can easily be transplanted into any application and still work. When it comes to interacting with the API, Twilio has a number of client libraries to choose from. Our weapon of choice is PHP, so I will be using the PHP client library.
To make things a little easier I’m providing two downloads, one is the complete source code with all the code included. The other is just the framework preconfigured with the necessary libraries and helpers. This way, if you want to follow along, we won’t have to waste a lot of time setting up and configuring CodeIgniter.
Step 1 - Get a Twilio Account
Before you can access the Twilio API you first need to create an account to get access information. You typically have to pay to use Twilios service, but they do provide a free trial that comes with $30.00 worth of credit which you can use for the purposes of this example.
Visit https://www.twilio.com/try-twilio and fill out the provided form.
Your account dashboard is a collection of all of your account information in one easy to understand and access place. This is where you will find your Account SID and Auth Token. These are the two values you will need in order to make API requests. The dashboard also shows your account balance along with a rough calculation as to how that dollar amount translates into API requests. Your developer sandbox information is also displayed here, however we won’t be doing anything with the sandbox in this example.
The other thing you will need to do before continuing is to setup an outgoing called ID number within Twilio. For obvious reasons you can’t just go placing calls and sending text messages from any old number. You first need to enter and confirm a caller ID number within your account and then you can use that number when making API requests.
OK, so now that you have your API access information and have setup your caller ID your ready to jump in and get coding.
Step 2 - Setup
If you have not done so already, download a copy of the source code (blank or complete) and unzip the archive onto your desktop. For our registration example you will need to create a database and update CodeIgniters database settings (/application/config/database.php) with the appropriate access information. Once you have created your database, use the following SQL statement to create the one table we will be using.
Now that you have created your database and updated the code you can upload everything to your development environment. You will notice that if you bring up the application in a browser you will most likely get an error. That’s because we haven’t created our default controller yet, but that’s the next step.
Step 3 - Create the Controller
Now that we’re up and running with our code and database we can get to coding. First thing to do is create a new controller called register.php in /application/controllers. When a user first visits our application we want to display our registration form so let’s setup our controller to do that by default.
The above code leverages CodeIgniters default controller function index() to automatically display our registration form when a user first visits our application. Now we need to create our registration form view file. Create a new folder in /application/views called register and a new file in that folder called index.php.
This view file contains just a simple four field registration form the user will complete to begin the registration process. Save and upload your changes and when you visit the application in a browser you should see the following form displayed. But before we go much further be sure to update the class variables at the top of the controller with your Account SID, Auth Token and caller ID number. Please note, the caller ID number should start with a plus sign (+), include the country code and have no hyphens.
Step 4 - Access the API
We now have our controller and registration form. You may notice however that when you submit the registration form nothing happens. The form is looking for a controller function called confirm(). This function will begin our user registration process by validating the form input, generating the users confirmation code and contacting the Twilio API to call our user and recite the code. Let’s go ahead and create this function now in our controller.
The majority of this code should be pretty self explanatory (for those familiar with CI) but let’s review just to be safe. The first 13 lines are all about validation. We are using CodeIgniters form_validation library to validate our form input and ensure we have valid data. If there are any errors we display the form again with error messages. On line 19 we create a random 4 digit number that we will use as our confirmation code. This is the code we will pass to Twilio to recite to our users and then test for in step 2 of our process. This will be stored in our database along with our other user data. Lines 21-31 handle the database insertion for our user record using CIs active record library. 33-38 are where we contact the Twilio API and make our request to call the user (I’ll review these lines in a moment). The remainder of the function displays step 2 of our registration form which is just a single field asking the user to enter their confirmation code. Before we forget let’s create this new view file called confirm.php in /application/views/registration.
As I mentioned above, lines 33-38 are where we actually make our API request to Twilio.
The first thing we do here is determine if we need to make the call or not by checking the $call variable passed to the function. I put this in here to avoid making additional API calls if the user enters a wrong confirmation code (this will make sense later on). Next we create a new instance of TwilioRestClient which is the PHP client library and pass it our Account SID and Auth Token for authentication. Using our new TwilioRestClient object, we make a request to the API using the request() function. This function takes 3 arguments: the path to the API method your calling, the type of request your making (POST, GET, etc.) and any data you are passing along to the API (as an array).
Something to make note of here is the path to the API method we are passing. In a rather odd turn of events, each API call must include your Account SID. I find this rather odd and verbose but alas it is required. There are ways to make this easier to use within your code by making a minor modification to their library, but I chose to keep things just the way they provide for the purposes of our example.
So we are calling the /Accounts/Calls API method and passing it a “From” phone number, “To” phone number and “Url” to handle the call. The “From” number is the phone number the call will be made from (your Twilio called ID number). The “To” number is the number Twilio will be calling. It’s worth noting that this number must inclue the country code and contain no hyphens. The code should probably include some sanitization to ensure this, but I kept it out for simplicity. Finally the URL to handle the call is where Twilio will look for instructions on what to do for this call. This is where we have to provide it with instructions using TwiML or Twilio Markup Language.
Step 5 - TwiML
There is an entire section of documentation dedicated to TwiML, so I don’t intend on spending a tremendous amount of time on it. Suffice it to say it is the XML format that Twilio expects when looking for instructions on what to do when placing a phone call. You have several options to choose from but all we care to do is place a call and read a script. Let’s go ahead and create a new function in our controller called handle_call() to generate the necessary TwiML.
The above code basically creates the following XML document.
The first thing we do here is find our user based on ID in the DB. Next we take their confirmation code and put spaces between the numbers. Without doing this Twilio will pronounce the number as a complete number instead of digit by digit which would be a bummer for our users. Finally we put it all together in a script and call the addSay() function adding a loop attribute of 2 to make sure Twilio repeats the message twice. If you were to visit this function in your browser (/registration/handle_call) you would hopefully see the XML I provided above as an example.
Step 6 - Confirmation
We now have the majority of our application in place. The only thing we’re missing is the processing code to handle step 2 of our registration process. Let’s create a new function in our controller called confirm_code() to handle the final bit of validation.
The above code processes the confirmation code submission and checks to see if our user entered the correct code or not. If correct, we send the user a SMS text message using Twilio and display a view called account_activated.php. If incorrect, we simply display a view called account_error.php. Let’s create those two views now in /application/views/register.
The code for sending the text message is very similar to the block we used to make the phone call above.
This time we are requesting the /SMS/Messages API method to send a text message and passing along “From”, “To” and “Body” as parameters. Just like above “From” is the phone number we are sending from (our Twilio caller ID number), “To” is the number we are sending to and “Body” is the actual content of the text message. It’s worth mentioning that text messages don’t require any TwiML instructions, only phone calls.
And there you have it. If you save and upload your changes you should now have a functioning example. Enter your phone number in the phone number field of the registration form (being sure to include the country code and no hyphens) and hit submit. You should shortly receive a phone call reciting your confirmation code. Enter that code in the confirmation code form and submit. You should then see the success message and receive a congratulatory text message.
When I was first building this app I was not having much luck with placing phone calls. Twilio would call me but say there was a system error and then hang up (very frustrating). Come to find out that I had my site password protected and it couldn’t get to the handle_call() function for the TwiML instructions. The point of this story is I wouldn’t have been able to figure out what the problem was without the Twilio Debugger available through your Twilio account.
This is obviously not a complete and well polished application but it does illustrate some of what Twilio is capable of. Some possible enhancements to this code could include adding a country code drop down menu to the registration form so the user doesn’t have to enter it as part of their phone number, better phone number validation to ensure processing and maybe e-mail integration since we are collecting the users e-mail address. Feel free to experiment on your own and let me know how you make out by leaving a comment.