Creating a Custom International Calling Card with Twilio

December 24, 2009
Written by
Danielle Morrill
Contributor
Opinions expressed by Twilio contributors are their own

Twilio Bug Logo

When I came downstairs this morning I was greeted by two bubbly and very sleep deprived Australians eager for some tea, and a chance to call Mum.  My first thought – there’s a Twilio app for that (or there will be soon)!

Being in the Christmas sprint, I decided I’d quickly code up an application that would make it easy for them to call a U.S. number from the landline at our house or any local phone, and be forwarded to their mom’s, boyfriends, and other folks through a simple menu.  20 minutes later, we made our first call!


Setting Up the International “Calling Card”

Twilio doesn’t provide international phone numbers, but you can set up a U.S. number and have it forward to an international destination using the <Dial> verb.  You don’t even need to use the REST API to make the outbound calls, its so simple!

Files to create:

  • * Handler for the incoming call, to greet the caller and read the menu, gather the menu selection keypress
  • * PHP handler for taking the keypress and directing the application to the right file to dial the number
  • * Files for each of the phone menu options, going to the different numbers to call

Setting up incoming-call.php

This first file is the one that I pointed the Twilio phone number to, to handle incoming calls.  It greets the caller and reads them a menu of people to call, and asks them to press a number to start.

It looks something like this:

<span style="color: #800080;"><?</span>php header<span style="color: #808030;">(</span><span style="color: #800000;">"</span><span style="color: #0000e6;">content-type: text/xml</span><span style="color: #800000;">"</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span> echo <span style="color: #800000;">"</span><span style="color: #0000e6;"><?xml version=</span><span style="color: #0f69ff;">"</span><span style="color: #0000e6;">1.0</span><span style="color: #0f69ff;">"</span><span style="color: #0000e6;"> encoding=</span><span style="color: #0f69ff;">"</span><span style="color: #0000e6;">UTF-8</span><span style="color: #0f69ff;">"</span><span style="color: #0000e6;">?></span><span style="color: #0f69ff;">n</span><span style="color: #800000;">"</span><span style="color: #800080;">;</span><span style="color: #800080;">?</span><span style="color: #808030;">></span>

<span style="color: #808030;"><</span>Response<span style="color: #808030;">></span>

<span style="color: #808030;"><</span>Gather numDigits<span style="color: #808030;">=</span><span style="color: #800000;">"</span><span style="color: #0000e6;">1</span><span style="color: #800000;">"</span> action<span style="color: #808030;">=</span><span style="color: #800000;">"</span><span style="color: #0000e6;">make-call.php</span><span style="color: #800000;">"</span> method<span style="color: #808030;">=</span><span style="color: #800000;">"</span><span style="color: #0000e6;">POST</span><span style="color: #800000;">"</span><span style="color: #808030;">></span>

 <span style="color: #808030;"><</span>Say voice<span style="color: #808030;">=</span><span style="color: #800000;">"</span><span style="color: #0000e6;">woman</span><span style="color: #800000;">"</span><span style="color: #808030;">></span>Hey girls<span style="color: #808030;">,</span> ready to call someone<span style="color: #800080;">?</span> If you know your selection<span style="color: #808030;">,</span> you may make it at any time<span style="color: #808030;">.</span><span style="color: #808030;"><</span><span style="color: #808030;">/</span>Say<span style="color: #808030;">></span> <span style="color: #808030;"><</span>Say<span style="color: #808030;">></span>Press <span style="color: #008c00;">1</span> to Call Laurens Mom<span style="color: #808030;"><</span><span style="color: #808030;">/</span>Say<span style="color: #808030;">></span> <span style="color: #808030;"><</span>Say<span style="color: #808030;">></span>Press <span style="color: #008c00;">2</span> to Call Jace<span style="color: #808030;"><</span><span style="color: #808030;">/</span>Say<span style="color: #808030;">></span> <span style="color: #808030;"><</span>Say<span style="color: #808030;">></span>Press <span style="color: #008c00;">3</span> to Call Eleesa's Home<span style="color: #808030;"><</span><span style="color: #808030;">/</span>Say<span style="color: #808030;">></span> <span style="color: #808030;"><</span>Say<span style="color: #808030;">></span>Press <span style="color: #008c00;">4</span> to Call Duh lane ah's Cell Phone<span style="color: #808030;"><</span><span style="color: #808030;">/</span>Say<span style="color: #808030;">></span> <span style="color: #808030;"><</span>Say<span style="color: #808030;">></span>To get help<span style="color: #808030;">,</span> Press <span style="color: #008c00;">5</span> to Call Danielle<span style="color: #808030;"><</span><span style="color: #808030;">/</span>Say<span style="color: #808030;">></span>

<span style="color: #808030;"><</span><span style="color: #808030;">/</span>Gather<span style="color: #808030;">></span>

<span style="color: #808030;"><</span>Say voice<span style="color: #808030;">=</span><span style="color: #800000;">"</span><span style="color: #0000e6;">woman</span><span style="color: #800000;">"</span><span style="color: #808030;">></span>Thanks <span style="color: #800000; font-weight: bold;">for</span> <span style="color: #800000; font-weight: bold;">using</span> <span style="color: #800000; font-weight: bold;">this</span> Twil ee oh app<span style="color: #808030;">,</span> created by Danielle<span style="color: #808030;">.</span> Happy holidays<span style="color: #808030;">!</span><span style="color: #808030;"><</span><span style="color: #808030;">/</span>Say<span style="color: #808030;">></span>

<span style="color: #808030;"><</span><span style="color: #808030;">/</span>Response<span style="color: #808030;">></span><strong></strong>

Setting up make-call.php

After the caller has pressed as key, the application posts the results to make-call.php, so we need to create a php file that understands what to do next with that information, and route the call.

<span style="background: #ffffe8 none repeat scroll 0% 0%; color: #a65700;"><?php</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">        </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800000; font-weight: bold;">if</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">(</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">$_REQUEST</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">[</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">'Digits'</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">]</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">=</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">=</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">'1'</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">)</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">{</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">                </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #400000;">header</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">(</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">"Location: call-laurens-mom.php"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">)</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">;</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">                </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800000; font-weight: bold;">die</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">;</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">        </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">}</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">        </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800000; font-weight: bold;">if</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">(</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">$_REQUEST</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">[</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">'Digits'</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">]</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">=</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">=</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">'2'</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">)</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">{</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">                </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #400000;">header</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">(</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">"Location: call-jace.php"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">)</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">;</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">                </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800000; font-weight: bold;">die</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">;</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">        </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">}</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">        </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800000; font-weight: bold;">if</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">(</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">$_REQUEST</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">[</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">'Digits'</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">]</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">=</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">=</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">'3'</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">)</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">{</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">                </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #400000;">header</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">(</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">"Location: call-elisas-home.php"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">)</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">;</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">                </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800000; font-weight: bold;">die</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">;</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">        </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">}</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">        </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800000; font-weight: bold;">if</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">(</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">$_REQUEST</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">[</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">'Digits'</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">]</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">=</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">=</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">'4'</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">)</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">{</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">                </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #400000;">header</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">(</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">"Location: call-dlaina-cell.php"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">)</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">;</span><span style="background: #ffffe8 none repeat sc
roll 0%0%; color: #000000;">                </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800000; font-weight: bold;">die</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">;</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">        </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">}</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">        </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800000; font-weight: bold;">if</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">(</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">$_REQUEST</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">[</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">'Digits'</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">]</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">=</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">=</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">'5'</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">)</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">{</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">                </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #400000;">header</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">(</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">"Location: call-danielle.php"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">)</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">;</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">                </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800000; font-weight: bold;">die</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">;</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">        </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">}</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">        </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #400000;">header</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">(</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">"content-type: text/xml"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">)</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">;</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">        </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800000; font-weight: bold;">echo</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">"<?xml version=</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0f69ff;">"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">1.0</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0f69ff;">"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;"> encoding=</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0f69ff;">"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">UTF-8</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0f69ff;">"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">?></span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0f69ff;">n</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">;</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #a65700;">?></span>

Setting up TwiML to Connect the Call

As you can see in the previous php script make-call.php, each selection directed the application to a different file.  This file is a very simple piece of TwiML that uses the <Dial> verb to connect the call.  Each one is pretty much the same, and looks like this:

<span style="background: #ffffe8 none repeat scroll 0% 0%; color: #a65700;"><?php</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">        </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #400000;">header</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">(</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">"content-type: text/xml"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #808030;">)</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">;</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #000000;">        </span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800000; font-weight: bold;">echo</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">"<?xml version=</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0f69ff;">"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">1.0</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0f69ff;">"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;"> encoding=</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0f69ff;">"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">UTF-8</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0f69ff;">"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">?></span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0f69ff;">n</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #0000e6;">"</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #800080;">;</span><span style="background: #ffffe8 none repeat scroll 0% 0%; color: #a65700;">?></span>

<span style="color: #a65700;"><</span><span style="color: #5f5035;">Response</span><span style="color: #a65700;">></span>

<span style="color: #a65700;"><</span><span style="color: #5f5035;">Say</span><span style="color: #a65700;">></span>Connecting you to Danielle, for help with this application<span style="color: #008c00;">..</span><span style="color: #a65700;"></</span><span style="color: #5f5035;">Say</span><span style="color: #a65700;">></span>

<span style="color: #a65700;"><</span><span style="color: #5f5035;">Dial</span><span style="color: #a65700;">></span><span style="color: #008c00;">4256987497</span><span style="color: #a65700;"></</span><span style="color: #5f5035;">Dial</span><span style="color: #a65700;">></span>

<span style="color: #a65700;"></</span><span style="color: #5f5035;">Response</span><span style="color: #a65700;">></span>

It’s Not Pre-paid, It’s Pay-As-You-Go

The best part about this for Elisa and Lauren is that it isn’t a prepaid card where they spend $50 and and are stuck with the card, even if they don’t use it up.  I’m billing them for exactly the amount they use, and they don’t have to pay for it until after the fact.  I can imagine turning custom pay-as-you-go calling cards into a really interesting business.

So there you have it.  If you have any international guests in your home this holiday season, or are interested in going into the calling card business, this might be a good place to start.  The app took less than 20 minutes to write, mostly because we were goofing around with the text to speech quite a bit, and is written with PHP.

You do need an upgraded Twilio account to get a phone number and make international calls, so maybe some Twilio minutes would be a good thing to ask Santa to bring you.  Happy holidays!