I am trying to figure out the best way to do this. I have an interception point that will basically send an email. The email is great except for one thing. I need to run a query get the records associated with this order and then create a pdf on the fly and attach it to the email. I have the pdf template working in a .cfm just how I want it. Just a little confused on where that cfdocument / pdf generation takes place. The query can be a service I inject here but just a little bit confused on how/where to generate my pdf and then attach it. Any suggestions?
public void function onLeadsImported(event,interceptData) {
var order = arguments.interceptData.order;
var user = arguments.interceptData.user;
var subject = “YOLO Marketing - You have new leads”;
var bodyTokens = {
firstName = user.getFirstName(),
lastname = user.getLastName()
};
var mail = mailservice.newMail(to=user.getEmail(),
from=variables.outgoingemail,
subject=subject,
bodyTokens=bodyTokens);
// generate content for email from template
mail.setBody( renderer.renderView(view=“email_templates/order_newleadsimport”) );
mail.setType(“HTML”);
mail.setUseSSL( getUseSSL() );
mail.setUseSSL( getUseTLS() );
mailService.send( mail );
One problem I see that there is no content argument in the Mail object.
<!--- addMailParam --->
<cffunction name="addMailParam" access="public" returntype="any" output="false" hint="Add mail params to this payload">
<cfargument name="contentID" required="false" type="string" hint="Initial value for the contentID property." />
<cfargument name="disposition" required="false" type="string" hint="Initial value for the dispositio nproperty." />
<cfargument name="file" required="false" type="string" hint="Initial value for the file property." />
<cfargument name="type" required="false" type="string" hint="Initial value for the type property." />
<cfargument name="name" required="false" type="string" hint="Initial value for the name property." />
<cfargument name="value" required="false" type="string" hint="Initial value for the value property." />
<cfargument name="remove" required="false" type="boolean" hint="If true, ColdFusion removes attachment files (if any) after the mail is successfully delivered.">
<cfscript>
// Add new mail Param
var mailparams = structnew();
var key = 0;
for( key in arguments ){
if( structKeyExists(arguments, key) ){ mailparams[key] = arguments[key]; }
}
arrayAppend(getMailParams(), mailparams);
return this;
</cfscript>
</cffunction>
Where in my quick test the cfdocument name is leads
OK so I figured it out, sorta. I put my pdf content in a view, grabbed the leads in my interceptor method and passed them to the render view method using the args argument. This almost works except the pdf attached to the document has an error (see attachment). Am I on the right course? If so what am I missing here?
public void function onLeadsImported(event,interceptData) {
var order = arguments.interceptData.order;
var user = arguments.interceptData.user;
var leads = leadService.getLeadsByOrderAndDate(order.getOrderID(),dateFormat(now(),‘yyyy-mm-dd’));
var subject = “YOLO Marketing - You have new leads”;
var bodyTokens = {
firstName = user.getFirstName(),
lastname = user.getLastName()
};
var mail = mailservice.newMail(to=user.getEmail(),
from=variables.outgoingemail, cc="sales@yolo-marketing.com",
subject=subject,
bodyTokens=bodyTokens);
// generate content for email from template
mail.setBody( renderer.renderView(view=“email_templates/order_newleadsimport”) );
mail.setType(“HTML”);
mail.setUseSSL( getUseSSL() );
mail.setUseSSL( getUseTLS() );
mail.addMailParam(
file=“Leads-#dateFormat(now(),‘mm-dd-yyyy’)#.pdf”,type=“application/pdf”,
content=renderer.renderView(view=“email_templates/leadpdf”,
args={leads=leads})
);
mailService.send( mail );
My guess is that there is an error or something happening in the leadpdf.cfm have you tried just outputting normal non CFML in the view. Like just a hello this is a test, if that fails I think there is something else seriously wrong.
So I ran 2 other tests… Here in this method I just tried to see what was returned and again nothing gets returned.This is ultimately why I think the attachment is not working.
public void function testGetLeadsByOrderAndDate(event,rc,prc) {
var leads = leadService.getLeadsByOrderAndDate(‘402881843ce4677c013ce9a45f510008’,dateFormat(‘2013-02-19 22:46:48’,‘yyyy-mm-dd’));
var pdfContent = renderer.renderView(view=“email_templates/leadpdf”,args={leads=leads});
writeDump(pdfContent);
abort;
}
I also tried to call it from a test handler function
public void function testGetLeadsByOrderAndDate(event,rc,prc) {
var leads = leadService.getLeadsByOrderAndDate(‘402881843ce4677c013ce9a45f510008’,dateFormat(‘2013-02-19 22:46:48’,‘yyyy-mm-dd’));
Well this works and its an ugly a$$ hack but until I figure out what’s going wrong It will have to do. leadsAttachement is the variable name of the cfdocument tag.
var mail = mailservice.newMail(to=user.getEmail(),
from=variables.outgoingemail, cc="sales@yolo-marketing.com",
subject=subject,
bodyTokens=bodyTokens);
include “/views/email_templates/leadpdf.cfm”;
// generate content for email from template
mail.setBody( renderer.renderView(view=“email_templates/order_newleadsimport”) );
mail.setType(“HTML”);
mail.setUseSSL( getUseSSL() );
mail.setUseSSL( getUseTLS() );
mail.addMailParam(
file=“Leads-#dateFormat(now(),‘mm-dd-yyyy’)#.pdf”,type=“application/pdf”,
content=leadsAttachment
);
mailService.send( mail );
Actually Dan, you might be better of doing it like this.
var mail = mailservice.newMail( … );
mail.setBody( renderer.get().renderExternalView(view="/contentbox/email_templates/#template#") );
mailService.send( mail );
And to customize the template, you can even look at tokens here as well.
I know why. The renderer is not supposed to be a singleton. Therefore it is loosing scope. In the docs I write that injecting the renderer is not a good idea. The solutions is to either do a provider of renderer or inject wirebox and request it on demand.