home Links Articles Books Past Meetings Photos SiteMap
The MDCFUG is sponsored by TeraTech. Visit us at www.TeraTech.com

Please send
comments/questions to

michael@
teratech.com

 

Practical CF:
<CFMAIL>

by Eron Cohen and Micahel Smith
TeraTech http://www.teratech.com/
Almost any company that has a customer database will occasionally find the need to send a personalized email to their customers. ColdFusion makes it very easy to create one off mass mailings or to build an automated mass-mailing engine for your client. Lets go over the basics and then we will talk about how to really make your email sing!

The star of our show is the CFMAIL tag. CFMAIL is used to actually send email. It's really quite simple to understand. In order to send a single email, all you need to know is the email address of the sender and receiver, and the subject. The code to send a message looks like this:

<CFMAIL TO="Michael@teratech.com" from="eron@in-sync.com" SUBJECT="Test Message" SERVER="smtp.my_mail_server.com">

Dear Michael,

I am testing the CFMAIL tag in ColdFusion…its easy!

Eron

</CFMAIL>

For a basic email message that is all there is to it! Not too bad huh? But that's just where the magic starts. You see there are a few more parameters and techniques that can be used with CFMAIL that make it even more powerful than that. For instance, you can use CFMAIL in conjunction with a database query to dynamically generate and send out email messages on the fly.

 
Dynamic Email Messages

So lets look more closely at how to go about sending out personalized/dynamic email messages. Lets pretend that our underwear company is having a sale on factory seconds. The marketing people need us to email all the customers in our database to tell them that they can get slightly irregular skivvies in their favorite color, style and size for ½ price.

They give you the following template to work from-they've bolded all the pieces they would like you to replace dynamically to personalize the message for each customer:

Customer Name
Customer Address
Customer City, Customer State, Customer Postal Code
Customer Country

Todays Date

Dear Customer First Name Customer Last Name,

We're pleased to announce our annual Who's Gonna See Them Anyway factory seconds sale. All of our irregular underwear is on sale for ½ the price of our regular underwear. You'll be glad to know we even have a large stock of size CUSTOMER SIZE CUSTOMER COLOR CUSTOMER STYLE ready for action in your drawers.

For more information, visit our website: http://www.latebloomersundies.com!

We're at your service,

Late Bloomers Incorporated

We check the database and see that we have thousands of customers to notify. But this is no problem, CFMAIL to the rescue. The process of solving this problem is fairly straightforward. First, you need to create a query to ascertain all the relevant data about your customers from the database. We are going to need all the fields from Customer_Table and we really only want rows that contain customers who have given us their email address so we'll filter out the customers who's email addresses are null:

<CFQUERY NAME="Get_Late_Bloomers_Customers" DATASOURCE="Late_Bloomers">

Select *
From customer_table
Where email_address is not null

</CFQUERY>

Now you use CFMAIL to send out the message to the people returned by the query. Basically, there are two ways of doing this. The easiest method is to use the QUERY= parameter of CFMAIL. By doing so, ColdFusion will effectively loop through and send out a single mail message for every record returned by the query. Effectively this means you need to make sure you use variables in the right places to avoid sending the same person thousands of email messages. To help you with this task, CFMAIL also allows you to use the GROUP= parameter. In our case, we'll want to use it with the Customer_id field so that customer's who's records return multiple rows will only get sent one email message:

<CFMAIL TO="#customer_email#" FROM="sales@latebloomersundies.com" SUBJECT="Factory Seconds Sale!" SERVER="smtp.latebloomersundies.com" QUERY="Get_Late_Bloomers_Customers" GROUP="Customer_id">

#customer_first_name# #customer_last_name#
#Customer_Street_Address#
#Customer_City#, #Customer_State#, #Customer_Postal_Code#
#Customer_Country#

#dateformat(now(),"mm/dd/yyyy")#

Dear #customer_first_name# #customer_last_name#,

We're pleased to announce our annual Who's Gonna See Them Anyway factory seconds sale. All of our irregular underwear is on sale for ½ the price of our regular underwear. You'll be glad to know we even have a large stock of size #customer_size# #customer_color# #customer_style# ready for action in your drawers.

For more information, visit our website: http://www.latebloomersundies.com!

We're at your service,

Late Bloomers Incorporated

</CFMAIL>

That's really all there is to it. This will email all of the Late Bloomer's customers that were contained in the GET_LATE_BLOOMERS_CUSTOMERS query. All of the variables from our query (the field names that are referenced between pound signs) will be replaced with values from each row when we run the template. The only trouble with using this method is that it gives you hardly any control or feedback about the mail that is going out. There's no way to know for sure that every customer who was supposed to be emailed was sent a message. That is why you will sometimes need to use a different method. Instead of letting CFMAIL do the work using the QUERY= parameter, you can use CFLOOP to loop through the records one at a time to send out your message. In doing so, you can add an extra insert query that will mark each record as your message is sent to them. This way you can stop the query and still easily pick up where you left off.

Using the same query from above, the new code would be as shown below. Note that we'd need to make provisions in the query to handle grouping so that we don't send out duplicate email messages. Also, I've added a table to our database to keep track of which customers got which mass-mailing. This way, if something goes wrong, we'll know who already got the message. The table simply contains a field for the name of the mailing and the Customer_ID of the person who received it.

<!---Loop through query and send an email to each customer ---> <CFLOOP QUERY="Get_Late_Bloomers_Customers" >

<!---Now send the actual email--->
<CFMAIL TO="#customer_email#" FROM="sales@latebloomersundies.com" SUBJECT="Factory Seconds Sale!" SERVER="smtp.latebloomersundies.com" >

#customer_first_name# #customer_last_name#
#Customer_Street_Address#
#Customer_City#, #Customer_State#, #Customer_Postal_Code#
#Customer_Country#

#dateformat(now(),"mm/dd/yyyy")#

Dear #customer_first_name# #customer_last_name#,

We're pleased to announce our annual Who's Gonna See Them Anyway factory seconds sale. All of our irregular underwear is on sale for ½ the price of our regular underwear. You'll be glad to know we even have a large stock of size #customer_size# #customer_color# #customer_style# ready for action in your drawers.

For more information, visit our website: http://www.latebloomersundies.com!

We're at your service,

Late Bloomers Incorporated
</CFMAIL>

<!---Finally insert a row confirming the mail was sent --->
<CFQUERY NAME="Mass_Mail_Sent" DATASOURCE="Late_Bloomers">

INSERT INTO mass_mail_sent
(
Mass_mail_name,
Customer_ID
)

VALUES

(
'Half Price Seconds',
#Get_Late_Bloomers_Customers .customer_id#

)

</CFQUERY>

</CFLOOP>

Other CFMAIL parameters you should know about

Although only a few of the parameters for CFMAIL are required, there are a few other CFMAIL parameters that you should be aware of. The only parameters that you absolutely need for every single CFMAIL message that you send out are TO, FROM and SUBJECT. You will also need to specify the SERVER if there is none defined in your CFADMINISTRATOR as shown below.

But there are also some very useful optional parameters that you'll probably use often in your CFMAIL career. For instance, oftentimes, you'll want to send out a mail message using HTML rather than plain text. To do so, you simply specify TYPE="HTML" parameter. When doing so, you should be aware that there are still quite a few people who's email clients don't have or don't allow HTML formatted email. If you don't already know for sure your targets have HTML capabilities, you should either refrain from sending out HTML emails or at very least send out the message with both plain text and HTML. The simplest way to do so is to put the plaintext version of the message at the beginning and use HTML comments to comment out what you've written in plain text. (Be careful not to use ColdFusion comments! HTML comments only have two dashes: <!- - an HTML comment - - > while ColdFusion comments have three <- - - a ColdFusion Comment --->. If you use ColdFusion comments by mistake, the plaintext version of the message won't go out as part of the email message at all. ) This way, your HTML enabled recipients will not see the message twice because its commented out using HTML comments, while on the other hand, your plaintext only recipients will see the plain text version of the message first (albeit between a couple of HTML comment tags) and then they will see the message again as HTML code.

Another useful one is the MIMEATTACH parameter. This allows you to attach a single file to your outgoing email message. To use it, you simply set the value equal to the full path and file name of the file you wish to send. For instance, to send a GIF file of the latest styles from Late Bloomers you'd add the parameter MIMEATTCH="c:\temp\latest_styles.gif". If you want to attach more than one file to an outgoing message, you'll need to use a secondary tag: CFMAILPARAM. It can be used in conjunction with or instead of the MIMEATTACH parameter of CFMAIL. To send the same GIF file with CFMAILPARAM, you would include the following code in between your <CFMAIL></CFMAIL> tags.

<CFMAIL TO= FROM= SUBJECT= ...>
<CFMAILPARAM FILE=" c:\temp\latest_styles.gif ">
Message body…
</CFMAIL>

For reference, here is the complete lineup of parameters for the CFMAIL tag:

<CFMAIL TO="the email address of the recipient"
FROM="the email address of the sender"
CC="email address for a carbon copy of the message to be sent to"
BCC=" email address for a blind carbon copy of the message to be sent to "
SUBJECT="subject of the message"
TYPE="if you want to send out a HTML formatted message, the TYPE should be set to HTML"
MAXROWS="Maximum number of email messages that should be sent out"
MIMEATTACH="path to a file you want to attach to the message. For multiple attachments use the CFMAILPARAM tag"
QUERY="Name of SQL query that contains the dynamic information referenced in your message"
GROUP="Used to prevent duplicate emails from beings sent-same as GROUP in CFOUTPUT"
GROUPCASESENSITIVE="yes/no: do you want GROUP to be casesensitive" STARTROW="1st row of the query you want to use for your dynamic information"
SERVER="IP Address or host name of the SMTP mail server you wish to use"
PORT="Port ID of the mail server's SMPT port"
MAILERID="How you want the mailer to be identified in the message header. ColdFusion 4.x is the default."
TIMEOUT="How long in seconds to wait for a response from the SMTP server">

Creating a massmail gateway

So now you know how to do one off mass mailings. But suppose your marketing people like to do regular mailings. If you're like most web developers, you've got a full plate and don't really have time to do this on a regular basis. What you need to do is create a gateway for your coworkers to send out the mailing themselves. Again, in its most basic form, this is a very simple matter. In short you need to make a form that will allow the user to choose options and compose the text of their message.

For extra spice and ease of use, I recommend using the Ektron eWebEditPro tag instead of the <textarea>. This will allow your people to create the message in Microsoft office and then just paste it in, pictures, formatting and all.

More about how CFMAIL works

When CFMAIL generates an email message, it first is written to a spool directory. Basically, what this means is that it is written to a specific place on the server's hard drive where it waits to be passed on to your email server. This is important because sometimes the process can take a second or more per message. If you were sending out a mailing to hundreds of people, ColdFusion would have to wait for each message to be sent on before it could continue. Instead, it just deposits them into this temporary spool directory where it waits its turn to be sent. Next time you use CFMAIL to send out an email message look in your C:\Cfusion\Mail\Spool directory. If you're quick (Or your servers are slow) you'll see a file with a cryptic name appear in that directory and then disappear.

Hopefully, when it disappears, it has been successfully handed-off to your email server…if the message is rejected by the mail server for some reason, then it will wind up in the C:\Cfusion\Mail\Undelivr directory. There it will stay as a "dead letter" until some kind of action is taken to remove it or an attempt is made to resend it. If you send out a lot of mail, it's a good idea to get hold of a custom tag [tag name=??]from the Allaire tag gallery that will reprocess the messages that are in this directory. It will attempt to resend them until they reach a certain age, and then it will just delete them. If you're curious to see what sort of messages are not being delivered you can open the files with a text editor such as notepad. You should look for problems in the mail message headers - obviously, the most likely problem is an incorrect or badly formatted email address. The headers look something like:

x-cf-version: 4.5.0
x-cf-server: smtp.myserver.com
x-cf-port: 25
x-cf-timeout: 60
x-cf-from: eron@in-sync.com
x-cf-to: larysa@in-sync.com

Content-type: text/plain

Date: Thu, 30 Mar 2000 22:13:27 +0400

From: eron@in-sync.com

Subject: Your Password

To: larysa@in-sync.com

By default, ColdFusion also logs any problem emails in the mail.log file. For debugging and security purposes, you can make adjustments in the ColdFusion Administrator so that even just informational messages about outgoing emails are logged. Furthermore, you can even have ColdFusion log the text of ALL outgoing email messages. Needless to say, this could cause your logs to get very large very fast. To view your mail.log file (and your other ColdFusion logs) go to the ColdFusion Administrator under LOGGING>MAIL LOG. Or, you can get to it directly by looking in your c:\cfusion\log\ directory for mail.log.

-Replacements for CFMAIL
-Problems to overcome

Other ideas
CFX_MAIL
Separat the mail server from the CF server
Auto email when place order
Other x-mailer headers - eg priority
SPAM - how not to spam
Bounces - soft and hard
Trouble shooting
Test email to self when doing mass emails
IMS mail server written in CF

Summary

CFMAIL is an easy to use was to send email from ColdFusion - whether you are sending one customized email or thousands

Resources

ColdFusion Documentation

Bio

Eron Cohen is ColdFusion programmer, MDCFUG speaker and author. Michael Smith is president of TeraTech http://www.teratech.com/, a 11-year-old Rockville, Maryland based consulting company that specializes in ColdFusion, Database and Visual Basic development. Michael runs the MDCFUG and recently organized the two-day, Washington, DC-based CFUN-2k conference which attracted more than 750 participants. You can reach Michael at michael@teratech.com or 301-424-3903


Home | Links | Articles | Past Meetings | Meeting Photos | Site Map
About MDCFUG | Join | Mailing List |Forums | Directions |Suggestions | Quotes | Newbie Tips
TOP

Copyright © 1997-2017, Maryland Cold Fusion User Group. All rights reserved.
< >