Sending Text Messages (SMS) With ColdFusion And CFMail

Posted May 9, 2007 at 10:27 AM

Tags: ColdFusion

I have never played around with sending text message with ColdFusion (or anything non-cell-phone related), so I thought this morning would be a fun time to try it out. My initial thought was to try and use CFHttp to submit the text message forms provided on the individual carrier sites. I know that there are different ways to do it, but I figured I would give this a go first. Here is the CFHttp and CFHttpParam code that I used to mimic the form being submitted on Verizon's mobile site:

 Launch code in new window » Download code as text file »

  • <cfhttp
  • url="https://www.vtext.com/customer_site/jsp/disclaimer.jsp"
  • method="POST"
  • useragent="Mozilla / Firefox"
  • result="objHTTP">
  •  
  •  
  • <!--- Set referrer. --->
  • <cfhttpparam
  • type="CGI"
  • name="referer"
  • value="https://www.vtext.com/customer_site/jsp/messaging_lo.jsp"
  • encoded="false"
  • />
  •  
  •  
  • <!--- Include the original hidden form fields. --->
  •  
  • <cfhttpparam
  • type="FORMFIELD"
  • name="trackResponses"
  • value="No"
  • />
  •  
  • <cfhttpparam
  • type="FORMFIELD"
  • name="Send.x"
  • value="Yes"
  • />
  •  
  • <cfhttpparam
  • type="FORMFIELD"
  • name="translatorButton"
  • value=""
  • />
  •  
  • <cfhttpparam
  • type="FORMFIELD"
  • name="showgroup"
  • value="n"
  • />
  •  
  • <cfhttpparam
  • type="FORMFIELD"
  • name="DOMAIN_NAME"
  • value="@vtext.com"
  • />
  •  
  •  
  • <!--- Visible form fields. --->
  •  
  • <!--- To (number). --->
  • <cfhttpparam
  • type="FORMFIELD"
  • name="min"
  • value="XXXXXXXXXX"
  • />
  •  
  • <!--- Text message Content. --->
  • <cfhttpparam
  • type="FORMFIELD"
  • name="text"
  • value="This is a test ColdFusion submission."
  • />
  •  
  • <!--- Not sure what this is??? --->
  • <cfhttpparam
  • type="FORMFIELD"
  • name="message"
  • value=""
  • />
  •  
  • <!--- From (name or number). --->
  • <cfhttpparam
  • type="FORMFIELD"
  • name="subject"
  • value="Ben Nadel"
  • />
  •  
  • <!--- Reply-to number. --->
  • <cfhttpparam
  • type="FORMFIELD"
  • name="sender"
  • value="XXXXXXXXXX"
  • />
  •  
  • <!--- Call back number. --->
  • <cfhttpparam
  • type="FORMFIELD"
  • name="callback"
  • value=""
  • />
  •  
  • <!--- Message priority. --->
  • <cfhttpparam
  • type="FORMFIELD"
  • name="type"
  • value="0"
  • />
  •  
  • <!---
  • Count field (available characters). Your Message,
  • Reply To Address and Callback Number fields all
  • count toward the 160-character message length.
  • --->
  • <cfhttpparam
  • type="FORMFIELD"
  • name="count"
  • value="#(160 - 37)#"
  • />
  •  
  • <!--- Form buttons. --->
  •  
  • <cfhttpparam
  • type="FORMFIELD"
  • name="Send"
  • value="Send"
  • />
  •  
  • <cfhttpparam
  • type="FORMFIELD"
  • name="Reset"
  • value="Clear"
  • />
  •  
  • <cfhttpparam
  • type="FORMFIELD"
  • name="disclaimer_submit"
  • value="disclaimer_submit"
  • />
  •  
  • </cfhttp>

That is HUGE and was a bit of a pain to create (Verizon has a confirmation page before you actually send it through). And that's just for one site! Imagine having to do that for each carrier? No thanks.

The other option is to use the mobile email addressed that most carriers provide. With these numbers, we can use ColdFusion and CFMail to send a text message to a mobile device. The first trick was to round up all the email addresses that the carriers use. With the use of Google, this was a fairly easy task. The next step was just setting up a simple web form:

 Launch code in new window » Download code as text file »

  • <!--- Kill extra output. --->
  • <cfsilent>
  •  
  • <!--- Param the form variable. --->
  • <cfparam
  • name="FORM.from"
  • type="string"
  • default=""
  • />
  •  
  • <cfparam
  • name="FORM.to"
  • type="string"
  • default=""
  • />
  •  
  • <cfparam
  • name="FORM.provider"
  • type="string"
  • default=""
  • />
  •  
  • <cfparam
  • name="FORM.subject"
  • type="string"
  • default=""
  • />
  •  
  • <cfparam
  • name="FORM.message"
  • type="string"
  • default=""
  • />
  •  
  • <cftry>
  • <cfparam
  • name="FORM.submitted"
  • type="numeric"
  • default="0"
  • />
  •  
  • <cfcatch>
  • <cfset FORM.submitted = 0 />
  • </cfcatch>
  • </cftry>
  •  
  •  
  • <!---
  • This is the data validation error array. We will
  • use this to keep track of any data errors.
  • --->
  • <cfset arrErrors = ArrayNew( 1 ) />
  •  
  •  
  • <!---
  • Let's build up a list of providers. Each provider
  • will have a differen domain name for the mail usage.
  • --->
  • <cfset objProviders = StructNew() />
  • <cfset objProviders[ "Verizon" ] = "vtext.com" />
  • <cfset objProviders[ "Sprint PCS" ] = "messaging.sprintpcs.com" />
  • <cfset objProviders[ "T-Mobile" ] = "tmomail.net" />
  • <cfset objProviders[ "Cingular" ] = "cingularME.com" />
  • <cfset objProviders[ "NexTel" ] = "messaging.nextel.com" />
  • <cfset objProviders[ "Virgin Mobile" ] = "vmobl.com " />
  •  
  •  
  • <!--- Check to see if the form has been submitted. --->
  • <cfif FORM.submitted>
  •  
  • <!---
  • Strip out non-numeric data from To field. For
  • now, we are only goint to allow phone numbers.
  • --->
  • <cfset FORM.to = FORM.to.ReplaceAll(
  • "[^\d]+",
  • ""
  • ) />
  •  
  • <!--- Validate form fields. --->
  •  
  • <cfif NOT Len( FORM.from )>
  • <cfset ArrayAppend(
  • arrErrors,
  • "Please enter your FROM number"
  • ) />
  • </cfif>
  •  
  • <cfif NOT Len( FORM.to )>
  • <cfset ArrayAppend(
  • arrErrors,
  • "Please enter your TO number"
  • ) />
  • </cfif>
  •  
  • <cfif NOT Len( FORM.message )>
  • <cfset ArrayAppend(
  • arrErrors,
  • "Please enter your text message"
  • ) />
  • </cfif>
  •  
  •  
  • <!---
  • Check to see if we have any form validation
  • errors. If we do not, then we can process
  • the form.
  • --->
  • <cfif NOT ArrayLen( arrErrors )>
  •  
  • <!---
  • Check to see which provider was selected. If
  • no provider was selected then we are just gonna
  • try to loop over all of them.
  • --->
  • <cfif NOT StructKeyExists( objProviders, FORM.provider )>
  •  
  • <!---
  • Set the provider value to all keys in
  • the provider struct. That will allow us
  • to loop over them.
  • --->
  • <cfset FORM.provider = StructKeyList(
  • objProviders
  • ) />
  •  
  • </cfif>
  •  
  •  
  • <!---
  • Loop over the provider values to send the
  • SMS text message.
  • --->
  • <cfloop
  • index="strProvider"
  • list="#FORM.provider#"
  • delimiters=",">
  •  
  •  
  • <!---
  • When sending out the CFMail, be sure to put
  • the full email address in the TO including
  • the provider-specific domain.
  • --->
  • <cfmail
  • to="#FORM.to#@#objProviders[ strProvider ]#"
  • from="#FORM.from#"
  • subject="New Message"
  • type="text">
  •  
  • <!---
  • Set the text part of the message. This
  • allows us to sent a text message without
  • destroying our beloved tabbing.
  • --->
  • <cfmailpart
  • type="text/plain"
  • >#FORM.message#</cfmailpart>
  •  
  • </cfmail>
  •  
  •  
  • </cfloop>
  •  
  •  
  • <!---
  • Send the user back to the same page with a
  • new form (mostly so that they do not re-submit
  • the form twice). I like to put in a RandRange()
  • sometimes, just to make sure there is no
  • strange caching taking place.
  • --->
  • <cflocation
  • url="#CGI.script_name#?#RandRange( 1, 100 )#"
  • addtoken="false"
  • />
  •  
  • </cfif>
  •  
  • </cfif>
  •  
  • </cfsilent>
  •  
  •  
  • <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  • <html>
  • <head>
  • <title>
  • Sending Text Messages (SMS) With ColdFusion
  • And CFMail
  • </title>
  • </head>
  • <body>
  •  
  • <cfoutput>
  •  
  • <!---
  • Check to see if we have any form validation
  • errors to display.
  • --->
  • <cfif ArrayLen( arrErrors )>
  •  
  • <p>
  • Please review the following issues:
  • </p>
  •  
  • <ul>
  • <cfloop
  • index="intError"
  • from="1"
  • to="#ArrayLen( arrErrors )#"
  • step="1">
  •  
  • <li>
  • #arrErrors[ intError ]#
  • </li>
  •  
  • </cfloop>
  • </ul>
  •  
  • </cfif>
  •  
  • <form action="#CGI.script_name#" method="post">
  •  
  • <!---
  • This is our hidden value to flag that the
  • form has been submitted (and is NOT loading
  • for the first time).
  • --->
  • <input type="hidden" name="submitted" value="1" />
  •  
  •  
  • <label for="from">
  • From:
  •  
  • <input
  • type="text"
  • name="from"
  • id="from"
  • value="#FORM.from#"
  • />
  • </label>
  • <br />
  •  
  • <label for="to">
  • To:
  •  
  • <input
  • type="text"
  • name="to"
  • id="to"
  • value="#FORM.to#"
  • />
  • </label>
  •  
  • <select name="provider">
  • <option value="">-- Not Sure --</option>
  •  
  • <!--- Loop over providers. --->
  • <cfloop
  • index="strName"
  • list="#StructKeyList( objProviders )#"
  • delimiters=",">
  •  
  • <option value="#strName#"
  • <cfif (FORM.provider EQ strName)>
  • selected="true"
  • </cfif>
  • >#strName#</option>
  •  
  • </cfloop>
  • </select>
  • <br />
  •  
  • <label for="message">
  • Message:
  •  
  • <input
  • type="text"
  • name="message"
  • id="message"
  • value="#FORM.message#"
  • maxlength="160"
  • />
  • </label>
  • <br />
  •  
  • <input
  • type="submit"
  • value="Send SMS Text Message"
  • />
  •  
  • </form>
  •  
  • </cfoutput>
  • </body>
  • </html>

The idea here is that you put in the To/From information and select the provider. Since each provider has it's own email address format, this will help us figure out which address format to use. If you are not sure which provider the recipient is using, the processing will loop over all the providers and send a CFMail message. If that works, why let them select a provider at all? Well, because sending potentially bad emails to multiple providers just feels wrong, doesn't it?

So, I know that this has all been done before (probably years ago), but I thought I would give it a go, see how it works. This is an easy way to send SMS text messages through ColdFusion if you do not have access to ColdFusion's event gateways (which I do not) and if I ever need to do this for some application, at least I have the code that will do it.

Download Code Snippet ZIP File

Comments (19)  |  Post Comment  |  Ask Ben  |  Permalink  |  Other Searches  |  Print Page





Reader Comments

>> So, I know that this has all been done before (probably years ago)

Yep. I messed with it a few years ago using http. I had it integrated with a calendar I set up to remind me of meetings and such. Now I use Yahoo as they have text messaging built in. They have a better calendar too.

Now I just use it to find my cell phone. ;)

Posted by Cozmo on May 9, 2007 at 11:07 AM


When you say you just use Yahoo, are you talking about an API for sending text messages? Or do you just mean as part of their calendar system?

Posted by Ben Nadel on May 9, 2007 at 11:11 AM


Ooooh... they have an API? I *love* API's. There goes this weekend. ;)

But yeah, just the calendar app. I moved all my stuff to Google (gmail, docs, etc) but I haven't messed with their calendaring system yet.

Posted by Cozmo on May 9, 2007 at 11:32 AM


Nice code. While using event gateways certainly seems like the "right" way to send SMS messages even a company like Southwest uses the email method you detail.

Posted by Sam Farmer on May 9, 2007 at 12:09 PM


Great article, Ben. One thing that is important to note is that the various carriers place limits on the number of characters that could be in the text message. For example, Verizon Wireless restricts the length of the message to144 characters. To make matters more confusing, the different carriers have different upper limits to boot :(

At a minimum, make sure your app checks for the number of characters for the given provider, or always checks that it's fewer than the carrier with the lowest maximum message length.

Posted by Christian Ready on May 9, 2007 at 12:17 PM


@Christian,

Excellent point! And to even complicate things more, I believe that the Subject of the outgoing email is also included as part of the character limit (as it becomes part of the final text message).

As a lame-ass fix, I put a MaxLength of the Message field, but it is 160. Clearly this would break if maxed out since it doesn't take the Subject into account or the differences in carrier.

I guess the next step would be to figure out the limit for the different carriers, or to pick a lowest common value, such as 100 characters, that should satisfy them all.

Posted by Ben Nadel on May 9, 2007 at 12:24 PM


Take a look at http://www.livejournal.com/tools/textmessage.bml?mode=details

It lists *all* of the SMS carriers and their message restrictions. Basically, most carriers specify an upper limit for the entire message and a sub-limit on the "from" field.

So, for the example of Verizon Wireless, it says that the message can only be 140 characters but of that 140, the from field can occupy no more than 34 characters.

I'd say that for a US-based audience, you need to keep the entire message to 120 characters but for an international audience, you probably want to be even more conservative and stay under 90.

Posted by Christian Ready on May 9, 2007 at 12:46 PM


Holy cow, that's like the most bad-ass text message resource link ever :)

Thanks a lot for bringing that to my attention. It is super useful.

Posted by Ben Nadel on May 9, 2007 at 12:49 PM


Not a problem. I'm actually in the middle of building an SMS-sender application myself. Originally, we started with just an e-mail list but it just got to be too hard to keep the messages small enough. Now along comes you and you've written half the app for me so this was the least I could do :)

Posted by Christian Ready on May 9, 2007 at 1:04 PM


Team work is a beautiful thing :)

Posted by Ben Nadel on May 9, 2007 at 1:09 PM


has anyone gotten into real SMS shortcodes?
Ive looked into this several times in the past, and it just never seemed like something I would be investing in 'for fun'.

Are there any new SMS shortcodes 'packages' out there that would allow the creation of a site/service around Text messaging without paying out the @ss for the shortcode and per-text fee's?

Posted by JOSH on Jul 11, 2007 at 12:19 PM


I haven't looked into any real SMS since I think they all require using the Enterprise-level gateways, which I do not have access to. I haven't even looked at prices since the above is prohibitive.

Posted by Ben Nadel on Jul 11, 2007 at 12:30 PM


We use a shared short code service provided by an sms aggregator called Unwired Appeal. The cost is more reasonable if it is shared. However users do need to enter a specific 4 digit code at the beginning of each message to identify our account. I also use ColdFusion to send, receive, process and reroute messages. It works great.

Posted by Bob on Aug 8, 2007 at 11:34 AM


@Bob,

I just took a look at the Unwired Appeal website. Looks like a nice site / set of services. Thanks for passing that along.

Posted by Ben Nadel on Aug 10, 2007 at 8:32 AM


I have something similar working, but I have one question. I would like to allow messages longer than 120 characters. I have started a process that takes the message length and my goal is to have it send emails until the message is complete so it will email the entire message, just in chunks...however I am having problems.....any guess on how to accomodate this?

Posted by Michael Appenzellar on Dec 27, 2007 at 11:58 AM


@Michael,

What problem are you running into? What aspect is not working?

Posted by Ben Nadel on Dec 27, 2007 at 12:56 PM


thanks for the response. Well the only real problem is getting the remaining 120 characters each time. I know it is a combination of left, right and len statements but cna't seem to get the right combination. My thought was send the first 120 characters, set the remaining characters to a sting, send the next remaining 120 characters all within a loop until the entire grouping of emails was complete.

Posted by Michael Appenzellar on Dec 27, 2007 at 1:00 PM


@Michael,

To be really basic, I think you are on the right track - grabbing 120 characters and then moving on. The only tricky part is when you want to make sure you don't cut a word in half.

This seems like an interesting little problem. Let me see if I can whip up a quick demo over lunch. I have an idea cooking.

Posted by Ben Nadel on Dec 27, 2007 at 1:05 PM


@Michael,

I thought I would try and put something down on paper for you:

http://www.bennadel.com/index.cfm?dax=blog:1105.view

Let me know if that helps at all.

Posted by Ben Nadel on Dec 27, 2007 at 2:38 PM


Post Comment  |  Ask Ben


Home   |   Web Log   |   ColdFusion   |   Projects   |   Resume   |   Job Form   |   Search   |   Contact
Epicenter Consulting - Custom Software Solutions for Business Evolution HostMySite.com - The Leader In ColdFusion Hosting