Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at CFUNITED 2008 (Washington, D.C.) with:

Sending Text Messages (SMS) With ColdFusion And CFMail

By Ben Nadel on
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:

  • <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:

  • <!--- 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.




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. ;)

Reply to this Comment

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?

Reply to this Comment

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.

Reply to this Comment

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.

Reply to this Comment

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.

Reply to this Comment

@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.

Reply to this Comment

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.

Reply to this Comment

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.

Reply to this Comment

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 :)

Reply to this Comment

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?

Reply to this Comment

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.

Reply to this Comment

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.

Reply to this Comment

@Bob,

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

Reply to this Comment

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?

Reply to this Comment

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.

Reply to this Comment

@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.

Reply to this Comment

Hi,
First of all, I would thanks very much for all the codes. It could take me months if I write my own.

I am developing a Register of Newsletter. The user will register their email address and cell phone to receive news via their email address and cell. All phones will have diff carriers.

And I wonder if your codes handle to send out a multi phone numbers with different carriers?

The worse thing I can do is to ask to them to select the carrier name along with their phone number (when they register) and store it in DB. Then when I send out the message, I will go thru the loop to send to each of them at a time. But I don't think it's good idea.

Any advise?
Thanks

Reply to this Comment

@Hung,

If you are going to be sending to a lot of people, I would maybe look into the shared SMS service rather than using the CFMail route. Apparently the cellular companies don't like people using mail to send SMS (they don't get money for it) and will ban your stuff if they catch on to it.

Reply to this Comment

Yes we do have text message service.
So let go back to my earlier question is that how do I send an text message to multi cell?
Any advise please
Thanks
Hung Pham

Reply to this Comment

@Hung,

My code does not handle multiple senders. However, does your SMS service require that? I would be surprised that they would need more than simply the number to text.

Reply to this Comment

@Bob,

I'm am today officially embarking on engaging an SMS aggregator using coldfusion to send and receive sms short codes.

I got my dedicated IP setup today and was setting up the sms gateway.

Would you mind sharing with me some of the unseens that you've run into? Possibly some code snippets even?

thanks
Matthew

Reply to this Comment

@Matthew,

I have not dealt with SMS gateways - I assume you are doing this in ColdFusion Enterprise Edition. You'll probably know more about this than myself :)

Reply to this Comment

Do you know if there is a limit that an SMS gateway provider like AT&T or verizon imposes on the number of messages sent - either per day, per hour, or per month. I am wondering if there is a limit place on the message sender as to how many messages can actually be sent.

Reply to this Comment

I would love to find out more information about setting up SMS gateways. We have been using a shared short code provider and they service has ben down for three weeks in the US so we are investigating more service providers and other options. I just stumbled upon the SMS gateway information for ColdFusion 9 and I'm trying to see how to leverage this.

Reply to this Comment

SMS Gateways:

Since we run a commercial SMS gateway, I can tell you straight off...its expensive in money AND time.

If your intention is for private business use, your better off with a shared short-code. Get another SC provider.

We still use an aggregator ourselves, albeit our own shortcode. and what does that get us? well for all intents and purposes, the only functional difference is that each text message has 1-less keyword parameter to type in. thats pretty much it.

Once we get to 1 million messages/month we'll attempt to directly contract with each of the US cellular businesses. (you will find it excruciatingly difficult to contract with any cellular directly unless you have demonstrated measurable (by their standards) usage requirements.

Several cellulars have gone to charging $500/contract. (the aggregator will pass that on to you in addition to their hefty monthly charges). keep that in mind.

Connor: what are your SMS intentions?

Reply to this Comment

@matthew walsh, we are looking to send an SMS on every approved application that comes through and we were working with Clickatell, but there shared shortcodes were recently banned by US carriers due to some rogue users. They have worked to get it fixed, but we are looking at three weeks now and no change. We will be sending about 200-300 messages a day, so not much really. I am looking into other shared shortcode providers (CellTrust, Message-Media, and several more)

Reply to this Comment

@matthew,

As a side note, what are the downsides to just using some code like Ben has here? Since we don't know the provider for each person, could we just send an email to every provider and the right one would go through? Doesn't seem ethical, but is there a way to find out the provider?

Reply to this Comment

Connor,

seems to me as part of your information collection process (application form), you could easily add a combobox to collect the users carrier.

the applicant is certainly motivated to provide the info so you'd be set.

outside of that email spamming would work too.
You dont hear alot about that method since most would be tight lipped about it.

me? i would not be surprised if those email portals monitor submittal IP's and eventually block very low matching recurring submittal IP addresses.

Reply to this Comment

I've been using the cfmail option to send emails to user's cell phones for almost two years.

I usually send around 2,000 to 3,000 messages per day and have ran into lots of problems with the carriers blocking my messages after a certain number of connections in a certain time frame. They keep track of your IP address and label you as spam if you are sending too many messages. It's also important to have a valid DNS Pointer record to your sending server. I've gotten around the blocking by adding 4 more mail servers to send from and just cycle through the server connections at send time so the messages are evenly distributed over each server. I still reach the limits on heavy send days.

Another problem I've recently run into with the cfmail tag is when I specify the failto attribute the failto address shows up as the sent from address on the text message. What I am trying to do is show my user's email address as sent from (from) but have all rejected messages come back to me (failto). This would allow text message receivers to reply directly to the user that sent the message and allow me to manage bounced addresses... the problem is, it shows my email address instead of the sender's address when I use failto. If I remove failto, the sender's email address is shown as the sender but they also get all the bounced messages which isn't good.

Anyone have any thoughts on how I might be able to get around this little problem? Any ideas/thoughts how I might be able to make this process better would be greatly appreciated! I'd love to be able to use a SMS gateway service, but the cost is so high so I'm stuck with these hacks.

Reply to this Comment

@Connor, @Matthew, @Matt,

I have heard a mixture of all of these problems from everyone who deals with SMS. I think the CFMail approach is good for very low-volume stuff. Above that, you probably gotta go with dedicated or shared short codes. Shared short codes, as you guys have already discussed are less expensive, but stlll pricey. The one shared short code that I played with was with TextMarks. They have a great API; but, they put ads (rather large ads) at the bottom of each SMS message. If you want to go ad-free, even with TextMarks, it costs like $1000/month for a significant amount of volume:

http://www.textmarks.com/pro/options/

I've heard of people trying to get contracts going directly with the cellular carries and I'm told that's just a whole other nightmare that you don't want to deal with. I've actually heard that the cell carriers pretty much dismiss you until you can bring the a massive amount of volume.

I do wish there was an easier way in all of this.

Reply to this Comment

Hi,
I saw this piece of code in your example and was thinking Coldfusion 9 is truly supporting javascript-like function calls...

# <cfset FORM.to = FORM.to.ReplaceAll(
# "[^\d]+",
# ""
# ) />

If I request a page containing this code:

<cfset tekst="de doodoodoo, de daa daa da">
<cfoutput>#tekst.GetToken(2,",")#</cfoutput>

I get the error
"The GetToken method was not found."

or am I overlooking something?

Marc

Reply to this Comment

@Marc,

This is not a CF9 feature; it's actually a bit of a hack what I am doing there. Underlying *most* simple values in ColdFusion is a Java string (all of ColdFusion is built on top of some form a Java class or another). The Java string exposes the replaceAll() and replaceFirst() methods (among many others).

It's an undocumented / quasi excepted feature. If you are curious about it, take a look at this blog post:

http://www.bennadel.com/blog/1023-ColdFusion-Wants-You-To-Access-The-Underlying-Java-Methods.htm

Just talks about some of the underlying stuff.

Reply to this Comment

In my implementation of this, the CFMailpart was causing my message body to display multipart MIME information. By simply removing the CFMailpart tags from my code, it works slick as ice.

Reply to this Comment

Sir Ben, I was really having trouble of creating this SMS (computer to mobile phone) transactions. actually i was doing an on-line grading system where in the grades of the student are sent to their mobile phones.

Thank's for the information you shared. It really help mea lot.

Reply to this Comment

I hope this works for me. I need to be able to send a text message to my dispatcher when we receive an emergency service request. Rather than make the user enter the texting info, I want to handle it through coldfusion and send it to the provider I know my dispatcher has on their phone so I should be able to simplify this.

Thanks.

Reply to this Comment

Ben, this was a fabulous find. We have a low volume that needs to go out (like 5 to 10 a day) and this will work perfectly to prove the concept. Once again, amazing concept!

Thanks!
Chris

Reply to this Comment

@anyone,

Does anyone know how to find out what domain a given phone number uses?

Reply to this Comment

hi Ben Nadel.
i hv a confusion to use cfmail function to send sms
first of all mobileNo should be registered at service provide accroding to me understanding

i m putting in

to=+923224338794@messaging.nextel.com
from=+923454999794
message="this is nice help fron ben"
and submit

but no answer

have the no should register at messaging.nextel.com
or on other service provider by using their domain

or not

any help will be greatly appreciated

regards
ghulam Nabi.

Reply to this Comment

hi,
can anyone tell me how to use Ben code
is number must be register first at service provider
e.g my number is 3456789675 and compay is telenor
at send to option i will write something like this
3456789675@telenor.com
any help will be highly appreciated

Reply to this Comment

I haven't read the article, yet, but I'm just glad to see it at the tippy top of Google's results. :D

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
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.