Kind of a newbie question.... We started using Twilio for SMS. Inbound texts are sent via an HTTP post using webhooks. I'm a bit lost on how to convert the string I get to a structure I can work with. When I use: <cfset requestBody = toString( getHttpRequestData().content ) /> and dump requestbody to a text file I get:
Looks like & is the delimiter.
Thanks in advance for any suggestions.
If the message has been converted to use ASCII characters in place of special characters, Scott's suggestion will work. However, if it is not converted AND if the user who sent the message places an ampersand (&) in the message, using & as the delimiter will fail.
So, before implementing Scott's suggestion, make sure that the message the user sends is converted.
^ _ ^
Yes... The little bit of the string you showed appears to be URL encoded which is why I suggested that function. If it isn't for some reason, then you will need to write a function to parse it properly based on whatever format they are using. Looking at the Twilio documentation, it seems like it should be in the url or form scope of the request, but i have not tried setting up a webhook yet... coincidentally I will be working on a Twilio integration soon though so this would be good to know...TwiML™ for Programmable SMS - Twilio
Out of curiosity... have you tried just dumping out the form scope? <cfdump var="#form#>
Based on the documentation, and what you are seeing in the request body, you may just need to access the data like #Form.ToCountry# #form.SmsMessageSid#, etc
So since I was going to be working with twilio soon anyways I decided to set up a quick webhook and try it. I set up a webhook that emails me dumps of the CGI, URL, and Form scopes whenever the webhook gets a request and the values from Twilio are all in the Form Scope. The following is a list of the struct keys that were in the form scope ( I removed the values because they contain my personal phone number and stuff)
|FORM - struct|
Thanks, Scott. I've only used webhooks with JSON. Never thought it would be a simple as form scope.
no problem.... twilio is a remarkably easy to use API!
In less than an hour I sent a message to my phone from CF and recieved a reply from my phone via a webhook to a cfm file.
I have integrated CF code with MANY APIs over the years, and this one of the least painful.
Twilio actually had a tutorial for sending with CF....
<cffunction access="public" name="sendToTwilio" returntype="string" output="false">
<cfargument name="to" type="string" required="true" />
<cfargument name="body" type="string" required="true" />
<cflock timeout="1" scope="Application" type="readonly" throwontimeout="true">
<cfset twilioaccountSID = APPLICATION.twilio.accountSID>
<cfset twilioauthToken = APPLICATION.twilio.authToken>
<cfset twiliophone = APPLICATION.twilio.phone>
<cfhttp method = "post" result="result" url = "https://api.twilio.com/2010-04-01/Accounts/#twilioaccountSID#/Messages" username = "#twilioaccountSID#" password = "#twilioauthToken#">
<cfhttpparam type = "formfield" name = "From" value = "#twiliophone#">
<cfhttpparam type = "formfield" name = "To" value = "+1#arguments.to#">
<cfhttpparam type = "formfield" name = "Body" value = "#arguments.body#">
<cfif len(result.filecontent) GT 400 >
<cfset APPLICATION.twilio.accountSID = "SID HERE">
<cfset APPLICATION.twilio.authToken = "Token Here">
<cfset APPLICATION.twilio.phone = "Phone Here">
<cfinvoke component="utility" method="sendToTwilio" to="#form.phone#" body="#form.message#" returnvariable="error">
<input type="text" name="phone" id="phone">
<textarea name="message" rows="3" maxlength="160" id="message"></textarea>
<input type="submit" name="Send" id="Send">
didn't see that... but I wrote basically the same function in my cfc in about 25 minutes by just reading the api docs, and then I wrote a simple webhook handler that just sends me the form, url, and cgi scopes when twilio sends the webhook posts. (I replaced the sensitive parts with placeholders like myvalueishere but you'll get the point).
The hardest part was figuring out how to set up the test phone number and where to enter my webhook url for testing.... that took me almost 30 minutes
this.ssid = 'MYSSIDISHERE';
this.authtoken = 'MYTOKENISHERE';
<cffunction name="sendSMS" access="public" hint="retreives tracking information">
<cfargument name="message" type="string" required="true">
<cfargument name="from" type="string" required="true">
<cfargument name="to" type="string" required="true">
<cfhttp url="https://api.twilio.com/2010-04-01/Accounts/#this.ssid#/Messages.json" method="post" username="#this.ssid#" password="#this.authtoken#">
<cfhttpparam type="formfield" name="Body" value="#arguments.message#" >
<cfhttpparam type="formfield" name="From" value="#arguments.from#" >
<cfhttpparam type="formfield" name="To" value="#arguments.to#" >
<cfreturn deserializejson(cfhttp.FileContent) />
<cfinvoke component="com.integrations.twilio" method="sendSMS" returnvariable="results">
<cfinvokeargument name="message" value="this is a test from ColdFusion Code" >
<cfinvokeargument name="from" value="+mytestphonenumberhere" >
<cfinvokeargument name="to" value="+myactualphonenumberhere">
<cfmail to="myemailaddressishere" subject="SMS Webhook" from="myfromaddressishere" type="html">
<cfdump var="#url#" label="URL" expand="no">
<cfdump var="#form#" label="FORM" expand="no">
<cfdump var="#CGI#" label="CGI" expand="no">
I'm curious how you're responding to Twilio when an SMS is received. I can manipulate the form data from the webhook to do what I need it to do but every inbound text generates an error in Twilio's dashboard. It's looking for some type of XML reply.
The provided XML does not conform to the Twilio Markup XML schema. Please refer to the specific error and correct the problem.