Twilio call control inside of Salesforce using Visualforce Sites

This is a quick demonstration of how to build a Twilio application entirely using the Visualforce Sites development environment inside of Salesforce.  If you haven’t built an application inside of Saleforce before, you can sign up for a free developer account here. Free force.com accounts give you access to the Visualforce and Sites technology however they are limited to a single “Site” and a single page of TwiML.

If you are new to Visualforce, log into your developer.force.com and click the “Setup” link at the top of the page.  In the “App Setup” section in the bar on the left side, disclose the “Develop” section.  You should see links to Apex Classes, Components, Pages, and Sites.

I am not a Visualforce expert and many of the techniques in this post are rather bruteforce :)  If you have suggestions on how to improve this tutorial please let me know and I’ll update the post accordingly! 



Step 1: Create a Controller class

Once you have logged into developer.force.com and hit the “Setup” link at the top of the page,  select “Apex Classes” link in the left bar and click the “New” button to create a new controller. Paste the following into the text field and hit the Save button.  
public class TwilioPinController {
    public boolean getIfCorrectPin() {
        if (ApexPages.currentPage().getParameters().get(‘Digits’) == ’1234′)
            return true;
        return false;
    }
    public boolean getIfIncorrectPin() {
        if (ApexPages.currentPage().getParameters().get(‘Digits’) != ’1234′)
            return true;
        return false;
    }
}
The system will automatically name the controller “TwilioController” based on the the class name.

Step 2: Create Components

Select “Components” link in the left bar and click the “New” button to create a new component.  Set the Label and Name to “TwilioCorrectPinComponent” and paste the following into the text field and hit the Save button.
<apex:component >
    <Say>You entered the correct pin!  Thank-you</Say>
</apex:component>
Click the “Component” link in the left bar and click the “New” button again to create a second component.   Set the Label and Name to “TwilioIncorrectPinComponent” and paste the following into the text field and hit the Save button.
<apex:component >
    <Say>Incorrect Pin.</Say>
</apex:component>


Step 3: Create Pages

Select “Pages” link in the left bar and click the “New” button to create a new component.  Set the Label and Name to “TwilioStartCall” and paste the following into the text field and hit the Save button.
<apex:page showHeader=”false” contentType=”text/xml”>
<Response>
    <Say>Hello, please enter your four digit pin.</Say>
    <Gather numDigits=”4″ timeout=”15″ action=”/gotpin”/>
</Response>
</apex:page>
Click the “Pages” link in the left bar and click the “New” button again to create a second page.   Set the Label and Name to “TwilioGotPin” and paste the following into the text field and hit the Save button.
<apex:page showHeader=”false” controller=”TwilioPinController” contentType=”text/xml”>
<Response>
    <c:TwilioCorrectPinComponent rendered=”{!ifCorrectPin}” />
    <c:TwilioIncorrectPinComponent rendered=”{!ifIncorrectPin}” />
</Response>
</apex:page>

Step 4: Create Sites

Now for the final step!  Select “Sites” link in the left bar and click the “New” button to create a new site.  Set the Site Label and Site Name to “TwilioStartCall”.
  1. Set the Default Web Address to “index” so the full URL for the app is http://<your-app>-developer-edition.na7.force.com/index
  2. Set the Active Site Home Page to “TwilioStartCall”
Now click the Save button and load http://<your-app>-developer-edition.na7.force.com/index in a web browser.  You should see the TwilioStartCall i.e., “Hello…”.
Now comes the ‘hacky’ part.  Because the PageReference setRedirect() method uses javascript to redirect the browser to another page (not an HTTP 301/307), Twilio can’t use the standard setRedirect() method for navigating a set of sites pages in TwiML.  Instead, we need to create a separate “Site” for each subcomponent of our application.
The next step is to create a new Site for the TwilioGotPin page.  IMPORTANT: free force.com developer accounts are limited to a single Site :(  Click  ”Sites” link in the left bar and click the “New” button to create a new site.  Set the Site Label and Site Name to “TwilioGotPin”.
  1. Set the Default Web Address to “TwilioGotPin” so the full URL for the App is http://<your-app>-developer-edition.na7.force.com/gotpin
  2. Set the Active Site Home Page to “TwilioGotPin”
Now click the Save button and load http://<your-app>-developer-edition.na7.force.com/gotpin in a web browser.  You should see the TwilioStartCall i.e., “Incorrect Pin”.  Now try http://<your-app>-developer-edition.na7.force.com/gotpin?Digits=1234 and you should see “You entered the correct pin!”.
The finally step is to wire the application up to your Twilio phone number.  If you want your users to call a phone number and interact with your application, go the Phone Numbers page in the Twilio account portal and associate http://<your-app>-developer-edition.na7.force.com/index with one of your Twilio phone numbers.  If you want your users to receive calls from your Salesforce application, then set the Url parameter of your outgoing call REST API request to http://<your-app>-developer-edition.na7.force.com/index.  We’ll leave make REST API requests to initiate calls from inside Salesforce for another post.
So that’s all folks.  You can now build call control applications inside of Visualforce sites that interact with your Salesforce data.  One could imagine all kinds of neat applications:
  1. Build a company phone/PBX inside of Salesforce
  2. Create phone numbers for your sales team to input data into Salesforce over the phone  
  3. Build a voice interface for your customers to interact with your Salesforce data
  4. Use Twilio to implement a click-to-call site that lets you record calls with your customers and automatically add recordings Salesforce
  5. Automatic reminder calls for important events inside of Salesforce