ColdFusion Event Gateways: Building an eCommerce Bot for iChat and Google Talk · 1521 words posted 03/23/2006 12:57 AM
I recently rebuilt an ecommerce site from the ground up. One of the frustrations of working remotely is that you don’t get to see, in real time, how your client uses the application you’ve built for him. Fortunately, ColdFusion MX 7 supports Event Gateways out of the box. Think of an event gateway as a real-time information broker that bypasses HTML to let your site communicate via SMS or Instant Messaging with non-web clients such as a cell phone, or iChat.

So I whipped up an IM system that sends an alert to iChat any time an administrator logs into the new ecommerce site (see screenshot, left). I liked the feature so much that I thought I could persuade my client to fund a messaging system to send an alert whenever a customer took a certain action, for example, made a purchase over XX thousand dollars, or requested expedited overnight shipping.
In this entry, I’ll suggest an architecture for building your own messaging system using ColdFusion MX 7. The site is closed-source, so I can’t share the bulk of my source code, but I’ll walk you through the logic and give you enough help to get you started.
Requirements
The requirements for this project were pretty restrictive:
- The site rebuild was almost complete, and I didn’t want to lose the client’s respect by pitching an expensive solution late in the game. Development hours had to be short to keep the solution affordable.
- Likewise, the app was already in production using ColdFusion MX 7 Enterprise and MS SQL Server 2000. I had to work with the existing tool set. This meant obvious combinations like Java and XML Sockets were out. Ditto Flash Communication Server.
- I would rather eat glass than write new interface code. In fact, I wanted something off the shelf that I could simply hook to my application.
- Two years ago I wrote a news alert application in Flash for a bond house in Hong Kong and New York. While the app worked fine, it made me keenly aware of the limits of using a browser window for a notification app that’s intended to stay open all day: browser windows close.
Filtering the above requirements, we’re left with an inexpensive (free) widget that lives outside the browser, communicates in real time, and is already built for me. Sounds like a job for an IM client.
ColdFusion Event Gateways, XMPP, Jabber, Google Talk, iChat, and Protocol Soup
By default, ColdFusion MX 7 Enterprise Edition ships with several gateway types, including XMPP, the protocol that powers Jabber. You might not have heard of Jabber, but you’ve certainly heard of Google Talk or iChat, both of which support Jabber Instant Messaging.
By configuring a gateway instance, you can tell ColdFusion to recognize and respond to chats with an arbritrary gmail address, for example your.admin.bot@gmail.com. You can also use the gateway to push messages out to people who are listed as buddies.
For the developer it sounds like a potluck of protocols to understand, but for the end user it’s very simple: using any IM client that recognizes Jabber (such as Google Talk, ichat, Adium, etc.) you add the bot as a buddy and you chat with it.
For the technical details of configuring a bot, see Ben Forta’s excellent Building an IM Bot. Here’s one way to architect your application.
You Had Me At Hello: bot logic

The diagram below consists of three layers: people (whether it’s an admin using ichat to set up alerts, or a customer using a web browser to place an order); components (these are CFCs); and, of course, the database.
In our example, the gmail bot is a listener CFC: it’s only job is to listen to chat requests and respond accordingly. When a person sends a message to the bot, ColdFusion packages the information in a structure called CFEvent. Within the CFEvent structure you can access information about the sender and the message she sent. Our gmail bot uses the onIncomingMessage function to recognize four commands:
hello: Turns on alerts. For example, after sayinghelloyou will receive notices when a customer makes an order with expedited shipping.goodbye: Turns off alerts.status: Simply tells you whether you are receiving alerts or not.help: Returns a list of recognized commands to the ichat client.
The orders CFC handles orders and inserts them in the database.
The auth CFC authenticates and tracks admin logins.
Finally, the sender CFC broadcasts messages to the ichat client using sendGatewayMessage().
The ichat client is an admin with a gmail address. Let’s call the address you@gmail.com. The admin needs to add the gmail bot as her buddy. Let’s call it your.admin.bot@gmail.com. There are any number of ways you can have the gmail bot authenticate a buddy request. For example, you could look up the sender’s gmail address (passed in CFEvent.OriginatorID) and compare it to a list of known admins in the database. My small business client only has 10 employees, so for convenience and security I manually added each employee as a buddy.
Step by step:
- The admin send a
hellomessage to the bot. - When the bot receives a message, it recognizes the admin as a buddy it calls the function
onIncomingMessage. OuronIncomingMessagefunction includes a simple parser built around a series offindnocase()statements. When it recognizeshellothe bot takes two steps: first, it passes the admin’s gmail address (CFEvent.originatorID) toauth, and second, it assembles a return message consisting of acommand, abuddyID, and amessageto return back to the admin—we just need to let her know that we recognized her command. authinserts the admin’s buddy ID into the database. Let’s call the tabletbl_listeners. This means the admin is now listening for events. And here’s an important catch: while gateway CFCs can create and recognize session variables, they do not share those variables with regular CFM files. This means you can’t expect a page loaded over the web to recognize a session created via the gmail bot. The implication becomes clearer when we get to thesenderin a moment. For now, just remember that the admin is now listed in our database as someone who’s listening for events.- A customer places an order.
- The order is saved in the database.
- After safely inserting the order, the
ordersCFC checks for a trigger. You can write a trigger any number of ways; I write my triggers as functions which returnbooleans. Did the customer select expedited shipping? If no (false), that’s the end of our flow chart—our admin doesn’t need to know the instant every customer places an order. But iftrue, we want to pass a message to thesenderCFC to alert the admin. - The
senderCFC has just received a message fromorders. Thesenderhangs on to the message, but first… senderchecks withauthto see who, if anyone, is listening.authgrabs a list of listening admins from the database and passes that list as aqueryobject back tosender.- Finally,
sendertakes the message (“A customer has placed an overnight order”) and pushes it to the listener, you@gmail.com. The listener receives an alert in iChat and can act accordingly.
Considerations
Once you understand how Event Gateways work in ColdFusion, it’s easy to build a simple messaging system. Some final considerations to keep in mind:
- It’s always good to use
cftryandcfcatchto handle errors at a granular level, but when you’re using an XMPP gateway you must use try/catch blocks around any code that references a gateway. If the gateway is stopped, or even if its status is set tooffline, ColdFusion will generate an error. As long as you’re using try/catch, temporarily taking down your gateway won’t break your application. - Learn to love log files. When you first start working with XMPP gateways you’ll have many Ferris Bueller moments: anyone? anyone? ColdFusion doesn’t send error messages back out to your chat client, so when something fails it fails silently. Check your log files if the chat isn’t behaving as expected.
- Think about best practices when writing CFCs: in the example above, our
ordersCFC doesn’t care who’s going to receive a message or how that message will be sent. It simply creates the message “A customer has placed an overnight shipping order” and then passes that message as a string to thesenderCFC. This sort of loosely coupled delivery agnosticism will pay off later if we expand our system to SMS.
I hope this gets you started building your own messaging systems. From here, it’s only a short step to building an order support system that’s an order of magnitude faster than a web interface, or even an SMS system that allows customers to track shipments from their phones. In addition to the Forta article mentioned above, I found the following two resources especially helpful: Jeff Tapper’s PowerPoint presentation Using Event Gateways in CFMX7 and Rule Your Site With Instant Messaging by Robert Capili.
Finally, thanks to Sean Corfield for his feedback.
* * *
3. On Mar 23, 09:14 PM Gus said:
The basic process I use is to send a message, and check the status result. If it failed, stop and restart the gateway.
isSent = chatOBJ.sendGoogleMSG(IMEvent);
if isSent EQ ‘failed’ {
adminOBJ = createObject(“component”,”cfide.adminapi.administrator”).login(“yourAdminPassword”);
gatewayOBJ = createObject(“component”,”cfide.adminapi.eventgateway”);
gatewayOBJ.stopGatewayInstance(‘yourGatewayName’);
gatewayOBJ.startGatewayInstance(‘yourGatewayName’);
}
I run this as a scheduled task, and send myself a notification whenever the service hangs.
Doesn’t happen too often, but I haven’t had to manually deal with the gateway in months.
Hope you find this useful. #


1. On Mar 23, 08:58 AM Gus said:
I’ve been running the mxnachatbot@gmail.com cfmx/google chatbot since September. It allows users to interact with MXNA through Google talk ( there is also a non-google jabber version ).
The one thing I have found is that the gateway will hang periodically. To deal with this I have code in my bot that will detect if the gateway is not responding, and automatically restart it.
I’d be happy to send that code along to you if you like.
Gus #