Welcome!

You will be redirected in 30 seconds or close now.

ColdFusion Authors: Yakov Fain, Jeremy Geelan, Maureen O'Gara, Nancy Y. Nee, Tad Anderson

Related Topics: ColdFusion

ColdFusion: Article

Who Says You Can't Take It with You?

Who Says You Can't Take It with You?

Have you ever been off on a trip, away from your home or office computer, and wanted (no, needed!) to check your e-mail?

Or have you ever been stuck at a location where firewalls or other network limitations prevented you from accessing your mail or sending mail to others?

E-mail has become a lifeline for many people. For some, it's the main mechanism for staying in touch with others. (Many have been known to check their e-mail more frequently than they check their voicemail or answering machine.) For an increasing number of people, being able to access e-mail is not just a luxury, it's an absolute necessity.

How do you check your e-mail when you don't have access to your own computer? Of course, you need a computer with an Internet connection, but that's just the beginning. In the olden days, before the existence of the Web, it was rather simple. You could telnet to your UNIX host and run an e-mail program like elm or pine.

Nowadays, the process is much more complicated. Most people use POP3-based clients like Eudora, Outlook or Netscape Messenger to retrieve and send e-mail, including attachments. If you don't want to go to the bother of setting yourself up as a "user" of one of these e-mail client programs on someone else's computer, or if you simply can't make use of such programs because a firewall blocks POP3 traffic, another solution is needed.

A Web-based e-mail system is a perfect solution. Users can connect to a Web site that allows them to login, supply their e-mail password (and other relevant information) and view a list of messages for them to read. Unlike the typical POP3 client program that deletes your messages from the server as they're downloaded, this application would leave your messages on the server so that you'd have access to them when you got back to your home base. In addition, you could download the messages you wanted to view selectively, skipping spam and other unwanted e-mail.

This article describes how I used ColdFusion to build a Web-based e-mail system called popART, for "POPmail Access and Retrieval Tool." (I considered calling it "popTART," but feared my lawyer would get a phone call from Battle Creek, Michigan.) The goal was to create a robust, full- featured application for people who are used to more sophisticated e-mail clients like Netscape Messenger, Outlook or Eudora. It may not replace these programs, but it can serve as a viable alternative when they're not available, for whatever reason.

Why Reinvent the Wheel?
The question arises: Why build a Web-based e-mail system at all? Many portal services already provide a variant of this kind of service. You can use these services to access your e-mail easily over the Web, provided you sign up for an e-mail address on their site. Some of them even let you access mail from your home or office e-mail addresses. But outgoing mail sets your e-mail address to "[email protected]" rather than to your original e-mail address. Unless you're looking for anonymity (or extra work for yourself), why get yet another e-mail address?

People who just want access to their home or office e-mail simply need a system that will provide them with that access without requiring them to sign up for a new e-mail address or use proprietary software. Such a system would be an extremely useful, generalized tool for anyone on the Net to use. It could also be configured as a customized application for a particular group of people who get their e-mail from one particular server, such as the employees of a company or the customers of an ISP.

Why Use ColdFusion?
ColdFusion is a perfect platform choice for building a Web-based e-mail system. Two of ColdFusion's tags, <CFPOP> and <CFMAIL>, are specifically tailored for this very sort of task. But throwing together a ColdFusion module that uses these tags doesn't necessarily make it a viable e-mail system. The key is to maintain "state" between pages so the necessary connection information is known at all times without requiring the retransmission of that information every time the user goes from page to page. (Since the password is part of that connection information, ideally it should be transmitted as little as possible -- and preferably not as part of a URL query string!)

I've provided snippets of ColdFusion code from some of the core modules to illustrate the process of building this application. However, these snippets are simplified versions of the code that I eventually used in my own application, and additional work would be required to create a solid and robust e-mail system based on them.

Requirements
The basic requirements for an application like this are as follows:
1. A login page. This page would provide a place for users to enter all the information necessary to connect them to their POP mail server. This would include their POP user name, their password and the name/address of their POP mail server.

(This page doesn't need to be a ColdFusion module. It can be a simple HTML page with a form on it. The form's ACTION parameter should point to a ColdFusion module that uses the <CFPOP> tag to connect to the server to retrieve mail, using the POST method so that sensitive information isn't included in the URL. The password would be entered here and used as the basis for secure access to e-mail throughout the application, but wouldn't be retained or recorded.)

2. A message list page. Once connected, a page should be displayed that lists the "headers" of the messages waiting for you on the server. The header is the part of an e-mail message containing "metadata" information about the message, such as its subject, the address of the person who sent it to you and when it was sent. You'll use the <CFPOP> tag to return the headers of all messages and format them as an HTML table with links to the "bodies" of the individual messages.
3. A message display page. Each entry on the message list page should include a link to a page that will display the contents ("body") of that individual message. You can use the <CFPOP> tag here to retrieve the header and body of an individual message.
4. A means of replying to a message. By clicking on a link found on the message display page, a user should be able to send a reply to the message. Ideally, similar links should be available to do "reply all" (reply to everyone who got or sent the message) and "forward" (send the message on to someone else). The application can open a window using JavaScript that includes a form with a <TEXTAREA> for entering the response message. This form can link to a page that makes use of the <CFMAIL> tag to actually send the e-mail.
5. A means of generating a new message. Similarly, there should be a way to create a new e-mail message from scratch. This function should be usable from everywhere in the application. If you play your cards right, you can reuse some of the functionality you built for replying to messages.

In addition, it would be useful for the application to have a means of viewing or downloading attachments to messages, of deleting messages and of retrieving new mail from the server. This article won't cover these additional features.

Use of Session Variables
A fundamental part of this application is its use of ColdFusion's session variables to maintain "state" as the user jumps from page to page. Under the covers, session variables make use of cookies to identify a pool of values associated with a given application. For this application, the session variables hold the POP server connection information (user name, password, etc.) so that they can persist across pages. This means the application doesn't repeatedly retransmit this information between the ColdFusion server and the browser (though it does transmit the information between the ColdFusion server and the user's POP mail server for each request).

The global ColdFusion module Application.cfm should be used to establish the session variable scope. It can also be used to set other global parameters.

<CFAPPLICATION NAME="popart"
SESSIONMANAGEMENT="Yes"
SESSIONTIMEOUT=600>
<CFSET SMTPhost = "smtphost.myisp.com">

Once session variables are set, they don't need to be included as parameters in links to subsequent pages, either within the query string portion of the URL (for GET) or within the standard input (for POST). The less this information (which includes the password) is transmitted across the wire, the better.

A very simplified POP3 session goes something like this. By telnetting to port 110, you can "talk" to the POP3 server directly. After the server acknowledges your connection, you can send a line that says "USER username" (substituting your user name, of course). The server will respond by telling you that you need a password, so you send another line that says "PASS password." Once you have passed these authorization tests, you can interrogate the POP3 server about your e-mail by sending additional commands.

The STAT command will tell you how many e-mail messages are waiting. You can use that number as an upper bound for successive applications of the RETR or TOP command, which can retrieve individual messages (header and body) or just the headers from messages. If desired, the DELE command can permanently delete specific messages from the server. (The deletion becomes permanent only when you "commit" by explicitly entering a QUIT command. Messages won't be purged if a session is terminated prior to issuing the QUIT command.)

ColdFusion's <CFPOP> tag can perform sophisticated operations by automatically grouping these commands together. It returns results in a manner similar to <CFQUERY> or <CFDIRECTORY>, so "rows" returned can be iteratively processed via the <CFOUTPUT> tag.

The<CFPOP> tag's required parameters are a USERNAME, a PASSWORD, a SERVER name, an ACTION and a NAME for the <CFPOP> query, which will be used by subsequent <CFOUTPUT> tags. Optional parameters include the MESSAGENUMBER (which could be a range or list of numbers). If the MESSAGENUMBER isn't supplied, it's assumed that the requested operation applies to all messages rather than to just one.

The ACTION parameter can be "getall" (get the entire message including header), "getheaderonly" (get just the header) or "delete" (delete the message from the server). Using ACTION="getheaderonly" without supplying a MESSAGENUMBER returns all of the headers. This format of the <CFPOP> tag is used on the message list page. Alternatively, using ACTION="getall" and supplying a MESSAGENUMBER will return the entire contents (header and body) of a single message. This format is used on the message display page.

The Login Page

The HTML form on the login page will probably need four entry fields: POP user name, POP user password, POP server name or IP address and the user's e-mail address (see Figure 2). In an ideal world, the POP user name and the server name could be derived from the e-mail address. (e.g., "[email protected]" would have a POP user name of "joe" and a POP server name of "myisp.com"). This isn't always the case. Some ISPs give their customers POP user names that are different from the name in their e-mail address, and more often than not the POP server isn't simply "myisp.com," but rather a specific system name like "mailhost.myisp.com" or "popserver.myisp.com".

This page could be customized so that some parameters are hard-coded. This is useful if you're designing this application for employees of a company or customers of an ISP, all of whom use the same POP3 server and all of whom have their e-mail addresses associated with the same domain. You can also create defaults to use if some information isn't entered. For example, the name and domain in the e-mail address can act as the default POP user name and POP server name if those fields aren't supplied.

Message List Page
My version of this application, popART (see Figure 3), makes use of a master page containing three frames. A frame-based architecture can be more efficient, cleaner and more user-friendly because there's less need to use the "Back" button to navigate between the message list and an individual message.

The top frame is a title page containing the popART logo, global buttons used by the application and an ad link generated by an ad server. The middle frame contains the message list page that displays the headers of the messages waiting on the server. The bottom frame starts out blank, but will contain the message display page when individual messages are selected for reading.

If you use a similar design, the form on the login page should connect to this master page. Otherwise it can connect directly to the message list page. First, the parameters passed from the login form are used to set the values of session variables.

<CFSET Session.user = #user#>
<CFSET Session.password = #password#>
<CFSET Session.servername = #servername#>
<CFSET Session.address = #address#>

Once these values are set, the <CFPOP> tag is used to retrieve the message headers. The output of this tag acts much like a <CFQUERY>, as you'll see below.

<CFPOP NAME="email"
ACTION="getheaderonly"
PORT=110 TIMEOUT=600
USERNAME="#Session.user#"
PASSWORD="#Session.password#"
SERVER="#Session.servername#">

Note that the message bodies (and attachments) aren't retrieved as part of this process, just the headers. This should make the process of retrieving the list faster, but it also affords the user some additional flexibility. If you can see the list of messages before downloading them in their entirety, you can selectively choose not to download messages that you don't want to see. You can appreciate this if you've ever used a POP3 client program and waited an eternity for several long spam messages or messages with attachments to download in order to read the one genuinely important message that followed.

First, the parameters passed are used to set the values of session variables.

<CFSET Session.user = #user#>
<CFSET Session.password = #password#>
<CFSET Session.servername = #servername#>
<CFSET Session.address = #address#>

The message headers are displayed as part of an HTML table. (See Listing 1 for the code snippets from this module.) The first line is for column headings (From, Subject, Received). Subsequent lines are generated by the <CFOUTPUT> tag associated with the query named "email". There are columns for message number, sender (from), subject and date sent. The number displayed in the message number column is a link to the message.cfm module (see Listing 2), passing the message number as a parameter.

Message Display Page

The message.cfm module's primary function is to display the message body (see Figure 4). It begins this process by retrieving the individual message using the <CPFOP> tag.

<CFPOP NAME="message"ACTION="getall"
PORT=110 TIMEOUT=600
USERNAME="#Session.user#"
PASSWORD="#Session.password#"
SERVER="#Session.servername#"
MESSAGENUMBER="#num#">

It then redisplays the header information. Following the header, the body of the message is displayed. You could do this using the "<PRE>" tag, but long lines would roll off the edge of the screen. Instead, enclose the body text in a table, explicitly use a monospaced font, and append hard line breaks in the message body with "
" tags.

Reply Function
This would be sufficient if all you wanted to do is display the message. But this module is also supposed to provide a mechanism for replying to the displayed message. To accomplish this task, you must first derive pertinent information from the original message.

You derive the subject and prepend the string "Re:" to it (if it isn't already there). You also derive the reply address, which is the "Reply-to" field (if it exists) or the "From" field.

Finally, you build a copy of the message body, indent each line with "> " and prepend the whole thing with an introductory line. ("On December 31, 1999, [email protected] wrote:") The JavaScript variable "x" is set to the content of this bodycopy field. The contents of this variable can be retrieved by the subsequent module compose.cfm by referring to "window.opener.x". This is actually far less cumbersome than trying to pass this field as a parameter.

There must also be a link enabling the user to compose a response. In popART, I use an image for this link. The image links to another JavaScript function, composeMessage(). I place this image (and other similar images used as links to similar functions) at both the top and bottom of the message display.

As I mentioned earlier, it's our goal to reuse this function for other message composition tasks, such as forwarding, replying to all or generating a new message from scratch. Thus the function may be invoked using different modes to perform these additional tasks. Here, the function simply derives the recipient and subject from the header fields, and uses JavaScript's window.open function to open the compose.cfm module (see Listing 3) in a new, tailored window.

Message Composition Window
This window contains a table with text input lines for each of the header fields and a larger text area for the body of the message (see Figure 5). This area is filled with the contents of window.opener.x, the modified and indented copy of the original message body. Note that the "From" field is hidden, but it can be set up as a regular modifiable text field if so desired.

Sending the E-mail
The send.cfm module (see Listing 4) makes use of the tag to send the e-mail message. Note that it makes use of the global variable SMTPhost, which was set in the Application.cfm file earlier. Following the sending of the e-mail, the page tells the user that "Your message was sent" and lists the recipients. (This particular version uses JavaScript's setTimeout function to automatically close this window after eight seconds.)

Drawbacks, Deficiencies and Additional Enhancements
Although the application in its current state is very useful, a number of improvements need to be added to make it a truly robust e-mail application.
1. The "Reply" function should be complemented with a "Reply All" function and a "Forward" function. Most of the core work is already there to support this.
2. The "New Message" function needs to be built. The composeMessage JavaScript function, found on the message display page, has most of the functionality in place to do this. All that's needed is a link that calls this function with a mode parameter of "new." (I place this link in the title frame of my application.)
3. A function for permanently deleting messages would also be nice. Given the way this application interacts with the POP server, the best way to handle this is to "mark" messages for deletion, using a checkbox next to the message number in the message list. A link would be provided to "purge" all the marked messages permanently. This purging would have to be followed by the re-retrieving of all messages from the server to refresh the message list, since deleting messages in the middle of the list would alter the numbers of all subsequent messages.

4. Support for viewing and sending attachments should also be included. The <CFPOP> tag provides support for placing attachments in a specific directory when a message is downloaded. But placing these attachments in a directory accessible through the Web server would make these attachments openly accessible as well. (One commercially available Web e-mail service actually places users' attachments in a publicly accessible directory for anyone to see!) For security reasons, the attachments directory shouldn't fall under the Web server's root directory, nor should it be designated as a directory that can be seen via the Web server. In this way, attachments can be viewed or downloaded only through this application, by users authorized to see only their own e-mail attachments.
5. Most of the existing e-mail client programs automatically highlight hyperlinks, such as URLs and e-mail addresses. By clicking on these hyperlinks, you can open up new browser windows or initiate e-mail messages. This is definitely a nice feature to have in an e-mail tool, but it's very tricky to figure out where such links begin and end (especially when they end in commas, periods, brackets or other punctuation). ColdFusion's REReplace function is powerful enough to do a lot of this work, but the endings of hyperlinks should be marked carefully. (Also, think about this: Do you want "mailto:" links to open the browser's internal e-mail response function or your application's?)
6. More robust error handling is required. If the POP server doesn't accept the user name and password, the application displays a nasty error message from the ColdFusion server. Also, there's no indication of success or failure when e-mail is sent. Additional error checking and validation are necessary.
7. More robust security is also required. Using ColdFusion 4.0's Encrypt and Decrypt functions might be useful for encrypting passwords. Additional code may be necessary to support "refreshing" of session variables if they've timed out or, if desired, the user can be required to sign in again after a timeout. Using this application over an SSL (Secure Sockets Layer) connection is another way to enhance security.

8. The <cfpop> tag in ColdFusion 3.0 has some known bugs. One rather serious bug prevents users from reading any message beyond the first one if that first message has an attachment. (This was fixed in ColdFusion 4.0.) It's recommended for this reason that ColdFusion 4.0 should be used as the basis of this application.
9. In addition, the <cfmail> tag lacks a lot of the functionality one would want for sending e-mail (blind carbon copy, reply-to header, etc.). There are shareware and commercially available ColdFusion tags that can serve as plug-compatible replacements for <cfmail> (and for <cfpop>), including Christopher Evans's CFX_MAIL and Patrick Steil's CFX_iiPOP3. These are available at Allaire's ColdFusion Developer's Exchange, formerly known as the Tag Gallery (www.allaire.com/developer/gallery.cfm).

Conclusion
I've barely scratched the surface in describing what's involved in building an application like this. The code snippets I've provided, for simplicity's sake, don't include certain finesses in laying out the pages the way they appear in the screen shots. Still, I hope this article serves as a useful introduction to the process of designing and building a Web-based e-mail system in ColdFusion.

If you'd like to take a look at the resulting application in its current state, visit www.neurozen.com/popart. It's still in beta; however, it provides all the main features and a number of the additional enhancements described in this article.

More Stories By Rich Rosen

Rich Rosen has been on the Net since before there was
a Net. He's been with Pencom Web Works
(www.pencomwebworks.com) since 1997, building
e-commerce, multimedia and Web/database connectivity solutions using NetDynamics, Macromedia Flash,
RealAudio and ColdFusion. The popART e-mail system described in this article is one of the many showpieces
at his personal Web site (www.neurozen.com).

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


IoT & Smart Cities Stories
If a machine can invent, does this mean the end of the patent system as we know it? The patent system, both in the US and Europe, allows companies to protect their inventions and helps foster innovation. However, Artificial Intelligence (AI) could be set to disrupt the patent system as we know it. This talk will examine how AI may change the patent landscape in the years to come. Furthermore, ways in which companies can best protect their AI related inventions will be examined from both a US and...
The challenges of aggregating data from consumer-oriented devices, such as wearable technologies and smart thermostats, are fairly well-understood. However, there are a new set of challenges for IoT devices that generate megabytes or gigabytes of data per second. Certainly, the infrastructure will have to change, as those volumes of data will likely overwhelm the available bandwidth for aggregating the data into a central repository. Ochandarena discusses a whole new way to think about your next...
Charles Araujo is an industry analyst, internationally recognized authority on the Digital Enterprise and author of The Quantum Age of IT: Why Everything You Know About IT is About to Change. As Principal Analyst with Intellyx, he writes, speaks and advises organizations on how to navigate through this time of disruption. He is also the founder of The Institute for Digital Transformation and a sought after keynote speaker. He has been a regular contributor to both InformationWeek and CIO Insight...
Bill Schmarzo, Tech Chair of "Big Data | Analytics" of upcoming CloudEXPO | DXWorldEXPO New York (November 12-13, 2018, New York City) today announced the outline and schedule of the track. "The track has been designed in experience/degree order," said Schmarzo. "So, that folks who attend the entire track can leave the conference with some of the skills necessary to get their work done when they get back to their offices. It actually ties back to some work that I'm doing at the University of ...
DXWorldEXPO LLC, the producer of the world's most influential technology conferences and trade shows has announced the 22nd International CloudEXPO | DXWorldEXPO "Early Bird Registration" is now open. Register for Full Conference "Gold Pass" ▸ Here (Expo Hall ▸ Here)
@DevOpsSummit at Cloud Expo, taking place November 12-13 in New York City, NY, is co-located with 22nd international CloudEXPO | first international DXWorldEXPO and will feature technical sessions from a rock star conference faculty and the leading industry players in the world. The widespread success of cloud computing is driving the DevOps revolution in enterprise IT. Now as never before, development teams must communicate and collaborate in a dynamic, 24/7/365 environment. There is no time t...
CloudEXPO New York 2018, colocated with DXWorldEXPO New York 2018 will be held November 11-13, 2018, in New York City and will bring together Cloud Computing, FinTech and Blockchain, Digital Transformation, Big Data, Internet of Things, DevOps, AI, Machine Learning and WebRTC to one location.
The best way to leverage your Cloud Expo presence as a sponsor and exhibitor is to plan your news announcements around our events. The press covering Cloud Expo and @ThingsExpo will have access to these releases and will amplify your news announcements. More than two dozen Cloud companies either set deals at our shows or have announced their mergers and acquisitions at Cloud Expo. Product announcements during our show provide your company with the most reach through our targeted audiences.
The Internet of Things will challenge the status quo of how IT and development organizations operate. Or will it? Certainly the fog layer of IoT requires special insights about data ontology, security and transactional integrity. But the developmental challenges are the same: People, Process and Platform and how we integrate our thinking to solve complicated problems. In his session at 19th Cloud Expo, Craig Sproule, CEO of Metavine, demonstrated how to move beyond today's coding paradigm and sh...
What are the new priorities for the connected business? First: businesses need to think differently about the types of connections they will need to make – these span well beyond the traditional app to app into more modern forms of integration including SaaS integrations, mobile integrations, APIs, device integration and Big Data integration. It’s important these are unified together vs. doing them all piecemeal. Second, these types of connections need to be simple to design, adapt and configure...