Salesforce + Twilio + Receiving Incoming Texts

Recently, I’ve been toying with mashing up Salesforce and Twilio’s SMS capabilities.  For those of you who don’t know what Twilio is, you should check it out.  Twilio is a web service that gives you the ability to integrate voice and SMS into your apps and they have a simple API and documentation.  This is a pretty handy service and there are a lot of use case scenarios where this functionality makes sense.  For example:

  • Text-based marketing to leads/contacts.
  • Notification of certain events to sales reps or field personnel.
  • A text-based web service that runs on Force.com.

Kyle Roche and Aslam Bari put together a great library to help developers use Twilio with the Force.com platform.  You can find it here on the Force.com Code Share.

The best way to get started is to create a free Twilio trial account so you can get your API credentials and sandbox info.  The API for sending texts is here, and with Kyle and Aslam’s library it is really simple to start sending texts from your Salesforce account.

It basically works like this.

If you’re already using Twilio to send SMS, have you set up a way to process an incoming message?  Perhaps you’re sending info to prospects and you want them to reply “Yes” if they’re interested.  Then, you want to trigger some workflow from that incoming text.  Well, Twilio will accept incoming texts and you can configure where you want the SMS info to be sent.  Basically, Twilio receives incoming SMS messages and then sends an HTTP request to you with a number of parameters.  Three of the most important parameters are From (the number of the message sender), To (your Twilio number), and Body (the contents of the message).  Here is the documentation for how Twilio handles incoming texts.

In order to process these incoming SMS messages you first need an Apex Controller and Visualforce page.  The request will get sent to this page and the parameters will be stored.  Using the stored parameters we’ll create a closed task and associate it with the appropriate Contact.   The code for the Controller and VF page are below.

/*********************************************************************************
This controller will grab the three parameters From, To, and Body when the Twilio
HTTP request is made.  Once we have the From number (which is the sender's number)
we can use it to query Salesforce for a Contact matching that (presumably) mobile
number.  When we've found a matching Contact we create a closed Task to record the
message of the incoming text, and it will now show up under the Activity History
related list for this Contact
*********************************************************************************/
public with sharing class TwilioRequestControllerContacts {

	// Set instance variables to capture the To, From, and Body Parameters that Twilio sends in the HTTP request
	public String fromNumber = ApexPages.currentPage().getParameters().get('From');
	public String toNumber = ApexPages.currentPage().getParameters().get('To');
	public String body = ApexPages.currentPage().getParameters().get('Body');
	public PageReference response = new PageReference('http://your_site_url/TwilioResponse');

	// This is the initial method that gets called when the TwilioResponse page loads
	public PageReference init()
	{
		// Helpful with debugging
		System.debug('FROM: ' + fromNumber);
		System.debug('TO: ' + toNumber);
		System.debug('BODY: ' + body);

		// If we capture all of the parameters successfully, call the saveIncomingText() method
		if(fromNumber != null && toNumber != null && body != null)
		{
			response = saveIncomingText();
			return response;
		}

		return null;
	}

	private PageReference saveIncomingText()
	{
		// Call the method to clean the incoming phone number
		String cleanFromNumber = formatPhone(fromNumber);

		// Query the student whose phone number matches the incoming phone number
		List <Contact> contactList = [SELECT Id, FirstName, LastName
									     FROM Contact
									     WHERE MobilePhone =: cleanFromNumber limit 1];

		// Move forward only if we find at least one match.
		if(contactList.size() > 0)
		{
	    	for (Contact contact : contactList)
	    	{
				System.debug(contact.FirstName + ' ' + contact.LastName);

				// Create a new Task to store the record of the incoming text, then attach it to the appropriate Contact
	    		Task text = new Task();
	    		text.Subject = body;
	    		text.WhoId = contact.Id;
	    		text.Status = 'Completed';
	    		text.Type = 'Incoming Text';

	    	    // Insert the Incoming Text object and return the response page.
	    	    try
	    		{
	    		   insert text;
	    		   return response;
	    		}
	    		catch(DmlException e)
	    		{
	    		  System.debug('INSERT TASK FAILED: ' + e);
	    		}
	    	}
		}

	    return response;
	}

	// Twilio sends the phone number as +15555551234.  We have to reformat the string to (555) 555-1234
	private String formatPhone(String fromNumber)
	{
		String areaCode = fromNumber.substring(2,5);
		String prefix = fromNumber.substring(5,8);
		String last4 = fromNumber.substring(8);
		String formattedPhone = '(' + areaCode +')' + ' ' + prefix + '-' + last4;
		System.debug('FORMATTED PHONE IS: ' + formattedPhone);
		return formattedPhone;
	}
}
<!--Visualforce Page-->
<!--This is a simple page that calls the init method when it loads-->
<apex:page controller="TwilioRequestControllerContacts" action="{!init}" showHeader="false" sidebar="false">
   <apex:pageBlock title="Twilio Request Listener"></apex:pageBlock>
</apex:page>

The next step is to give your Site access to this page and controller. If you’ve not worked with Salesforce Sites it is pretty simple to set one up.  Utilizing Sites is how we can expose our Visualforce page to the outside world, thus letting the Twilio HTTP request hit our page.  You should also make sure that your Public Access Settings on the Site give at least read access to the Contact object.

The last step is to tell Twilio where to send the request.  Log in to your Twilio account and click ‘My Account’.  Under the heading Developer Tools you’ll see a field titled SMS URL.  Paste the full URL path to your Visualforce page into that field.

As always, any feedback or questions are welcome.  If you’ve implemented a different solution to handle this issue I’d love to hear about it, too.

Tags: , ,

Salesforce + Twilio + Receiving Incoming Texts

7 Responses

  1. Great article Clint!

    Jeff Douglas February 9, 2011 at 3:55 am #
  2. Thanks much Jeff!

    Clint Lee February 11, 2011 at 1:48 am #
  3. We will need to develop SMS capability whereby community moderators can send/receive SMS to/from contacts (we are working in sub-Saharan Africa) where many of those we are supporting can only communicate using SMS.

    Are there considerations to think through if we decide to reuse your code in the context of a community?

    Hamish Drewry June 19, 2015 at 1:35 pm #
  4. Hi,

    I am not being able to get this to work. i have setup the VF page, the site and the SMS URL as per your suggestion. However, I cannot capture the incoming message from Twilio. Under Alert section in Twilio it is giving me an error: 12200 – Schema validation warning. On checking with the Twilio customer support they are saying that the response for the HTTP post that Twilio does on Salesforce needs to be in TwiML.

    Can you please suggest how to solve this issue?

    Debarshi Barat July 14, 2015 at 12:07 am #
  5. Hi Clint,

    I want to have SMS sent from my instance. Below are my requirement for it:
    1. When a field is updated on a record, the related contact on the record should get a SMS on his/her number.
    2. This contact will reply to the message and depending on the keywords, a workflow rule should be called for updating a field and a SMS should be sent to owner after the updates are done.
    Ex: If the contact replies as YES, a field should be updated and a SMS should be sent to the third Contact.

    Please let me know how can I proceed with this.

    I am a beginner to Salesforce development.

    Rushank September 7, 2015 at 6:03 am #
  6. Hi Debarshi Barat,
    I am also facing the same issue. Could you please let me know how did you resolve the issue.
    It would be of great help!

    Thanks in advance!

    Narasimhan November 12, 2015 at 2:32 am #
Trackbacks/Pingbacks
  1. Tweets that mention Salesforce + Twilio + Receiving Incoming Texts | Clint Lee -- Topsy.com - February 8, 2011

    […] This post was mentioned on Twitter by Reid Carlberg, Force by Design. Force by Design said: Learn how to receive texts with #Salesforce! @ClintSLee great example of #SFDC #Twilio integration on #Force platform. http://fbd.bz/eMwkts […]

Leave a Reply