Using CFMAIL to send attachments stored in memory

Categories: HTML/ColdFusion, Source Code, Java

Awhile back I was looking for a way to send e-mail attachments in CFMX without writing data to disk. That solution uses the Javamail API to directly send a e-mail with attachments to an SMTP server. This method also completely bypasses the CF mail spool.

Charlie Arehart linked to the article from an article he wrote about storing CFDOCUMENT and CFREPORT contents in a variable. In the comments on his post, Jon Wolski posted a solution that uses the built-in ColdFusion tags CFMAIL and CFMAILPART. So, I thought I'd re-do my original example using Jon's technique in this post—just so you can see an example of both methods.

Below is some source code that will show you how to use the CFMAIL tag to send a multipart message that contains:

  • Plain Text
  • HTML (with embedded images)
  • Two file attachments from binary data stored in memory
<!---// create a PDF document and save it to a variable //--->
<cfdocument format="pdf" name="binPdf">
   <h1>
      A PDF Document
   </h1>

   <p>
      This is a document rendered by the cfdocument tag
      at <cfoutput>#dateFormat(now(), "mmmm dd, yyyy")#
      #lCase(timeFormat(now(), "h:mmtt"))#</cfoutput>.
   </p>
   <table width="50%" border="2" cellspacing="2" cellpadding="2">
      <tr>
         <td><strong>Name</strong></td>
         <td><strong>Role</strong></td>
      </tr>
      <tr>
         <td>Bill</td>
         <td>Lead</td>
      </tr>
      <tr>
         <td>Susan</td>
         <td>Principal Writer</td>
      </tr>
      <tr>
         <td>Adelaide</td>
         <td>Part Time Senior Writer</td>
      </tr>
      <tr>
         <td>Thomas</td>
         <td>Full Time for 6 months</td>
      </tr>
      <tr>
         <td>Michael</td>
         <td>Full Time for 4 months</td>
      </tr>
   </table>
</cfdocument>

<!---// create a png chart and save it to a variable //--->
<cfchart name="binChart" format="png" font="arialunicodeMS" xaxistitle="Month" yaxistitle="Degrees Celsius" showlegend="yes">
   <cfchartseries type="line" serieslabel="Europe">
      <cfloop index="i" list="Apr,May,Jun,Jul,Aug,Sep">
         <cfchartdata item="#i#" value="#RandRange(12,42)#">
      </cfloop>
   </cfchartseries>
   <cfchartseries type="line" serieslabel="USA">
      <cfloop index="j" list="Apr,May,Jun,Jul,Aug,Sep">
         <cfchartdata item="#j#" value="#RandRange(12,42)#">
      </cfloop>
   </cfchartseries>
</cfchart>

<cfscript>
// config
sSubject = "CFMAIL w/diskless attachment!";
sAddyTo = "to@yourcompany.com";
sAddyFrom = "from@yourcompany.com";

// create the boundary marker indicating each new multi-part section
sBoundary = createUUID();
// create the CID for the embedded image
sCID = "23abc@pc27";
</cfscript>

<cfmail to="#sAddyTo#" from="#sAddyFrom#" subject="#sSubject#">
<cfmailpart type="multipart/mixed; boundary=#chr(34)##sBoundary##chr(34)#">
--#sBoundary#
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<html>
<head>
   <title>HTML E-mail</title>
</head>
<body>
   <h1>
      You like using HTML e-mail in CFMX.
   </h1>
   <p>
      <img src=cid:#sCID# />
   </p>
</body>
</html>

--#sBoundary#
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

You like using plain text in CFMX.

--#sBoundary#
Content-Type: application/pdf
Content-Disposition: attachment; filename=test-file.pdf
Content-Transfer-Encoding: Base64

#binaryEncode(binPdf, "base64")#

--#sBoundary#
Content-Type: image/png
Content-Disposition: attachment; filename=chart.png
Content-Transfer-Encoding: Base64

#binaryEncode(binChart, "base64")#

--#sBoundary#
Content-Type: image/png
Content-Disposition: attachment; filename=chart2.png
Content-ID: <#sCID#>
Content-Transfer-Encoding: Base64

#binaryEncode(binChart, "base64")#

--#sBoundary#--
</cfmailpart>
<cfmailpart type="application/x-unsupported">
This should not be rendered by a mail user agent because it does not support the MIME-type.
</cfmailpart>
</cfmail>

Related Blog Entries

Comments

Jeff Fleitz's Gravatar Nice!

Thanks for sharing.
John Wells's Gravatar Great looking example. I am going to try it. Do you know of any good examples on processing incoming emails? I am using Version 7 now but soon to get v8. Thanks
Ben Nadel's Gravatar Dan, this is awesome! I commented a long time ago on your post about sending in-memory binary data using the Java mail API, but that post went pretty high over my head :) This one, however, looks super straight forward. Thanks for showing this demo.
Dan G. Switzer, II's Gravatar @Ben:

One thing that was pointed out by someone else on CF-Talk was that this method does *not* generate a syntactically correct SMTP message. This means some mail clients may not correctly interpret the message.

For this reason, I'd suggest still using the Javamail API method.
Ben Nadel's Gravatar Good to know. Thanks.
Susan Hansen's Gravatar I am SOOOOO glad you take the time to post information like this for librarians like me who have to do CF on 10 hours/week and absolutely NO programming skills. I got this code to email me a PDF of my list of fields, but it is not filling in the data from my form. Should it be able to do that without external programs? I'm pushing hard to get CF8 here but since we just got 7, I have to make something else work for a while. The form I'm trying to send via email and display as a pdf is at http://www.rochesterpubliclibrary.org/apps/forms/A... if anyone has thoughts for me I would really appreciate it. Once I get one of these going, I can use it for many applications we have at the library.
Dan G. Switzer, II's Gravatar @Susan:

As a comment above mentions, you would probably be better off using the method talked about here:

http://blog.pengoworks.com/index.cfm/2007/2/8/Send...

That should show you off enough code to get you up and running.

Add Comment



If you subscribe, any new posts to this thread will be sent to your email address.