Click here to Skip to main content
15,170,651 members
Articles / DevOps
Tip/Trick
Posted 17 Sep 2016

Stats

20.3K views
2 bookmarked

How to Attach a Dynamic PDF to a Salesforce Messaging Email Template

Rate me:
Please Sign up or sign in to vote.
4.00/5 (1 vote)
23 Sep 2016CPOL2 min read
This tip describes how to attach a dynamic PDF to a Salesforce messaging email template.

Introduction

While it is well known how to send dynamic email attachments using APEX in Salesforce, what is not well known is how to send dynamic email attachments using an email template (i.e., messaging:emailTemplate) for use in workflow rules and email alerts. This tip describes how to attach dynamic PDFs to a Salesforce messaging email template.

How It Works

This endeavor requires several different pieces in order to work:

  • A pdf page (e.g. Invoice)
  • A class for your PDF page (e.g. InvoiceController)
  • A component to be referenced by the email template (e.g. IncludeAttachment)
  • A class for the referenced component (e.g. IncludeAttachmentController)
  • An email template containing the messaging:emailTemplate structure (e.g. Customer Invoice Email)

First, you want to create your pdf page. Here is a simple example; call this page Invoice:

<apex:page controller="InvoiceController" applyHtmlTag="false" 
applyBodyTag="false" showHeader="false" sidebar="false">
<html>
<span>Here is some dynamic PDF data:  <apex:outputText 
value="{!ContactName}" escape="false"/></span>
</html>
</apex:page>

Here is the controller behind this PDF page. Call this controller InvoiceController:

public class InvoiceController {

    public String ContactID {
        get{
            if(ContactID == null && 
            ApexPages.currentPage().getParameters().get('contactId') != null){
                ContactID = ApexPages.currentPage().getParameters().get('contactId');
            }
            
            return ContactID;
        }
        set;
    }

    public String ContactName {
        get{
            return [SELECT Name FROM Contact WHERE ID = :ContactID LIMIT 1].Name;
        }
        set;
    }
}

Next, you want to create a component (VisualForce or Lightening) that will be referenced by the email template. Call this component IncludeAttachments:

<apex:component controller="IncludeAttachmentsController" access="global">
    <apex:attribute name="contactId"
        description="Contact Id"
        assignTo="{!contactObjectId}"
        type="Id" />

    <apex:outputText value="{!PageContents}" escape="false" />
</apex:component>

Now, we will need to create a controller called IncludeAttachmentsController:

global class IncludeAttachmentsController {

/* Variables and Constants */

global String PageContents{ get; set; }
global String contactObjectId{ get; set {
    UpdateContents(value);
} }

public void UpdateContents(String contactObjectID) 
{
    try {
        PageReference pageRef = Page.Invoice;
        pageRef.getParameters().put('contactId', contactObjectID);
    
        PageContents = pageRef.getContent().toString().replace
        ('<html style="display:none !important;">', '<html>');
    } catch(exception ex) { 
        PageContents = 'An error has occurred while trying 
        to generate this invoice.  Please contact customer service.';
    }
}
}

Finally, we can create the email template itself; call this Customer Invoice Email:

<messaging:emailTemplate subject="Invoice Attached" recipientType="Contact" 
 relatedToType="Contact" replyTo="your@company.com">
    <messaging:attachment renderAs="PDF" filename="Invoice.pdf">
        <c:IncludeAttachments contactId="{!relatedTo.Id}"/>
    </messaging:attachment>
    <messaging:htmlEmailBody >
    <html xmlns="http://www.w3.org/1999/xhtml">
        Please find your invoice attached.
    </html>
</messaging:emailTemplate>

Points of Interest

Notice the following line in your email template:

<c:IncludeAttachments contactId="{!relatedTo.Id}"/>

This line is what calls your component with the contactId parameter. The component then calls its class, which passes the ContactId parameter to the invoice controller (i.e. InvoiceController). Notice how there is no renderAs="PDF" on the Invoice page; that is because you want this page to render as a string into the IncludeAttachmentsController. The renderAs="PDF" attribute is located on the messaging:attachment in the email template.

NOTE:  If you experience an error, as in the entire email does not send in production but sends during testing, it could be that you are referencing external sites.  For example, this will cause complete failure:  <img src="https://www.somesite.com/someimage.png" />

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Beavis Killer
Unknown
No Biography provided

Comments and Discussions

 
QuestionPDF error when sent through email alert Pin
Member 1461637417-Oct-19 10:10
MemberMember 1461637417-Oct-19 10:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.