EmoPhone: How To Build A Twilio-Powered IVR Using PHP and ngrok


Before cell phones, there were only landline phones. In high school, I frequently called the person I had a crush on at home. Calling a semi-private phone number to have private conversations was always a rough time. I hoped against all odds that my crush would be the one answering my call and not their parent or sibling. Awkward conversations with disapproving fathers were plentiful in this landline era.

I don’t want to relive the existential dread of those phone calls. But, I do want to use a phone call as a means to unlock nostalgia and coding skills. Fire up Terminal and break out your mixtape CDs. We’re building EmoPhone, a Twilio-Powered IVR that plays emo music using PHP, and ngrok.  Try it out right here: +1 504-684-7369

Toolbox Checklist

Before we get going with the tutorial (and a litany of references to my favorite emo bands) let’s run down the tools you’ll need to build an IVR in PHP.


Getting Set Up With Twilio and ngrok: Signals That We Send Over The Air And Through A PHP Server

Let’s say one of my emo-band buddies calls EmoPhone once it’s complete. In a perfectly engineered world, they’ll hear a greeting, then a list of emo songs to choose from. Once a selection is made, the song will play. Before we get coding, let’s get our house in order.

If you’re new to Twilio, you’ll need to create an account and buy a phone number. You can search for a number with the area code of your choice, or a number that contains a phrase you like. I searched for a phone number that has the phrase “emo” in it.

Here’s how you do that in GIF form.


Next, download ngrok. If you needed some convincing on why we’re using ngrok, check out these 6 awesome reasons to use it.  It’ll help Twilio access the code we’ll write, and the tunes we’ll play. ngrok lets you expose local files to the world via a URL. We’ll use ngrok to give Twilio the URLs it needs to execute our code and make the EmoPhone run smoothly.

Let’s create a folder where we can keep our code. Open up Terminal and enter cd Documents. Then write the command mkdir Hacks. This will make a folder in your Documents directory called Hacks. Now we have a place to store the first bit of code we’ll write, and a place to store the code for your other future projects.
Now let’s solve the the Zoolander problem. Namely, the files we’ll create are on your computer and Twilio has no way of accessing them. Fire up a server to expose our code to ngrok. Make sure you have PHP 5.4.0 or later installed so you can get a server going with the following command. Double check you’re in the directory Hacks, then enter php -S localhost:8888 into terminal. Your server should be up and running. Then cd to the directory where you downloaded ngrok and input ./ngrok http 8888You should see this.


Excellent, our development environment is set up and we can write some code.

Say It Like You Mean It

First impressions count. We have to greet the caller before we get to riding phone lines and playing jams.

The first piece of code we wrote will feature XML commands we call TwiML. These are XML verbs that instruct Twilio to do things like record calls, play files, respond with text to speech and a whole lot more.

This file will handle the incoming call and greet the caller. Create a file called incoming-call.xml. We’ll then paste the following code into that file. Here’s what it’ll look like:

Try calling your app. You should hear Alice (Twilio’s lovely TTS robot) reading the greeting prompt. When you input a digit, you should hear an application error.

Now, let’s break down what each verb in that snippet of code is doing

  • <Response>  – Twilio wants something from our server, namely, our TwiML file. This verb lets Twilio know we hear it loud and clear, and we are responding to the request.
  • <Say> – dictates the words you’ll say to the caller via our lovely TTS bot, Alice
  • <Play> – this verb let’s you play an audio file to the caller. A bit later we’ll use it to play sad jams, and in this case, we’re playing the recorded intro I provided for Emo Dial.
  • <Gather> – this verb rounds up all the data your user inputs via pressing 1, 2, 3 etc in their song selection.

Open your browser and go to localhost:8888/incoming-call.xml. You should see your pretty XML file.
xml localhost

With this code in place, our caller is ready to select a song from Taking Back Sunday, Brand New, Say Anything, or Saves The Day. Are we ready to play it? Not quite yet, but we’re getting there.

Oh, Hello

Now we have a means to share our code with the outside world of APIs. But we still have to figure out what we’ll tell Twilio to do with those songs, how to handle user input, and how to <Play> the songs the user selects.

Your caller is no longer a mystery man. You now know which song they want to hear because they made a selection. The <Gather> and <Play> verbs will help us instruct Twilio how to handle the selection.

Twilio needs to <Gather> the user’s input which will then be passed to the ‘handle-user-input.php’ file. That ‘handle-user-input.php’ file will trigger an action, telling Twilio to play the song associated with the user’s input. Before getting into that, we’ll add the necessary TwiMLto incoming-call.xml right before we <Say> anything to the user.

Our updated XML file will look like this. You can see the changes on line 4 and line 11


Believe In What You Want From PHP

Thank you XML. You’ve done a great service, but if we’re talking to servers and handling unpredictable user inputs, we’re going to need a more dynamic coding language – PHP.

XML is a static language. It can relay our greeting to our caller without a hitch because we’re delivering the same greeting every time. Our user won’t be selecting the same song every time unless they’re a huge Brand New fan. Nevertheless, we can’t bank on that so it’s on to PHP.

Put your trust in simple acts, they’ll carry the weight of what we want out of our PHP file. For example the variable the <Gather> verb is huge in this file. So is the variable $digitPushed. That variable contains the data of what we’ll <Gather>, namely, the digits the user pressed.

Now Twilio knows which button the caller pressed courtesy of PHP passing that info along. But Twilio doesn’t know what to do with it. In this following snippet of code, we’ll spell out what Twilio should do with each of the 4 song selections by using switch statements in PHP.

Playing The Songs

You’ll want to host your songs in the same directory as all your code. This way when Twilio goes looking for that mp3 file to play, it’ll find it in the directory that ngrok is exposing via a url. Add the ngrok forwarding url with the filename of the song you want to play into the <Play> fields in your php file. My ngrok forwarding url is http://emophone.ngrok.io. The file I want to play is TakingBackSunday.mp3 so I would drop http://emophone.ngrok.io/TakingBackSunday.mp3 in the first play field. I’d do the same for the other songs I want to play.

Name this file handle-user-input.php

Our jams are online, let’s take this EmoPhone home.

If It Makes You Less Sad, We’ll Start Sharing This With The World

The code is written. The server is fired up. We’re peeling off Exit 152 and getting close to home. Now we need to point Twilio to our ngrok forwarding url. Go back to your Twilio dashboard and tab over to “Voice” There you’ll see a field for Request URL. Copy the forwarding URL from ngrok and drop it in the Request URL field for your Twilio number, add the file extension then hit save.


Tell All Your Friends

Your app is online! It’s playing music! It’s in the world! YUSS.

To butcher the words of one Adam Lazzara:

You can tell all your friends
To put the phone to their heads
This all was only wishful tinkering
This all was only wishful tinkering
(the only thing that I regret is that I, I never let you call me back)

Now that you have your first Twilio powered IVR up and running you can customize it however you please. If you’re not a fan of emo music, make an Adventure Time FAQ hotline. You can make a IVR with your favorite quotes from The Office, you can get incredibly meta and make an IVR that tells stories about your favorite IVRs! The possibilities are endless.

If you’re looking to expound upon the IVR hackery you’ve learned, check out the few posts below and please hit me up on twitter. For questions or comments above 140 characters, shoot me an email at kyleky@twilio.com. I’m all ears, especially if you have ideas for new emo songs to add, any questions to ask, apps to share, or hacks to hip me to.