The Small Business IVR

Working in support, I field a lot of queries from small business managers and startups about how to setup and build a phone menu system (IVR).

Interactive Voice Response (IVR) adds a level of class to your small business setup, they can make your organisation look bigger than it is and allows you to directly manage the routing of calls made to your company.

One of the best features of a Twilio based IVR is that you can give your customers one phone number and then route the calls to your sales / technicians / whoever as you need to.

–       No more ring this number for sales, ring this number for support etc.…

Lets propose we need to make an IVR for ‘John Smith Widget Company’, this IVR needs to have two menu options; one for sales and one for support and greet the caller with the office hours: 8am to 6pm


– When the caller selects an option (Sales or Support) we want to be able to route this call to an appropriate phone number (the companies sales manger for example), when this person (sales manager) answers the phone we want to be able to whisper that this is a sales call and offer them a chance to accept or reject the call.


– Should no one answer the phone or the call be rejected, as a fall back we need to explain to the caller no one is around and to leave a message on our voicemail system.

For this we will need:

A Twilio Account

A Twilio phone number

A webserver that supports a scripting language, I’m using PHP here but the code and logic will translate across most other languages.

If you haven’t done so already, sign up at

You will need to verify your phone number and once in, copy your phone number, Accountsid and Authkey from your account portal page.

Download the Twilio PHP Libaray from github, the URL is:


Make a new directory, something called smbivr and copy the ‘Services’ into this directory.

Now we need a landing page for when someone calls your Twilio number.

Make a new file called twilioIncomingCallHandler.php and save it in your directory smbivr

In this file we are going to add:


// Phone Number for your Sales Line:

$salesNumber = “”;

// Phone Number for your Support line:

$supportNumber = “”;

// To set the Caller ID to be the actual caller, uncomment this:

//$callerID = $_GET[“From”];

// To set the CallerID to the number dialed IE your Sales Line uncomment this:

$callerID = $_GET[“To”];

// Check if the HTTP request is loop by checking for any pressed digits

$menuInput = $_GET[“Digits”];

// If the menu is 1 we know they want sales team so we are going to say

// ‘Transfering you to sales now, Please note call calls are recoreded for training purposes’

// Then we are going to call the sales line and whisper the details of the call as well as giving the agent to divert to VM.

// If the menu is 2 the call is for support, so are going to transfer the call to out support line and whisper that the call is about customer support.

// If the menu is blank its a 1st time caller so we great the caller and then present the landing menu.

if ($menuInput == “1”) {

$TwiMLResponse = “<Dial callerId=\””. $callerID . “\” timeout=\”18\” action=\”./handleDialCallStatus.php\”><Number url=\”./whisper.php?type=sales\”>$salesNumber</Number></Dial>”;


elseif ($menuInput == “2”) {

$TwiMLResponse = “<Dial callerId=\””. $callerID . “\” timeout=\”18\” action=\”./handleDialCallStatus.php\”><Number url=\”./whisper.php?type=support\”>$supportNumber</Number></Dial>”;


else {

$TwiMLResponse = “<Gather method=\”GET\” timeout=\”25\” numDigits=\”1\”><Say voice=\”alice\”>Hello and welcome to Chicken and Bee. Your partner for web, voice and messaging services. Our opening hours are 8 am to 6 PM London Time. For Sales please press 1. For support or other enquiries please press 2.</Say></Gather>”;


header(“content-type: text/xml”);


<Response><?php echo $TwiMLResponse; ?></Response>

As you can see from the code this file is going to do two things, the first time its called it will greet the caller with our welcome message, opening hours and then ask the caller who they would like to be directed too, when the user inputs a digit Twilio will make a HTTP POST to the same file but this time including the digit the caller pressed.

Now when the code runs, it will look for any digits pressed and provide a different set of TwiML instructions – in this case call either the sales or support line.

This is the normal for a IVR system, but we are going to branch off now and do some advanced bits.

For example what if the caller is a known customer or a high value customer, it might be a good idea for us to gather this callerID and check our CRM to see if they are in fact a customer.

When we made the <Dial> verb we also included some attributes, these included:




You can find more information on these verbs at:


The action URL (handleDialCallStatus.php) will handle the call when the dialed party has provided a response – hangup, voicemail etc.

The URL (whisper.php) will speak to the dialed party and give them an option to accept or decline the call based on some TwiML and scripting.

To make the ‘Number URL’ speak to the dialed party we direct the URL to a new script called ‘whisper.php’

In this file we are going to place:


// Find out what kind of whisper we are going to do is this a sales or support call?

$callType = $_GET[“type”];

// If the Type is a sales call say to the agent that this is a sales call and give them an option to divert to voicemail or accept the call.

if ($callType == “sales”) {

$TwiMLResponse = “<Gather action=\”./agentResponse.php\” numDigits=\”1\”><Say>You have an incoming sales call.</Say><Say>To accept the call, press 1.</Say><Say>To reject the call, press 2.</Say></Gather><Say>Sorry, I didn’t get your response.</Say><Redirect>screen-caller.xml</Redirect>”;


// If this is a support call say to the agent that this is a support call and give them an option to divert to VM or accept the call

if ($callType == “support”) {

$TwiMLResponse = “<Gather action=\”./agentResponse.php\” numDigits=\”1\”><Say>You have an incoming support call.</Say><Say>To accept the call, press 1.</Say><Say>To reject the call, press 2.</Say></Gather><Say>Sorry, I didn’t get your response.</Say><Redirect>screen-caller.xml</Redirect>”;


header(“content-type: text/xml”);


<Response><?php echo $TwiMLResponse; ?></Response>

As you can see from the code, we are passing the type of call: Sales or Support as a variable to this TwiML.

You could if you had a CRM such as Salesforce or vTiger make an API call to the database, querying if the callerID is a known customer and if so pass back details to be relayed to the dialed party – How fantastic would it be to have your CRM provide your agent with the call details before they even connect with the customer.

However, in this example we are going to pass just the message that someone has called the sales or support line and would they like to accept or decline the call.

If the user presses 1, then the call connects both parties together, if the user presses 2 the call is hung up and the original caller is presented with a ‘I’m sorry, no one is available’ – This is where the Dial Action URL comes in to play.

Create a new PHP file called handleDialCallStatus.php

In this file place:


// If the call is due to be hung up be cause the whisper hung up, then we want to redirect the call to Voicemail and capture the Voicemail

$whisperStatus = $_POST[“DialCallStatus”];

if ($whisperStatus == “busy” or “no-answer” or “failed”) {

$TwiMLResponse = “<Say voice=\”alice\”>I am sorry. No one is around at the moment to take your call. Please leave your name and number and someone will get back to you shortly. Thank you!</Say><Record action=\”./handleRecording.php\” maxLength=\”60\” finishOnKey=\”*\” /><Say>I did not receive a recording</Say>”;




$TwiMLResponse = “<Hangup/>”;


header(“content-type: text/xml”);


<Response><?php echo $TwiMLResponse; ?></Response>

This file will work out what happened with our called party. Did they hang up, was the line busy or did the call fail for some reason.

In the event that the any of these three events happen (Reject call, no answer or line busy) we can apologize to the caller and ask them to leave a voicemail.

In this file you can see that we are calling the Record verb, for more information on this please see:


Inside the record verb we are going to reference handleRecording.php  which is going to be the file responsible for generating the email we are going to send once the recording has been completed.

Our final file:  handleRecording.php is the file responsible for picking up the URL of the voicemail file and then do something with it. In this case its going to email me a copy of the recording. However you could put this URL (or file) in to a database or some kind of messaging alert.

The code is:


// Define Email Address and Name

$eMailAddress = “[email protected]”;

$emailName = “YourName”;

$phoneLineName = “Sales HotLine”; // The Name of the phone line called EG is this your Sales Hotline

// Get the details of the call and recording

$recordingURL = $_POST[“RecordingUrl”];

$fromCallerID = $_POST[“From”];

// Get the Time

$humanTime = date(‘H:i d/F’, time());

// Assemble the headers

$headers = “From: Voicemail<[email protected]>\r\n”; //Your Voicemail email address

$headers .= “MIME-Version: 1.0\r\n”;

$headers .= “Content-Type: text/html; charset=ISO-8859-1\r\n”;

// Assemble the MessageBody.

$eMailBody = “Hi $emailName,<br /><br />”;

$eMailBody .= “The $phoneLineName was Called today at: $humanTime<br />”;

$eMailBody .= “The Caller ID was: $fromCallerID<br />”;

$eMailBody .= “The Voicemail is: <br /><br /><audio controls><source src=\”” . $recordingURL. “\”></audio><br /><br />”;

$eMailBody .= “<a href=\”$recordingURL\”>Click here To listen</a><br />”;

$eMailBody .= “Thanks!<br /><br />Voicemail!”;

// Assemble the Mail message

// mail(to,subject,message,headers,parameters);

mail($eMailAddress, “New Voicemail for $phoneLineName”, $eMailBody, $headers);

header(“content-type: text/xml”);



You will need to amend all the bits of this file to fit your network / mail server, including FROM email address, TO email address, your name.

Once you have this setup your good to go!

Now when someone calls your Twilio number:

twilioIncomingCallHander.php will pick up the file, greet the caller and ask them where to direct the call.

When the user selects an option the caller will be played ‘ringing’ sound while Twilio rings the provided number, informs them that a caller is on the line and gives them an option to accept or reject the call.

If the person answering the call accepts the call, we connect both parties together.

If the person answering rejects the call or the call cant be connected, we divert the caller to an answer machine, take a message and then email the message to  an email address.

With this IVR you can add routes and direct calls between your departments quickly and easily.