Click here to close now.

Welcome!

You will be redirected in 30 seconds or close now.

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

Related Topics: ColdFusion

ColdFusion: Article

Sending E-Mail With ColdFusion

Sending E-Mail With ColdFusion

You've seen it. You've probably done it, too. I'm talking about those Web sites that have a Contact Us link at the bottom of the page with something similar to mailto:[email protected] in the HREF attribute. They're kind of nice...

...and can spare you the burden of opening your e-mail client. They spawn a new message and populate the To: field and perhaps the Subject: field. The mailto: protocol can also be used in the ACTION attribute of the <form> tag. Pretty cool.

Great as the mailto: protocol is, it has shortcomings. Sometimes users don't have their e-mail client software configured correctly, so the link or form submission fails. Anyone who's installed MSIE on more than one occasion can probably attest to this. Plus, users have to confirm every e-mail sent via form submission. That's a necessary annoyance. Also, what if you want to capture more specific information about the user sending the e-mail? Sometimes a Subject: and Message: field just won't cut it.

That's what this article is about - creating an extensible, ColdFusion, Web-based e-mail application that uses only one CF template. This application offers several useful features; you'll see how to add and change them when you find a flavor that meets your needs. All this information will be in a zipped archive on the CFDJ site. Barring minor one-line code changes, the code is ready to use. Here are the features the application will cover:

  • Basic e-mail: Forms-based e-mail we all know and love
  • Handling multiple recipients: Grabbing names and addresses from a database and selecting multiple recipients
  • Keeping user input: Storing submitted info in a database for later crunching
  • Better-looking messages: Adding HTML and graphics to your messages
  • Send attachments: Adding the code for sending attachments

    ColdFusion makes incorporating these and other features quite easy.

    Introducing MailRat
    Figure 1 offers the debut of MailRat, the hippest new e-mail app ever to be powered by ColdFusion (let's not vote, though). As awesome and mind-bending as I've made it out to be, MailRat still consists of the following simple form elements:

  • Fields for your name and e-mail address
  • A SELECT list to choose the recipient's e-mail address(es)
  • A field to enter the topic you want to talk about
  • A text area to input your message
  • A file input field for attachment
  • Radio buttons for creating custom layouts for your messages

    The process is simple. Just enter the required information, then choose Go MailRat!. ColdFusion calls this same file, index.cfm, and changes the banner image on top to confirm that your message has been sent. Figure 2 shows the change in graphics. From the user's perspective there isn't much to it. Let's drill down a bit and see how it's all happening.

    Send e-Mail, Print the Form or Both
    index.cfm performs at least one operation and sometimes two. If the page is loaded for the first time, CF simply displays the MailRat interface. If the form is submitted, index.cfm needs to handle the e-mail operation, then print the interface. Let's assume this is the first time the page has loaded. In that case we'll be looking more at HTML than CFML. Listing 1, which is long but simple, contains the HTML output to create the interface.

    You won't find many surprises in that listing. It's really a form embedded in a couple of nested tables. The CFML in this portion of the document shows up when generating the SELECT list. Here it is up close:

    <select name="TheirEmail"
    style="width:258;" size="3" multiple>
    <CFOUTPUT QUERY="GetContacts">
    <option
    value="#EmailAddress#">#UserName#
    </CFOUTPUT>
    </select>

    The SELECT list is the product of a database query that occurred earlier in the execution. Here is the <CFQUERY>:

    <CFQUERY NAME="GetContacts" DATA-
    SOURCE="ContactDB">
    SELECT UserName, EmailAddress
    From Contacts
    </CFQUERY>

    The SQL inside this statement requests all usernames and corresponding e-mail addresses from the ContactDB data source, which is an MSAccess database. The SELECT list has OPTIONs with usernames as their text and e-mail addresses as their values. Notice, too, that the SELECT list contains the MULTIPLE attribute, i.e., all values of the selected options will be submitted to the server for processing.

    That's all there is to printing the form, except for the graphic at the top. If the MailRat is loading for the first time, ColdFusion displays the default banner. If mail was just sent, CF displays the mail-sent banner. This happens via a simple <CFIF> statement based on the value of the name entered. When the page loads for the first time, the default value of #YourName# is an empty string that cues CF to load the default banner.

    Creating and Validating the Message
    MailRat allows you to choose the type of layout you want the e-mail message to have. I used simple layouts, which basically changes the font family of the text. No reason why you can't go wild and exotic, though. Just make sure whoever receives this has an e-mail client that supports HTML. Most recent clients do, so you should be fine. You also have the option of choosing a file to send as an attachment; just click the button and choose the file from your directory tree. The only drawback is you lose any HTML layout capabilities you may have selected.

    What if you want to send the message to several people? After all, the SELECT list has the MULTIPLE attribute. In this case the code is no different. Remember that the value of #TheirEmail# is a comma-separated string, the same e-mail syntax for sending messages to multiple people. Choosing three people from the list would represent the value of #TheirEmail# to [email protected], [email protected] and person3 @somewhere.com. That's how the string will arrive when the script is called and how it'll be sent, as the value of the TO attribute.

    Notice that clicking on the radio buttons dynamically changes the image to match the mock-up of the font each layout will have. This article is about ColdFusion, but we should go over the JavaScript because there's so much interaction between the two. The image swap occurs when using the following code:

    function swapImg(idx) {
    document ['LayoutImg'].src =
    newImgs[idx].src; }

    It only takes three lines of code - not too bad. This function changes the source of the "Layout" image in the document, which you'll find near the radio button. When called, swapImg() expects an integer that'll reference an Image object with the corresponding JPEG image. Each radio button has the following code:

    onclick="swapImg(some_Integer);"

    Since there are only three images, the integer is either 0, 1 or 2. These integers reference an array element in the JavaScript array newImgs, which is created with a single call to function preload().

    function preload() {
    fExt = '.jpg';
    newImgs = new Array();
    var imgArr = new Array('Boring',
    'OK', 'Fancy');
    for (var i = 0; i
    imgArr.length; i++) {
    newImgs[newImgs.length] = new Image();
    newImgs[newImgs.length - 1].src = imgArr[i] + fExt;
    }
    }

    preload();

    This function preloads the images for the script. Image preloading is the process of downloading images and storing them in the browser cache before they're displayed. This may not seem like a big deal, but each time the user clicks a radio box for the first time, the browser normally makes an HTTP request back to the server to grab the image. If the images are loaded in the cache, the browser already has them and won't need to do the extra legwork.

    The array newImgs contains the Image objects with all the information about each JPEG. By the way, if you want to add more images for preloading, and they're JPEGs in the same folder as the others on the Web server, just add the first name of the image file as a string to the imgArray. For example, adding EvenFancier.jpg to the group changes the array as follows:

    var imgArr = new Array('Boring',
    'OK', 'Fancy', 'EvenFancier');


    Okay, the images are preloaded. The user has filled in the goods and selected an HTML layout option. Choosing Go MailRat! sets things in motion. Before sending everything back to the server, it's a good idea to get JavaScript involved again to make sure the user has provided enough information. Function checkMail() gets the call.

    function checkMail(f) {
    if((f.YourName.value == '') || (f.YourEmail.value == '') ||
    (f.TheirEmail.value == '') || (f.Message.value == '') ||
    (f.YourTopic.value == '')) {
    alert('You must complete all
    fields.');
    return false;
    }
    else if
    (isValidEmail(f.YourEmail.value) &&
    isValidEmail(f.TheirEmail.value)) {
    }
    else { return false; }
    }

    This function first determines if any of the fields (except the optional file attachment field) have been left empty. If so, the user is alerted and the form submission id canceled. Afterwards, checkMail() relies on isValidEmail() to make sure the e-mail address appears valid. I say appears valid because the actual code for validating e-mail addresses, according to the Internet standard, is thousands of characters long. For our purposes, as long as the user enters something, such as [email protected], everything will be fine. If the e-mail address fails this test, the user is again alerted and the submission canceled. Otherwise, it's back to the Web server with the form.

    function isValidEmail(str) {
    str += '';
    namestr = str.substring(0,
    str.indexOf("@")); // before the '@'
    domainstr =
    str.substring(str.indexOf("@")+1,
    str.length); // after the '@'
    if ((namestr.length == 0) ||
    (domainstr.indexOf(".") <= 0) ||
    (domainstr.length == 0) ||
    (domainstr.indexOf("@") != -1)) {
    alert('Hmmm.... "' + str + '"
    appears to be an invalid e-mail address.');
    return false;
    }
    return true;
    }

    Back to ColdFusion
    The form is submitted and index.cfm is called again, but this time things are different. All the CFML we glossed over at the beginning of the article comes into play. CFML uses a single <cfif> statement to determine whether to send e-mail (see Listing 2).

    The deciding factor for sending e-mail is the value of the variable #YourName#. If it's empty, the odds are there's no reason to send mail. As long as #YourName# isn't an empty string, CF will attempt to send e-mail. Once the script has determined that e-mail needs to be sent, it must check if the user uploaded a valid file for use as an attachment. This is done by not only checking the value of #Attachment#, but ensuring that the file exists. If both of the following conditions are true, the attachment will be sent with the plain text message:

    <CFIF #Attachment# NEQ "" AND #File-
    Exists(Attachment)# EQ "True">

    <CFMAIL
    FROM="#YourEmail#"
    TO="#TheirEmail#"
    SUBJECT="#YourTopic#"
    SERVER="pop.serve.com"
    MIMEATTACH="#Attachment#"
    >
    #YourName# wrote:
    #Message#

    <CFMAIL>
    This is the <CFMAIL> tag, which makes our job of sending e-mail ridiculously easy. Though we used only five of the attributes, let's take a look at all of them.

  • TO (required): This attribute expects the recipient's e-mail address(es). You can provide a static value or a ColdFusion variable. Multiple recipient addresses need only be separated by commas.
  • FROM (required): This attribute expects the sender's e-mail address.
  • CC (optional): This attribute can be set to one or more recipients to whom you'd like to send a copy. Can be set static or as a CF variable.
  • SUBJECT (required): This is the subject heading of the message and can be set to a static value or a CF variable.
  • TYPE (optional): This value indicates the MIME type of the message. It can only be set to a value of "HTML." If omitted, the message will be generated as plain text.
  • QUERY (optional): This attribute indicates the name of a database query performed with <cfquery> and can be used to print the results of a query in the message.
  • MAXROWS (optional): Indicates the maximum number of e-mail messages to send.
  • MIMEATTACH (optional): This attribute specifies the name of the path to a file attachment. The value can be static or a ColdFusion variable.
  • GROUP (optional): Used to group a set of query results by column name.
  • STARTROW (optional): Specifies which row to begin with in the query result set (the first row is 1 by default).
  • SERVER (required): Specifies the name or IP address of the SMTP server to contact in order to send the message. If this attribute isn't set, the script uses the SMTP server specified in the ColdFusion Administrator. For more information see the "Configuring a Default SMTP Server" section at the end of this article.
  • PORT (optional): This attribute indicates which TCP/IP port the SMTP listens to for requests. The default is 25.
  • MAILERID (optional): This attribute can specify a string in the SMTP header to identify the application. The default value is Allaire ColdFusion Application Server.
  • TIMEOUT (optional): This indicates the number of seconds to wait for a response from the SMTP server.

    Our <cfmail> tag identifies the sender, recipient, topic, SMTP server and file attachment value. The user provides the script with everything except the SMTP address. What about the message? It's placed between the opening and closing <cfmail></cfmail> tags. Notice there's no HTML, and there is a handful of carriage returns surrounding the #YourName# and #Message# variables. Since the e-mail will be sent as plain text, you have to do the formatting yourself. What you see is what you get.

    If the user hasn't uploaded a valid file attachment, the script uses a slightly different <cfmail> tag (see Listing 3).

    Since there isn't a valid file attached, CF can utilize the HTML attribute of the <cfmail> tag to output a message layout. It all depends on the value of the #Layout# variable, set when the user clicked on the selected radio button. The text in #YourName# and #Message# are still printed as before, but they're wrapped in some HTML.

    Once CF communicates with the SMTP server specified in the SERVER attribute and sends the message, why not store some info about the transaction? The following <cfquery> statement inserts a record into a waiting database.

    <CFQUERY DATASOURCE="ContactDB">
    INSERT INTO SentMessages
    (DateStamp, SenderName, SenderE-
    mail, Recipient, Topic, Message,
    Layout, Attachment)
    VALUES (#CreateODBCDateTime(Now())#, '#Your-
    Name#', '#YourEmail#',
    '#TheirEmail#', '#YourTopic#',
    '#Message#', '#Layout#',
    '#Attachment#')
    </CFQUERY>

    The DATASOURCE attribute is set to ContactDB, an MSAccess database included in the CFDJ download. The embedded SQL statement inserts a new record into the database, storing basically everything the message sender entered, plus the date and time the script ran by calling CFML functions #CreateODBCDateTime(Now())#. If you're interested in the sender's browser information and IP address, you could easily insert the CGI variables #HTTP_USER_AGENT# and #RE-MOTE_SERVER#.

    Wrapping Up
    After the e-mail is sent and the data is stored, the remaining code outputs the mail form to the browser. That's about it. Of course, you can change this application to suit your needs ad infinitum. One of the things you might want to change is the ability to enter any e-mail address without having to choose from a list. No problem. Change the SELECT list to INPUT TYPE=TEXT. Make sure you keep the same name of TheirEmail. Don't worry about validating the recipient's e-mail address before the form is submitted. The JavaScript function checkMail() already does it for you.

    Configuring a Default SMTP Server
    Notice that <CFMAIL> utilizes the SERVER attribute. You can set this value to an SMTP server. However, the CF Administrator makes it shamelessly easy to set a default SMTP server. That way you don't have to use the SERVER attribute every time you want to send mail. Here's how:
    1. Log into your CF Administrator.
    2. Choose Mail under the miscellaneous section.
    3. Enter the address of your SMTP server.
    4. If you want (but probably not), modify the port and time-out settings.
    5. Choose Apply.
    6. If you want to (probably so), choose Verify.

    That's all there is to it. If verification fails, check the SMTP server to confirm that it's available and running.

  • More Stories By Jerry Bradenbaugh

    Jerry Bradenbaugh works as a senior Web developer for Red Oak Technologies, Inc. (www.redoaktech.com). He focuses on robust Web-enabled systems using JavaScript, ColdFusion, Java and database technologies. He is also
    the Webmaster of HotSyte - The JavaScript Resource
    (www.serve.com/hotsyte) and is currently writing a JavaScript book for O'Reilly & Associates, Inc.

    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.


    @ThingsExpo Stories
    From telemedicine to smart cars, digital homes and industrial monitoring, the explosive growth of IoT has created exciting new business opportunities for real time calls and messaging. In his session at @ThingsExpo, Ivelin Ivanov, CEO and Co-Founder of Telestax, shared some of the new revenue sources that IoT created for Restcomm – the open source telephony platform from Telestax. Ivelin Ivanov is a technology entrepreneur who founded Mobicents, an Open Source VoIP Platform, to help create, deploy, and manage applications integrating voice, video and data. He is the co-founder of TeleStax, a...
    The industrial software market has treated data with the mentality of “collect everything now, worry about how to use it later.” We now find ourselves buried in data, with the pervasive connectivity of the (Industrial) Internet of Things only piling on more numbers. There’s too much data and not enough information. In his session at @ThingsExpo, Bob Gates, Global Marketing Director, GE’s Intelligent Platforms business, to discuss how realizing the power of IoT, software developers are now focused on understanding how industrial data can create intelligence for industrial operations. Imagine ...
    Operational Hadoop and the Lambda Architecture for Streaming Data Apache Hadoop is emerging as a distributed platform for handling large and fast incoming streams of data. Predictive maintenance, supply chain optimization, and Internet-of-Things analysis are examples where Hadoop provides the scalable storage, processing, and analytics platform to gain meaningful insights from granular data that is typically only valuable from a large-scale, aggregate view. One architecture useful for capturing and analyzing streaming data is the Lambda Architecture, representing a model of how to analyze rea...
    SYS-CON Events announced today that Vitria Technology, Inc. will exhibit at SYS-CON’s @ThingsExpo, which will take place on June 9-11, 2015, at the Javits Center in New York City, NY. Vitria will showcase the company’s new IoT Analytics Platform through live demonstrations at booth #330. Vitria’s IoT Analytics Platform, fully integrated and powered by an operational intelligence engine, enables customers to rapidly build and operationalize advanced analytics to deliver timely business outcomes for use cases across the industrial, enterprise, and consumer segments.
    The explosion of connected devices / sensors is creating an ever-expanding set of new and valuable data. In parallel the emerging capability of Big Data technologies to store, access, analyze, and react to this data is producing changes in business models under the umbrella of the Internet of Things (IoT). In particular within the Insurance industry, IoT appears positioned to enable deep changes by altering relationships between insurers, distributors, and the insured. In his session at @ThingsExpo, Michael Sick, a Senior Manager and Big Data Architect within Ernst and Young's Financial Servi...
    SYS-CON Events announced today that Open Data Centers (ODC), a carrier-neutral colocation provider, will exhibit at SYS-CON's 16th International Cloud Expo®, which will take place June 9-11, 2015, at the Javits Center in New York City, NY. Open Data Centers is a carrier-neutral data center operator in New Jersey and New York City offering alternative connectivity options for carriers, service providers and enterprise customers.
    When it comes to the Internet of Things, hooking up will get you only so far. If you want customers to commit, you need to go beyond simply connecting products. You need to use the devices themselves to transform how you engage with every customer and how you manage the entire product lifecycle. In his session at @ThingsExpo, Sean Lorenz, Technical Product Manager for Xively at LogMeIn, will show how “product relationship management” can help you leverage your connected devices and the data they generate about customer usage and product performance to deliver extremely compelling and reliabl...
    SYS-CON Events announced today that CodeFutures, a leading supplier of database performance tools, has been named a “Sponsor” of SYS-CON's 16th International Cloud Expo®, which will take place on June 9–11, 2015, at the Javits Center in New York, NY. CodeFutures is an independent software vendor focused on providing tools that deliver database performance tools that increase productivity during database development and increase database performance and scalability during production.
    The IoT market is projected to be $1.9 trillion tidal wave that’s bigger than the combined market for smartphones, tablets and PCs. While IoT is widely discussed, what not being talked about are the monetization opportunities that are created from ubiquitous connectivity and the ensuing avalanche of data. While we cannot foresee every service that the IoT will enable, we should future-proof operations by preparing to monetize them with extremely agile systems.
    There’s Big Data, then there’s really Big Data from the Internet of Things. IoT is evolving to include many data possibilities like new types of event, log and network data. The volumes are enormous, generating tens of billions of logs per day, which raise data challenges. Early IoT deployments are relying heavily on both the cloud and managed service providers to navigate these challenges. Learn about IoT, Big Data and deployments processing massive data volumes from wearables, utilities and other machines.
    The explosion of connected devices / sensors is creating an ever-expanding set of new and valuable data. In parallel the emerging capability of Big Data technologies to store, access, analyze, and react to this data is producing changes in business models under the umbrella of the Internet of Things (IoT). In particular within the Insurance industry, IoT appears positioned to enable deep changes by altering relationships between insurers, distributors, and the insured. In his session at @ThingsExpo, Michael Sick, a Senior Manager and Big Data Architect within Ernst and Young's Financial Servi...
    “In the past year we've seen a lot of stabilization of WebRTC. You can now use it in production with a far greater degree of certainty. A lot of the real developments in the past year have been in things like the data channel, which will enable a whole new type of application," explained Peter Dunkley, Technical Director at Acision, in this SYS-CON.tv interview at @ThingsExpo, held Nov 4–6, 2014, at the Santa Clara Convention Center in Santa Clara, CA.
    SYS-CON Events announced today that Intelligent Systems Services will exhibit at SYS-CON's 16th International Cloud Expo®, which will take place on June 9-11, 2015, at the Javits Center in New York City, NY. Established in 1994, Intelligent Systems Services Inc. is located near Washington, DC, with representatives and partners nationwide. ISS’s well-established track record is based on the continuous pursuit of excellence in designing, implementing and supporting nationwide clients’ mission-critical systems. ISS has completed many successful projects in Healthcare, Commercial, Manufacturing, ...
    PubNub on Monday has announced that it is partnering with IBM to bring its sophisticated real-time data streaming and messaging capabilities to Bluemix, IBM’s cloud development platform. “Today’s app and connected devices require an always-on connection, but building a secure, scalable solution from the ground up is time consuming, resource intensive, and error-prone,” said Todd Greene, CEO of PubNub. “PubNub enables web, mobile and IoT developers building apps on IBM Bluemix to quickly add scalable realtime functionality with minimal effort and cost.”
    The major cloud platforms defy a simple, side-by-side analysis. Each of the major IaaS public-cloud platforms offers their own unique strengths and functionality. Options for on-site private cloud are diverse as well, and must be designed and deployed while taking existing legacy architecture and infrastructure into account. Then the reality is that most enterprises are embarking on a hybrid cloud strategy and programs. In this Power Panel at 15th Cloud Expo (http://www.CloudComputingExpo.com), moderated by Ashar Baig, Research Director, Cloud, at Gigaom Research, Nate Gordon, Director of T...
    Sensor-enabled things are becoming more commonplace, precursors to a larger and more complex framework that most consider the ultimate promise of the IoT: things connecting, interacting, sharing, storing, and over time perhaps learning and predicting based on habits, behaviors, location, preferences, purchases and more. In his session at @ThingsExpo, Tom Wesselman, Director of Communications Ecosystem Architecture at Plantronics, will examine the still nascent IoT as it is coalescing, including what it is today, what it might ultimately be, the role of wearable tech, and technology gaps stil...
    DevOps tends to focus on the relationship between Dev and Ops, putting an emphasis on the ops and application infrastructure. But that’s changing with microservices architectures. In her session at DevOps Summit, Lori MacVittie, Evangelist for F5 Networks, will focus on how microservices are changing the underlying architectures needed to scale, secure and deliver applications based on highly distributed (micro) services and why that means an expansion into “the network” for DevOps.
    The Internet of Things (IoT) is causing data centers to become radically decentralized and atomized within a new paradigm known as “fog computing.” To support IoT applications, such as connected cars and smart grids, data centers' core functions will be decentralized out to the network's edges and endpoints (aka “fogs”). As this trend takes hold, Big Data analytics platforms will focus on high-volume log analysis (aka “logs”) and rely heavily on cognitive-computing algorithms (aka “cogs”) to make sense of it all.
    The Internet of Everything (IoE) brings together people, process, data and things to make networked connections more relevant and valuable than ever before – transforming information into knowledge and knowledge into wisdom. IoE creates new capabilities, richer experiences, and unprecedented opportunities to improve business and government operations, decision making and mission support capabilities. In his session at @ThingsExpo, Gary Hall, Chief Technology Officer, Federal Defense at Cisco Systems, will break down the core capabilities of IoT in multiple settings and expand upon IoE for bo...
    With several hundred implementations of IoT-enabled solutions in the past 12 months alone, this session will focus on experience over the art of the possible. Many can only imagine the most advanced telematics platform ever deployed, supporting millions of customers, producing tens of thousands events or GBs per trip, and hundreds of TBs per month. With the ability to support a billion sensor events per second, over 30PB of warm data for analytics, and hundreds of PBs for an data analytics archive, in his session at @ThingsExpo, Jim Kaskade, Vice President and General Manager, Big Data & Ana...