ColdFusion CFMailParam's New "Content" Attribute Is Awesome

Posted May 7, 2008 at 9:23 AM by Ben Nadel

Tags: ColdFusion

As part of the ColdFusion 8.0.1 updater, the CFMailParam tag can now attach files to an email using the Content attribute. When using this, the CFMailParam takes a File attribute and the Content attribute. In this case, the File attribute provides the name of the file as it will appear in the mail attachments list, not the path of the file on the server. The content attribute can take any ColdFusion variable that can be converted to binary data. Like the ColdFusion CFContent tag, this content attribute must use binary data; however, unlike the CFContent tag, the CFMailParam tag will automatically convert variables to binary data for you (when possible). Pretty awesome!

Let's take a look at an example. In this demo, I am going to attach a ColdFusion image object as well as a text value:

  • <!---
  • Grab an image from flickr.com and create a ColdFusion image
  • object via the URL.
  • --->
  • <cfset objImage = ImageNew(
  • "http://farm3.static.flickr.com/2304/2335117561_513d9f8a76_b.jpg"
  • ) />
  •  
  • <!--- Resize the image so that it's not too big. --->
  • <cfset ImageScaleToFit( objImage, 300, 300 ) />
  •  
  • <!--- Add a border. --->
  • <cfset ImageAddBorder( objImage, 2, "##333333" ) />
  •  
  •  
  • <!--- Create a signature variable. --->
  • <cfsavecontent variable="strSignature">
  • Ben Nadel
  • Kinky Solutions
  • www.kinkysolutions.com / www.bennadel.com
  • </cfsavecontent>
  •  
  •  
  •  
  • <!--- Send out email. --->
  • <cfmail
  • to="xxx@yyyyyyy.com"
  • from="yyy@zzzzz.com"
  • subject="Is that your wife???"
  • type="html">
  •  
  • Dude, I was doing some research for a business project
  • and I came across the attached file. Call me crazy,
  • but is that your wife making out with another chick??<br />
  • <br />
  •  
  • You better lock that down!<br />
  • <br />
  •  
  • <img src="cid:kissing" /><br />
  • <br />
  •  
  • Cheers,<br />
  • Ben
  •  
  • <!---
  • Attach file for inline usage. Use the contents of the
  • image object for the value of the CFMailParam. Unlike
  • the Content attribute in CFContent, we do not need to
  • use a binary variable here.
  • --->
  • <cfmailparam
  • file="wife_kissing_girl.jpg"
  • contentid="kissing"
  • content="#objImage#"
  • disposition="inline"
  • />
  •  
  • <!--- Attach signature text. --->
  • <cfmailparam
  • file="signature.txt"
  • content="#Trim( strSignature )#"
  • />
  •  
  • </cfmail>

Notice that we are passing the objImage variable directly to the CFMailParam tag. My first instinct was that I had to pass the ImageGetBlob( objImage ) value since that would give me the binary image data (which did work as expected), but after some testing, I found out that the CFMailParam tag will try automatically convert the value to binary for me. Of course, this doesn't always work. If you try to attach a ColdFusion query, for example:

  • <!--- Add query to email. --->
  • <cfmailparam
  • file="query.txt"
  • content="#QueryNew( 'id, name, value' )#"
  • />

ColdFusion will throw the following exception:

Could not convert the value of type class coldfusion.sql.QueryTable to binary.

As you can see, it is trying to do the binary conversion for you.

Anyway, running the above code resulted in the following GMail email:


 
 
 

 
CFMailParam Uses Content Attribute To Attach Email Attachements - Image And Text  
 
 
 

Notice also that for my signature file, I am not attaching a variable, but rather a trimmed text value. The documentation states that this has to be a ColdFusion variable, but it simply has to be a value that can be converted to binary (which can be an inline text value). Also, I was able to use the CFMailParam and Content tag to create attached files as well as files with an inline disposition (the image displayed within the content of the email itself). This is insanely cool. This, combined with the new Remove attribute is going to make the ColdFusion CFMailParam tag a force to be reconned with! I think these small tweaks are going to have fantastic improvements in the usability of these tags.




Reader Comments

May 22, 2008 at 4:49 PM // reply »
1 Comments

I think it is correctly spelled "reckoned," as in "I reckon you right about that."

In the email generation that we have done from Coldfusion server, we have more routinely relied on <img> tags that call back to our server, rather than sending the image content in the actual email. But, I guess that is because we aren't explicitly sending pictures, more just images for look and feel.

While it is sort of outside the range of your exploration of the content attribute, under what circumstances is it appropriate to send content via email and when should links be provided to pull content off a server?


May 22, 2008 at 6:10 PM // reply »
11,246 Comments

@Phil,

I am not sure there are any good rules on when to do this. I like the fact that with an embedded image, the images get loaded in the email without prompting the user for permission. This allows me to deliver my brand more effectively (I think).

On the other hand, the attachment does cause problems sometimes. For instance, right now, I am having some mail delivery problems for emails that have embedded images... Adobe is working on a hotfix for this.


Oct 9, 2008 at 3:47 PM // reply »
2 Comments

BTW... it seems like you can also pass in the filename for attachment...

disposition="attachment; filename=sample.png;"


Jan 24, 2009 at 8:34 PM // reply »
16 Comments

Ben, have you had luck actually receiving these emails? Running your example as-is doesn't work for me in Thunderbird 2. And based on these tests, image embedding is highly unreliable in general. It's a great technology but has been abused to death by spammers it seems. :(

http://www.campaignmonitor.com/blog/post/1761/embedding-images-in-email/


Jan 30, 2009 at 9:51 AM // reply »
11,246 Comments

@Brian,

The Content attribute works for more that just embedded images. It should work for any sort of attached file. I have tried it successfully with attached files.


Jim
Aug 7, 2009 at 10:47 AM // reply »
2 Comments

No... that was my wife.


Oct 6, 2009 at 9:32 AM // reply »
92 Comments

I took a look at this after your post on Twitter (thanks for suggesting it). I don't think it's possible to do what I need though by using this tag.

I have a file that exists in memory and I'd like to attach that to an email without first having to save it to disk. It's essentially an on demand report generation request and there's NO way I want to manage those files.


Oct 6, 2009 at 9:41 AM // reply »
11,246 Comments

@Andy,

Assuming this file exists in memory as either text or binary data, all you have to do is use it in the content attribute of the CFMailParam:

<cfmailparam
content="#YOUR_FILE_VARIABLES#"
file="arbitrary_file_name.ext"
/>

The "file" attribute here is arbitrary - it's just used when ColdFusion actually attaches the given variable to the email.


Oct 6, 2009 at 9:42 AM // reply »
11,246 Comments

@Andy,

If you look at this follow-up post:

http://www.bennadel.com/blog/1700-Ask-Ben-Creating-A-PDF-And-Attaching-It-To-An-Email-Using-ColdFusion.htm

... you'll see that I am creating a PDF file in memory and then attaching it to the email without ever saving it to a physical file.


Oct 6, 2009 at 1:42 PM // reply »
16 Comments

@Ben - what happens when using the content attribute if you have mail set to spool? Does CF write out a temp file somewhere or does this force it to send on-the-fly?


Oct 6, 2009 at 1:44 PM // reply »
11,246 Comments

@Brian,

I don't know what actually happens behind the scene. But ColdFusion handles it properly.


Oct 6, 2009 at 1:46 PM // reply »
11,246 Comments

@Brian,

Also, the CFMailParam "Delete" attribute is great for that stuff as well, if you DO have a physical file:

http://www.bennadel.com/blog/1214-New-ColdFusion-CFMailParam-Remove-Attribute-Makes-Deleting-Attachments-Simple.htm


Oct 6, 2009 at 2:58 PM // reply »
16 Comments

I really need to read the what's changed documentation better. Thanks Ben! :)


Oct 6, 2009 at 3:00 PM // reply »
11,246 Comments

@Brian,

No problem my man. If you have any questions, drop by :)


Oct 22, 2009 at 9:43 AM // reply »
2 Comments

@Ben

The content tag looks awesome, but I'm getting the error: Attribute validation error for tag CFMAILPARAM.The tag does not allow the attribute(s) CONTENT. The valid attribute(s) are CONTENTID,DISPOSITION,FILE,NAME,TYPE,VALUE.

This led me to believe we were running an older version of coldfusion, but it is 8.01xxx Any ideas?

Thanks a lot though, your examples are always great.


Oct 31, 2009 at 3:53 PM // reply »
11,246 Comments

@Kosko,

From the docs, it looks like it was added in the 8.01 updater. Perhaps you are just missing one of the required updates?


Aug 23, 2010 at 9:13 PM // reply »
17 Comments

I just discovered this "new" content attribute of CF8.01. The Adobe Live Docs don't mention it unless you read the new CF9 docs, so thank you for this blog post.

I was revisiting a CF7 app and needed to improve the effeciency of how the emails are generated. I've now changed it from reading in a file attachment for EVERY iteration of cfmail to storing the file as a binary variable and using the content attribute to take the file from memory instead. So if 50K personalised emails with attachments need to be generated it will require 1 file read instead of 50K.

Ben, is there anything that you haven't blogged about? :-)


Aug 23, 2010 at 9:20 PM // reply »
11,246 Comments

@Gary,

That's awesome my man! I've never thought about in terms of file reads before, but that makes perfect sense. Glad that this was able to help :)


Sep 8, 2010 at 12:39 PM // reply »
3 Comments

Ben,
Mine is version 8 and tried to download the update but still did not recognized content attribute in cfmailparam. May be I installed a wrong update, so many of them not sure which one I need with no clear explanation from adobe. Can anyone help pointing me to the right update file? please?


Sep 9, 2010 at 10:50 AM // reply »
11,246 Comments

@Alecken,

If it didn't work with the updater, then I don't have any great advice for you. When things don't work at that level, I definitely feel stuck. Perhaps try the updater again to make sure it worked?


Dec 14, 2012 at 2:52 PM // reply »
6 Comments

Ben,

Have you ever experienced any issues when using a dynamically generated file name instead of a static one like in your example?

I have an application where it reads multiple files from a data base and then uses this technique to add the binary representation of the file as a mail param.

The name of the file is stored in the database and read as a variable.

Sometimes it will work correctly, other times I receive something like CF124356.tmp for the attachment, instead of myfile.pdf

<cfmailparam content="#ToBinary(local.qryGetFileNames.FILE_BLOB)#" type="#local.qryGetFileNames.File_type#" file="#local.qryGetFileNames.File_Name#" disposition="attachment; filename=""#local.qryGetFileNames.File_Name#"""/>

Thanks


Mar 14, 2013 at 5:08 PM // reply »
1 Comments

Jordan, I'm having the exact same problem. Most of the time it will work but other times I'll get a .tmp file with a long random numeric string name. If you rename the .tmp to .pdf after downloading it from the attachment the file is perfectly fine... it's just the name that is getting screwed up.


Mar 15, 2013 at 2:22 PM // reply »
6 Comments

@Zachariah,

I was able to work around this problem by creating a temporary directory using CreateUUID() for the entire job. Then, for each unique e-mail address a separate directory based on a numerical sequence is created inside of the main temporary directory.

Once the temporary directories is created, the application writes the file from the database into the physical location on disk. The file is then attached using <cfmailparam remove="yes" />. The remove="yes" attribute instructs the mail spooler to delete the file after the file has been successfully sent.

There is a service that runs nightly to clean up the empty temporary directories. This solution works great and there have not been any problems since.

Hope that helps.



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 25, 2013 at 10:01 PM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
@Avi, Really glad to help! @Jaredwilli, I'm finding a this image hits home with a lot of people :) Hopefully we can all work through the rough patches together! @Prateek, AngularJS has error ... read »
May 25, 2013 at 9:53 PM
Nested Views, Routing, And Deep Linking With AngularJS
@Mrsean2k, I'm glad I could help! I haven't been able to keep up with the ui-router stuff. I keep saying that I'll carve out time, but I just haven't gotten to it :( ... read »
May 25, 2013 at 9:49 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, Thanks for the book recommendations. I am looking them up right now. I can see that Object Thinking is available for the Kindle App - sweet! Also, I just recently heard Martin Fowler on the ... read »
May 25, 2013 at 9:41 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
@Chris, I'm super excited to hear that my posts are helpful. I am also loving AngularJS; but, it definitely has some caveats and some odd behaviors and some things that just don't seem to "wor ... read »
May 25, 2013 at 9:36 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
@Adam, @Jason, After reading these comments, I double-checked my latest implementation and I am happy to report that I am using listFirst() and listRest(). ... read »
May 25, 2013 at 9:31 PM
Using "//" And ".//" Expressions In XPath XML Search Directives In ColdFusion
@Daxesh, I am not sure I understand the question about the current node. If you already have a reference to the current node, why would you need to query for it? As for parent node, I believe that ... read »
May 25, 2013 at 10:08 AM
Using "//" And ".//" Expressions In XPath XML Search Directives In ColdFusion
@Ben, my question is that i want the current node with its tag and its parent node. i just want only that data. So, give me the solution for that. and remember solution is working on " xpath 1.0 ... read »
May 25, 2013 at 10:01 AM
Using "//" And ".//" Expressions In XPath XML Search Directives In ColdFusion
hey ben, i want get my current node tag and also want the root node tag withing. So, how can i fix it.. ! ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools