September 23, 2019
Using ColdFusion to send a one off SMS Message using AWS SNS (in five lines of code!)
Comments
(15)
September 23, 2019
Using ColdFusion to send a one off SMS Message using AWS SNS (in five lines of code!)
Wizard 29 posts
Followers: 15 people
(15)

This can certainly be chalked up to be a “this is why I love ColdFusion” posts.

First my obligatory disclaimer;  I’m not an AWS guru.  I’m not a Java developer per se.  Most of what I’ve learned has been through brute force, hack and slash, trial and error development.  Think of my coding style like a drunken baby and accept that this may or may not be the “right way” to accomplish this task… but it’s the way I stumbled upon.

I’m working with a client who sells travel packages to customers.  Once an agent builds a package for a customer, they email them a link where the customer can complete their purchase.  They wanted to add a text messaging feature that sends an SMS text message to their mobile device.

Amazon Web Services includes a service called Simple Notification Service, or SNS.  SNS will do much, much, MUCH more than send simple SMS text messages, but the task in my hands is to send an SMS… so I’m going to limit  the scope of its use to doing just that.

ColdFusion runs on top of Java.  ColdFusion is, essentially a Java pre-parser.  In fact, the end result of ColdFusion processing a CFM page is Java byte code that does all of the processing for your ColdFusion pages.  As such, there’s a world of extensibility available to you in the Java world that you can leverage easily using ColdFusion.

Likewise, AWS has a Java Development Kit available for download.  Between the availability of the JDK for AWS and the extensibility of ColdFusion to be able to use JAR files, this becomes a very simple task.

Setting everything up

There are some steps needed to get this up and running on ColdFusion, but they’re pretty straightforward.

  1. Create an AWS account.
  2. Create (or make sure you have) an AWS User who has privileges to use SNS.
  3. Obtain that users Access and Secret keys for using AWS.
  4. Download the AWS JDK.
  5. Copy the appropriate JAR files into your ColdFusion installation.
  6. Restart the ColdFusion service.

Specifically relating to number 5 in this list, you need the following JAR files from the JDK Download:

  • aws-java-sdk-1.11.xxx.jar
  • jackson-annotations-2.6.0.jar
  • jackson-core-2.6.7.jar
  • jackson-databind-2.6.7.1.jar
  • joda-time-2.8.1.jar

The AWS SDK .jar is located in the lib directory, and the others are in the third-party directory.  Copy these files to your {cf-root}/cfusion/lib directory.

Once the JAR files are in your ColdFusion installation, and the service has been restarted, here’s the code needed to send an SMS through AWS SNS, in its entirety:

<cfscript>
   awsCredentials = createObject('java','com.amazonaws.auth.BasicAWSCredentials').init([YOUR AWS ACCESS KEY], [YOUR AWS SECRET KEY]);
   awsStaticCredentialsProvider = createObject('java','com.amazonaws.auth.AWSStaticCredentialsProvider').init(awsCredentials);
   snsClient = createObject('java', 'com.amazonaws.services.sns.AmazonSNSClientBuilder').standard().withCredentials(awsStaticCredentialsProvider).withRegion([YOUR AWS REGION THAT SUPPORTS SMS]).build();
   publishRequest = createObject('java', 'com.amazonaws.services.sns.model.PublishRequest').init().withPhoneNumber('+1XXX5551212').withMessage('This is my Message');
   Result = snsClient.publish(publishRequest);
</cfscript>

And sure enough.  This arrived on my phone:

AWS SNS Result

BOOM! Text messages via AWS SNS in just five lines of code.

Making it Better

Now that I have a proof-of-concept, there’s a lot of things I can do to make this better.  I could make the AWS Credentials variable an application scoped variable that gets created on application start.  Heck the first three lines of my proof-of-concept could be cached in the application.  I could also write a function that I pass the message and the phone number and it just takes care of it for me.  What I have, however, is enough to prove it can work.

Alternatives

Some other ways I considered taking care of this task:

  • Twilio.com has an API for sending SMS messages that’s REST based.  I’m sure there are many other services that offer something similar.
  • Almost every mobile provider has an email to SMS gateway, so as long as you know the provider, you can send an email using cfmail and the mobile provider

Credit where Credit is Due

Brian Klass.  I’ve seen him present at CF Summit several times, and his blog has great articles on how to use AWS with ColdFusion for a multitude of services.  Pay special attention to the following articles:

Enjoy!

15 Comments
2020-01-13 21:46:47
2020-01-13 21:46:47

Hi Charlie,
Thanks for your comments and ideas.   I tried putting the jars within the both the WEB-INF/cfusion/lib and the tomcat WEB-INF/lib folder – to no avail on older versions of CF.

The first two calls of the script seem to AWS (BasicAWSCredentials, AWSStaticCredentialsProvider) are able to find the AWS SDK when the SDK (aws-java-sdk-1.11.701.jar)  is placed in /cfusion/lib/

It is on the 3rd call to AmazonSNCClientBuilder that results in:

java.lang.NoClassDefFoundError: Could not initialize class com.amazonaws.http.AmazonHttpClient at com.amazonaws.AmazonWebServiceClient

Is AWS SDK just not compatible with older versions of CF?
How would I figure out how to resolve java.lang.NoClassDefFoundError ?

Thank you.

 

 

Like
(1)
>
CF_CayuseDev
's comment
2020-01-14 02:59:31
2020-01-14 02:59:31
>
CF_CayuseDev
's comment

Maybe the problem is not about CF9 after all,

You have mentioned running CF9 on Tomcat (your own implementation of it). You’ve not told us about your Tomcat or Java versions. Consider that CF9 was never updated to support more recent JVMs (8 and above), and only supported Java 7 in late CHFs.

So what version of Java is your Tomcat running on? You can see that in the CF Admin on its “settings summary” page. If it’s Java 8 or above, then I would argue this is not so much a problem with cf9 itself but about it not supporting more modern JVMs, which you may be running. If you’re able to try running java 6 on Cf9 (which it supported out of the box), and it works, then that confirms things.

Finally, FWIW, I know you seem to be running cf9 on Tomcat and it’s working otherwise, but note that CF9 was not listed as supporting Tomcat at all, at least per its system support matrix:

http://web.archive.org/web/20091229164411/http://www.adobe.com/products/coldfusion/pdfs/cf9_support_matrix_v3.pdf

Like
2020-01-07 22:53:36
2020-01-07 22:53:36

A few things for you, CF_CayuseDev.

First, now that you have mentioned you are using Tomcat (CF 9 deployed as a JEE ear or war file on a Tomcat you installed), that changes things still more. You could be running into classloading matters related to how things are configured in your Tomcat (separate from CF).

So I know you say you put your jars in your web app’s WEB-INF/cfusion/lib folder, and it has “worked in the past” for other libraries. Fair enough.

But what happens if you remove them from there and instead put them in your web app’s /WEB-INF/lib folder instead? And of course, restart Tomcat again.

That is technically where you should put an application-provided jar for Tomcat. Of course, CF is loaded within Tomcat and has its rules, but it does operate within (and extend) Tomcat’s classloading mechanism. FWIW, you can see more about that Tomcat classloading and its indication to use that folder for app jars, here:

https://tomcat.apache.org/tomcat-9.0-doc/class-loader-howto.html

Let us know if it helps. I realize it may not.

Finally, note that all your comments are indeed appearing, all 7 of them that you wrote in reply to me :-), as well as the first one that you edited. I gather you’re not aware that the portal here has moderation on blog comments. Someone did eventually release your comments from moderation, but until then you won’t see them.

Frustrating, yes, but it is what it is here. (And FWIW, you refer to this as “the Adobe forum”, but technically this is the CF portal. The Adobe forums, including the CF one–which does NOT have comment moderation–is in a different site: community.adobe.com.)

As always, just trying to help.

Like
(1)
(3)
>
Charlie Arehart
's comment
2020-01-08 15:57:57
2020-01-08 15:57:57
>
Charlie Arehart
's comment

Thank you very much for your reply. Sorry for the duplicate posts.

Like
>
CF_CayuseDev
's comment
2020-01-09 03:48:55
2020-01-09 03:48:55
>
CF_CayuseDev
's comment

Did you resolve the problem? What did it?

Like
>
Charlie Arehart
's comment
2020-01-14 23:26:11
2020-01-14 23:26:11
>
Charlie Arehart
's comment

Hi Charlie,

I was finally able to resolve my issue by adding an additional JAR file.
In addition to the the 5 files listed above in the JDK download, I found that also loading a couple JARS from AWS JDK third-party folder: (aws-java-sdk-1.11.699/third-party/lib/) as well, resolved the issue.

httpclient-4.5.9.jar
httpcore-4.4.11

After adding those jars and restarting tomcat, all was well.
Not sure if both of them are needed.

 

 

Like
2020-01-07 18:58:34
2020-01-07 18:58:34

I was able to get the code working outside of our ancient CF9 environment. This code doesn’t work with CF9.

Like
2020-01-07 18:38:45
2020-01-07 18:38:45

–duplicate post–

Like
2020-01-07 18:03:08
2020-01-07 18:03:08

–duplicate post–

Like
2020-01-07 13:38:14
2020-01-07 13:38:14

Did you restart CF after copying in the listed files?

If so, are you perhaps running and instance of cf that was added using the cf admin instance manager (in cf enterprise, trial, or developer edition)? If so, you need to copy the files to THAT instamce’s lib, rather than cfusion/lib, and restart THAT instance.

Like
(4)
>
Charlie Arehart
's comment
2020-01-07 17:46:02
2020-01-07 17:46:02
>
Charlie Arehart
's comment

–duplicate post–

Like
>
Charlie Arehart
's comment
2020-01-07 17:57:36
2020-01-07 17:57:36
>
Charlie Arehart
's comment

–duplicate post–

Like
>
Charlie Arehart
's comment
2020-01-07 18:37:27
2020-01-07 18:37:27
>
Charlie Arehart
's comment

–duplicate post–

 

Like
>
Charlie Arehart
's comment
2020-01-07 18:57:32
2020-01-07 18:57:32
>
Charlie Arehart
's comment

Removing the JAR file from that class path, and restarting – the script fails on teh first call

Class not found: com.amazonaws.auth.BasicAWSCredentials

so it seems that CF can find the jar.  Could there be an additonal location that the AWS SDS needs to be added?

Like
2020-01-07 02:21:47
2020-01-07 02:21:47

–duplicate post–

Like
Add Comment