Skip to main content
Ben Nadel at Scotch On The Rock (SOTR) 2010 (London) with: Roman Schlaepfer
Ben Nadel at Scotch On The Rock (SOTR) 2010 (London) with: Roman Schlaepfer ( @appleseedexm )

Sending Text Messages (SMS) With ColdFusion And CFMail

By on
Tags:

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.

Want to use code from this post? Check out the license.

Reader Comments

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

15,640 Comments

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?

6 Comments

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.

12 Comments

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.

20 Comments

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.

15,640 Comments

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

20 Comments

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.

15,640 Comments

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.

20 Comments

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

3 Comments

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?

15,640 Comments

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.

1 Comments

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.

15,640 Comments

@Bob,

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

2 Comments

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?

2 Comments

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.

15,640 Comments

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

3 Comments

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

15,640 Comments

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

3 Comments

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

15,640 Comments

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

3 Comments

@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

15,640 Comments

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

1 Comments

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.

9 Comments

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.

3 Comments

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?

9 Comments

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

9 Comments

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

3 Comments

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.

1 Comments

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.

15,640 Comments

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

6 Comments

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

15,640 Comments

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

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

Just talks about some of the underlying stuff.

1 Comments

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.

1 Comments

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.

1 Comments

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.

1 Comments

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

1 Comments

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.

1 Comments

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

1 Comments

Hello Ben,

Thanks for your code.

But I have checked the same in my local and live system, but it is not working.
Whether I have to change settings related things in CF Administrator for working the same.

I have tried the same like below,
<cfmail
to="9567102323@ideacellular.net"
from="9567102323"
subject="New Message"
type="text">

<cfmailpart
type="text/plain"
>Hello huan, this is a test message</cfmailpart>
</cfmail>

Can you please help where I fails?

Thanks,
Juan

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel