Sending SMS Text Messages From Twilio Using ColdFusion

Posted July 16, 2010 at 9:58 AM by Ben Nadel

Tags: ColdFusion

The other day, I blogged about sending SMS text messages to Twilio and responding to them with ColdFusion. Today, I'm going to look into sending SMS text messages from Twilio to a mobile phone using ColdFusion. This happens to be a super simple task; but, there is one big caveat that you need to know: you can only send SMS text messages from one of your rented Twilio phone numbers. For security and spamming reasons, Twilio does not want you to "spoof" other people's cell phone numbers. As such, they only allow your "From" number to be one designated by Twilio.

 
 
 
 
 
 
 
 
 
 

If you have no problem with that detail, the actual sending of the SMS text message from ColdFusion requires nothing more than a simple CFHTTP POST. When sending the SMS text message, you have to POST your information to Twilio's SMS REST resource:

http://api.twilio.com/2008-08-01/Accounts/{SID}/SMS/Messages

In this case, part of the RESTful SMS resource is defined by your username (account number / SID). Both your username and your password (Auth Token) can be obtained from your Twilio dashboard:

 
 
 
 
 
 
Twilio Username (SID) And Password (Auth Token) Are Provided On Your Twilio Dashboard. 
 
 
 

When posting to the Twilio REST web service, all of your HTTP requests must be authenticated. This means that you have to pass your username (SID) and password (Auth Token) as credentials along with every CFHTTP request. The requests can be done over either HTTP or HTTPS. Everything in Twilio seems to be case sensitive; as such, all of your form field names posted via CFHTTPParam tags need to be in upper-camel-case. If not, Twilio will not see them in the post data.

That's pretty much all you need to know, so let's look at some ColdFusion code:

  • <!---
  • Set the Twilio Accound credentials - this will be needed to
  • make HTTP posts to the Twilio REST web service. Your username is
  • your "Account SID" and your password is your "Auth Token" which
  • can be obtained on the dashboard.
  • --->
  • <cfset twilioUsername = "********************************" />
  • <cfset twilioPassword = "********************************" />
  •  
  • <!---
  • Set the outgoing phone number. For security / spamming reasons,
  • this FROM number must be one of the numbers you rented from
  • the Twilio service. Otherwise, you'd be able to spoof other
  • people's phone numbers.
  • --->
  • <cfset twilioFrom = "917-791-2120" />
  •  
  • <!---
  • Define the Twilio SMS REST resource. This can be in either
  • plain HTTP or Secure HTTPS (the extra security is up to you).
  • --->
  • <cfset twilioSMSResource = (
  • "http://api.twilio.com/2008-08-01" &
  • "/Accounts/#twilioUsername#/SMS/Messages"
  • ) />
  •  
  •  
  • <!--- ----------------------------------------------------- --->
  • <!--- ----------------------------------------------------- --->
  •  
  •  
  • <!--- Param the form values. --->
  • <cfparam name="form.to" type="string" default="" />
  • <cfparam name="form.message" type="string" default="" />
  •  
  •  
  • <!---
  • Check to see if we have enough information to send out the
  • SMS text message. Twilio will accept phone numbers with any kind
  • of formatting (including or excluding the optional +1 for US
  • phone numbers). But, for our purposes, we are going to only
  • accept 10-digit phone numbers.
  • --->
  • <cfif (
  • reFind( "^\d{10}$", form.to ) &&
  • len( form.message )
  • )>
  •  
  • <!---
  • Post our outgoing SMS text message request to the Twilio
  • SMS REST resource.
  •  
  • NOTE: The Form field names ***ARE*** case SENSITIVE. They
  • must all be in initial-camel-case according to the
  • documentation. If they are not, the REST web service will
  • not see them in the FORM post.
  •  
  • NOTE: By default, the Twilio response will be an XML packet.
  • You can create a JSON response by appending ".json" to the
  • Twilio resource URL.
  • --->
  • <cfhttp
  • result="post"
  • method="post"
  • url="#twilioSMSResource#"
  • username="#twilioUsername#"
  • password="#twilioPassword#">
  •  
  • <!--- Post the FROM number. --->
  • <cfhttpparam
  • type="formfield"
  • name="From"
  • value="#twilioFrom#"
  • />
  •  
  • <!---
  • Post the TO number. This is going to be recipient of
  • our outgoing text message.
  • --->
  • <cfhttpparam
  • type="formfield"
  • name="To"
  • value="#form.to#"
  • />
  •  
  • <!--- Post the SMS text message body. --->
  • <cfhttpparam
  • type="formfield"
  • name="Body"
  • value="#form.message#"
  • />
  •  
  • <!---
  • Post the callback URL for the Twilio to use once the SMS
  • message is sent. When you post an SMS request, it gets
  • queued on the Twilio servers. Once it gets processed,
  • this URL (StatusCallback) will be POSTed a resposne.
  • --->
  • <cfhttpparam
  • type="formfield"
  • name="StatusCallback"
  • value="http://www.bennadel.com/......./callback.cfm"
  • />
  •  
  • </cfhttp>
  •  
  •  
  • <!---
  • The CFHTTP response should be returning a 201 status code.
  • This indicates that the request was successful and that the
  • SMS Message was created. A 201 status code includes a
  • "location" for said SMS text message resource in the response
  • header.
  •  
  • [CFHTTP Response].responseHeader.location
  •  
  • Example:
  • /2008-08-01/Accounts/{SID}/SMS/Messages/{NEW-SMS-RECORD-ID}
  •  
  • This is the same as the response we got back in the
  • fileContent, however its content will be updated once the
  • SMS request has been fully processed.
  • --->
  •  
  •  
  • <!--- Redirect the user back to the form page. --->
  • <cflocation
  • url="#cgi.script_name#?success"
  • addtoken="false"
  • />
  •  
  • </cfif>
  •  
  •  
  • <!--- ----------------------------------------------------- --->
  • <!--- ----------------------------------------------------- --->
  •  
  •  
  • <cfoutput>
  •  
  • <!DOCTYPE HTML >
  • <html>
  • <head>
  • <title>Sending SMS Text Messages With Twilio And ColdFusion</title>
  • </head>
  • <body>
  •  
  • <h1>
  • Sending SMS Text Messages With Twilio And ColdFusion
  • </h1>
  •  
  • <!--- Check to see if we have the success flag. --->
  • <cfif structKeyExists( url, "success" )>
  •  
  • <p>
  • <strong>Your SMS text message has been sent!</strong>
  • </p>
  •  
  • </cfif>
  •  
  • <form method="post" action="#cgi.script_name#">
  •  
  • <p>
  • From:
  • <strong>Twilio</strong> -
  • <em>(rented Phone Number)</em>.
  • </p>
  •  
  • <p>
  • To:<br />
  • <input type="text" name="to" size="20" />
  • </p>
  •  
  • <p>
  • SMS Text Message:<br />
  • <input type="text" name="message" size="70" maxlength="140" />
  • </p>
  •  
  • <p>
  • <input type="submit" value="Send SMS Message" />
  • </p>
  •  
  • </form>
  •  
  • </body>
  • </html>
  •  
  • </cfoutput>

When you post to the Twilio SMS resource, you should get back a "201 Created" status code. This indicates that your SMS record has been successfully created on the Twilio server. The fileContent of the CFHTTP response will contain the details of that newly created SMS record:

  • <?xml version="1.0"?>
  • <TwilioResponse>
  • <SMSMessage>
  • <Sid>SM8b4445c73dbfab696769d5217ac706a6</Sid>
  • <DateCreated>Thu, 15 Jul 2010 16:54:09 -0700</DateCreated>
  • <DateUpdated>Thu, 15 Jul 2010 16:54:09 -0700</DateUpdated>
  • <DateSent/>
  • <AccountSid>*********************************</AccountSid>
  • <To>9175557281</To>
  • <From>9177912120</From>
  • <Body>Hey my man - what's going on?</Body>
  • <Status>queued</Status>
  • <Flags>4</Flags>
  • <Price/>
  • </SMSMessage>
  • </TwilioResponse>

As you can see, the "status" node of the XML response indicates that the SMS message has been queued. If you want to know when your SMS message has been fully processed (sent to the recipient), you can provide an optional StatusCallback URL in your CFHTTP post. If provided, Twilio will post the following FORM data to your callback URL once the SMS text message has been sent:

  • ACCOUNTSID *********************************
  • FROM 9177912120
  • SMSSID SM8b4445c73dbfab696769d5217ac706a6
  • SMSSTATUS sent
  • TO 9175557281

As you can see here, the new "status" value indicates that the message has been sent to the targeted mobile device.

By default, all Twilio REST responses are returned as XML packets. You can, however, change the return format by appending various file extensions to the resource URL. At this time, three additional formats are supported:

  • .csv - Comma-separated values.
  • .json - Javascript Object Notation.
  • .html - Standard web page markup.

This allows you to work with whatever data format you feel most comfortable. If you use the .html file extension, Twilio returns valid XHTML source code that you can output directly to the browser.

If your targeted mobile phone user tries to respond to your outgoing SMS text message, Twilio will simply use the SMS end point that you have defined in your Phone number configuration.

That's all there is to it. Twilio makes sending SMS text messages with ColdFusion just as easy as it does receiving SMS text messages. But, to be completely honest, I am little bummed that I have to use a Twilio phone number as my outgoing mobile number. I completely understand why this restriction would exist; but, it would be cool is if I could create a list of "verified" outgoing SMS phone numbers from within my dashboard. This concept exists for outgoing Twilio calls (Caller ID), but not exist for SMS text messages. Perhaps this is a feature that they will be adding in the future?




Reader Comments

Jul 16, 2010 at 2:46 PM // reply »
74 Comments

Great post. It seems odd to pass your username and password plain text in the http request using http. Why would you ever want to use http?


Jul 16, 2010 at 2:52 PM // reply »
11,238 Comments

@Justin,

You're asking as to why I would use HTTP vs. HTTPS? Good question. I had started out with HTTPS. The only reason I think I switched over to HTTP was simply to see if the request would work. I just neglected to switch back to httpS afterward.


Jul 16, 2010 at 3:07 PM // reply »
74 Comments

Cool. Have yourself a good weekend getting married, becoming a warrior, mastering jQuery, working out, becoming selfless or whatever else it is that you're doing.


Jul 16, 2010 at 3:20 PM // reply »
11,238 Comments

@Justin,

Ha ha ha, thanks - you have a great weekend as well.


Aug 8, 2010 at 4:03 AM // reply »
1 Comments

hello bro, I've downloaded it and now trying on my localhost.. :)
thx for sharing..
hope we can be a friend.. :D


Jul 7, 2011 at 4:34 PM // reply »
1 Comments

This is great. Thanks for taking the time to explain. There is an interesting problem. Everything works if you send a single word or string without a space; however if you send a sentence the text does not get processed by twilio. i.e Message = "Test" or "Help" works perfectly within the code, if you send "Help Me" or any other sentence construct it does not process. Any thoughts?


Nov 9, 2011 at 6:21 PM // reply »
2 Comments

Matt,
I solved the issue where spaces in the message body were breaking things by simply adding charset="utf-8" to the cfhttp code as follows:

  • <cfhttp
  • result="post"
  • method="post"
  • charset="utf-8"
  • url="#twilioSMSResource#"
  • username="#twilioUsername#"
  • password="#twilioPassword#">

I also updated the URL in the SMSResource to the newer API as follows:

Hope this helps!


sam
Nov 21, 2011 at 9:45 PM // reply »
1 Comments

Hi Sir Ben, i was about to incorporate this idea to my thesis study, how can i buy twilio phone numbers here in the philippines... i was creating enrollment system with sms technology, students will receive text messages at the end of every semester containing their final grades... Thank you for your kindness..

respectfully yours,
sam


Dec 20, 2011 at 3:49 PM // reply »
5 Comments

This works for a single text message, but what about if you want to send it to multiple numbers store in a database table?

I tried querying my db table with the store numbers and wrapping the <cfhttp> tag with the cfoutput query like this but nothing happens upon executing the page.

<cfoutput query="staff">

<cfhttp
result="post"
method="post"
url="#twilioSMSResource#"
username="#twilioUsername#"
password="#twilioPassword#">

.....

</cfoutput>


May 31, 2012 at 5:12 PM // reply »
4 Comments

This is great stuff Ben, but like Omar, I was having some trouble with sending out a mass message to a database of cell numbers (ie - people signed up to receive a text when a ballgame is cancelled).

#1. If you're not using the statuscallback, don't use it... it's optional anyhow. If you're using an invalid statuscallback and you're cflooping through a query you'll send all your texts to the same person because your callback is trying to do it's job and can't. I honestly don't need to know if a text was or was not received, so I just put the site's domin in that field as a default value... not a good idea; remove the field altogether. For more info on sending SMS:
https://www.twilio.com/docs/api/rest/sending-sms

#2. For some odd reason, cflooping over a query for each RESTful cfhttp takes a long time... like my submission was timing out after 43 texts. I have over 100 in the database so this was a problem. Overriding the default timeout value as such:

  • <cfsetting requesttimeout="600">

fixed my problem. And although the client still hangs/loads while it completes the task, at least it's sending everyone the text. I just wish there was a way around this... like including all the phone numbers you want to send the same message to in the same RESTful post to Twilio. If there's a way to do this I've yet to figure it out. Bear in mind that Twilio also does not simultaneously send out texts. The numbers will enter a queue and send out at a maximum pace of 1 per second, which is perfectly fine for what I'm using it for.


May 31, 2012 at 5:47 PM // reply »
4 Comments

Also, just wanted to point out something to save anyone else from trying:

  • <cfhttpparam type="formfield" name="To" value="#valueList(query.column, ",")#" />

A comma delimited list does NOT work when sending mass texts. you will need to loop through each request, one by one:

  • <cfloop query="yourQuery">
  • <cfhttp result="post" method="post" charset="utf-8" url="#twilioSMSResource#" username="#twilioUsername#" password="#twilioPassword#">
  • <cfhttpparam type="formfield" name="From" value="#twilioFrom#" />
  • <cfhttpparam type="formfield" name="To" value="#getNumbers.phoneNumber#" />
  • <cfhttpparam type="formfield" name="Body" value="Little League games for today have been cancelled. DO NOT REPLY TO THIS NUMBER." />
  • </cfhttp>
  • </cfloop>


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 17, 2013 at 7:42 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
Ben - thanks so much for posting these Angular articles and findings, they've been a huge help towards learning one of the more 'complex' JavaScript frameworks out there (IMO). I have been using Angu ... read »
May 16, 2013 at 5:01 PM
UPDATE: Parsing CSV Data Files In ColdFusion With csvToArray()
Your code was the closest thing I've found to obtaining some direction for converting ISO fields to values that CF can translate properly. Thank you for posting! ... read »
May 15, 2013 at 10:37 PM
Very Simple Pusher And ColdFusion Powered Chat
hi id making plz easy ... read »
May 15, 2013 at 6:07 PM
Making SOAP Web Service Requests With ColdFusion And CFHTTP
Ben, you once again saved my bacon at work. Thank you, thank you, thank you! ... read »
May 15, 2013 at 4:15 PM
What If All User Interface (UI) Data Came In Reports?
@Josh, Thanks! @Ben, I definitely recommend the David West book "Object Thinking" I've been quoting from. It goes deeply into the philosophy and history of OO programming. His breadth ... read »
May 15, 2013 at 11:36 AM
Ask Ben: Print Part Of A Web Page With jQuery
I found this helpfull when you need to keep (refresh) the original parent page after closing the iframe child print dialog (Hoping you're not using a form at this time so it won't submit again): On ... read »
May 14, 2013 at 7:13 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, If there's any books you'd recommend on the subject of domain modelling, I'd love to hear it. I just downloaded the free PDF of "Domain Driven Design Quickly". Figured I'd give it ... read »
May 14, 2013 at 6:57 PM
The UX Of Prototyping: Low-Fidelity Is The New High-Fidelity
@Phillip, I'm not sure I follow what you mean? Are you saying that you looked at the list of widgets provided by the jQuery UI and let that be your style guide? ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools