This week (Tuesday September 17 – Thursday September 19 2013), our friends at Twilio will be hosting TwilioCon – their annual cloud communications extravaganza. We’ll be there as an event sponsor, which prompted me to look back at my past integrations of Twilio with Force.com, and come up with a new one.
Twilio released their Helper Library for Salesforce back in February 2012, giving Force.com developers an easy way to work with their Voice and SMS APIs. Here’s an excerpt of the sample code I posted back then for sending an SMS from Force.com via the Twilio API:
Pretty straightforward! The more complex integrations demonstrate some nice features of Force.com – receiving and responding to SMS messages uses a public RESTful web service, while automatic call routing shows how Visualforce can generate XML just as easily as HTML.
This time round, I’m going to use Twilio’s Transcription feature to record a voice message, transcribe it to text, look up a contact based on the caller ID and create a Task with the message transcription.
Here’s how I got this working…
The first step was to create a simple TwiML file in Visualforce; this acts as the script when a user dials my Twilio number:
When the call connects, my app says “Hello! Please leave a message”, beeps, and the caller has two minutes of message time (this is the maximum message length if you want the message transcribed). When the call completes, the incoming caller ID and a transcription of the call is sent (via an HTML form post) to the given
The next step was creating an endpoint on Force.com to receive message transcriptions. First, I defined an Apex class as a REST endpoint. I’ll walk through it step by step here; you can also grab the complete Apex class, along with the Visualforce page.
Let’s start with the class definition:
That gives me an endpoint at
/services/apexrest/messagetotask on a Force.com Site. Next I need to define a method that will handle the HTTP POST. Here is the signature, with the relevant annotation:
I verify that the message really came from Twilio, and was not tampered with in transit, via the
TwilioClient.validateRequest() method (the signature validation process is described in more detail here).
Conveniently, the incoming form is parsed by the platform, so I just need to pull the relevant fields from the incoming params (
The next step is to locate a Lead from this phone number, creating a new Lead if we don’t find an existing one:
I’m just matching on the main and mobile phone numbers for Leads here, but you could match on additional fields, match against Contacts, custom objects, whatever you like.
With a Lead ID in hand, it’s a snap to populate a Task record with the relevant data and insert it in the database:
UPDATE: I added a link to the message recording at Twilio – very useful if the caller didn’t speak clearly and the transcription doesn’t make sense!
And that’s it – all done, in less than 40 lines of Apex.The last step was to create a Force.com Site, and make the MessageToTask endpoint publicly visible, as described in detail here. That gave me a publicly accessible endpoint with a URL of the form
https://somesite.force.com/services/apexrest/messagetotask, which I set as the Voice Request URL in the Twilio developer console. A couple of quick calls confirmed that all was working as expected!
Here are a couple of messages logged against a Lead:
And here’s the detail of one of those:
Now that the Task is saved against the Lead, you’d likely want some Workflow or a Trigger to assign the Lead to a Queue for attention. I’ll leave that as an exercise for the reader 🙂
If you are at TwilioCon this week, stop by the Salesforce booth and you can try this out, ask questions about anything Salesforce-related, or just hang out with the Developer Relations team – we’d love to see you!