Tag Archives: Email Template

Attach Dynamic Attachment to Salesforce Email Template

Sometimes we need to attach dynamic attachment to a Salesforce email template. So, following are the steps to create dynamic attachments for an email template.

  • Create a Visualforce Page and an apex controller to generate a PDF document.
  • Create a Visualforce Page Component and an apex controller for Visualforce Email Template.

VF Page for PDF(ProposalPDF):

<apex:page controller="ProposalPDFController" applyHtmlTag="false" applyBodyTag="false" showHeader="false" sidebar="false">
        Proposal Name:  <apex:outputText value="{!Opp.Name}" escape="false"/><br/>
        Proposal For:  <apex:outputText value="{!Opp.Account.Name}" escape="false"/><br/>
        Proposal Amount:  <apex:outputText value="{!Opp.Amount}" escape="false"/><br/>

Apex Controller for PDF VF Page(ProposalPDFController):

public class ProposalPDFController {
    public String OpportunityId {
            if(OpportunityId == null && ApexPages.currentPage().getParameters().get('id') != null){
                OpportunityId = ApexPages.currentPage().getParameters().get('id');
            return OpportunityId;
    public Opportunity Opp {
            return [SELECT Id, Name, Account.Name, Amount  FROM Opportunity WHERE Id = :OpportunityId LIMIT 1];

VF Page Component for VF Page Email Template(ProposalAttachment):

<apex:component controller="ProposalAttachmentController" access="global">
    <apex:attribute name="oppId" description="Opportunity Record Id" assignTo="{!opportunityId}" type="Id" />
    <apex:outputText value="{!PagePDFContent}" escape="false" />

Apex Controller for VF Page Component(ProposalAttachmentController):

global class ProposalAttachmentController {
    global String PagePDFContent{ get; set; }
    global String opportunityId{ 
        set {
    public void UpdatePDFContent(String opportunityId) {
        try {
            PageReference pageRef = Page.ProposalPDF;
            pageRef.getParameters().put('id', opportunityId);
            PagePDFContent = pageRef.getContent().toString().replace('<html style="display:none !important;">', '<html>');
        }catch(System.Exception ex){}

Note: The Email Template can be used for Workflow Rule, Process Builder, Approval Process, Flow etc.

Custom Send Email Button on Custom Objects

  • Go to Setup | Create | Objects.
  • Select your Custom Object.
  • Go to the Custom Buttons, Links and Actions section.
  • Click on New Button or Link.
  • Create a New Custom Button.
  • Select the Display Type as Detail Page Button.
  • Select the Behavior as Execute JavaScript.
  • Select the Content Source as OnClick JavaScript.
  • Include below code:

window.location = '/_ui/core/email/author/EmailAuthor?rtype=003&p3_lkid={!CustomObject__c.Id}&retURL=/{!CustomObject__c.Id}&p5={!$User.Email}&p24="{!CustomObject__c.To_Email__c}&template_id=00X90000001FCj4';

Note: If the custom object holds some of the contact details then you would need to use the values from custom object, not the contact object.

Save it. Edit the Page Layout of the Custom Object and drag this button on to the Page Layout under the Custom Button section.

The information shown below are the parameters that can be added in the URL. Fields that are mark with asterisk are always needed in the URL.

Parameter Name Parameter Value
p2_lkid To (can be Contact or Lead Id)
p3_lkid Related To (usually the parent record Id)
p4 CC
p5 BCC
p6 Subject
p23 Email Body
p24 Additional To
Template_Id Salesforce email template Id
retURL Redirection page when cancel button is clicked

Using Custom Controller in Visualforce Email Template

To show some records or render customized content on a visualforce email template, we need to include a custom component in a Visualforce email template that uses the custom controller.

Here is an example of visualforce email template with list of contacts of one account record.

Apex Controller:

public class AccountEmailTemplate
    public Id accountId {get;set;}
    public List<Contact> getContactList()
        List<Contact> conList;
        conList = [SELECT FirstName, LastName, Email, Phone FROM Contact WHERE AccountId =: accountId];
        return conList;

Visualforce Component(ContactList):

<apex:component controller="AccountEmailTemplate" access="global">
    <apex:attribute name="AccId" type="Id" description="Id of the account" assignTo="{!accountId}"/>
    <table border = "2" cellspacing = "5">
            <td>First Name</td>
            <td>Last Name</td>    
        <apex:repeat value="{!ContactList}" var="con">

Visualforce Email Template:

<messaging:emailTemplate subject="List of Contacts" recipientType="User" relatedToType="Account">
    <messaging:htmlEmailBody >
        Below is the list of contacts for account {!relatedTo.Name}.<br/><br/>
        <!--Embedded Visualforce component here -->
        <c:ContactList AccId="{!relatedTo.Id}" /><br/><br/>