I have a process using Apex and Visualforce to create a custom email with a pdf attachment and a field to enter body text. It is based off a custom object and the email addresses To, CC, bCC, are all pulled from the custom object or the logged in user's contact. The users have now requested that the body be based on an email template so they can modify it at will. I have read a lot about using SingleEmailMessage with templates and there seem to be some issues. I believe I would need to set the setTreatTargetObjectAsRecipient to false so I can set my own recipients. Basically, I just want to use the subject and body parts of the template and merge fields from my custom object into it. Can anyone give me some tips on how to accomplish this without rewriting my process?

Email extension controller:

public class AffEngpdfExtension 
public ID callersId;
private String transferUrl;

public String recipientEmail { get; set; }
public String ccEmail { get; set; }
public String bccEmail { get; set; }
public String subjectEmail { get; set; }
public String bodyEmail { get; set; }
public String docName { get; set; }

// Constructor
public AffEngpdfExtension(ApexPages.StandardController stdController) {
    stdController.addFields(new List<String>{ 'Name', 'User_Email__c', 'Oversight_Email__c', 'Sales_Rep_Email__c' });
    Affiliate_Consulting_Engagement__c affEngage;
    affEngage = (Affiliate_Consulting_Engagement__c)stdController.getRecord();

    callersId = stdController.getRecord().id;
    this.recipientEmail = affEngage.User_Email__c;
    ccEmail = affEngage.Oversight_Email__c + ';' + affEngage.Sales_Rep_Email__c;
    List<Contact> senderEmail = [SELECT Id, Email FROM Contact WHERE pse__Salesforce_User__c=:UserInfo.getUserId() LIMIT 1];
    bccEmail = senderEmail[0].Email;
    subjectEmail = 'Affiliate Consulting Engagement ' + affEngage.Name + ' - ' + affEngage.Engagement_Code__c;
    docName = affEngage.Name + '-' + affEngage.Engagement_Code__c;
    //Custom code for body would be here using data from the affEngage object ________________________________

public String TransferPage { get; set; }
public PageReference transferTopage() {
    transferUrl = '/apex/' + TransferPage + '?scontrolCaching=1&id=' + callersId;
    PageReference pdfPage = new PageReference(transferUrl);
    System.Debug('transferTopage-transferUrl: ' + transferUrl);
    return pdfPage;

// Email content...

public PageReference emailPdf() {

    if(String.isBlank(this.TransferPage)) {
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 
           'Internal Error: missing TransferPage in pdfExtension'));
        return null; // early out
    if(String.isBlank(this.recipientEmail)) {
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 
           'You must enter a Send To email address !'));
        return null; // early out
    if(String.isBlank(this.subjectEmail)) {
        subjectEmail = TransferPage;
    String tempstr = this.bodyEmail;
    tempstr = tempstr.replaceall('[^\\W\\D]*','');
    if (String.isBlank(tempstr)) {
        bodyEmail = 'Document(s) attached for your review.';
    // PageReference reportPage = ApexPages.currentPage();
    transferUrl = '/apex/' + TransferPage + '?scontrolCaching=1&id=' + callersId;
    PageReference pdfPage = new PageReference(transferUrl);
    Blob reportPdf;
    try {
        reportPdf = pdfPage.getContentAsPDF();
    catch (Exception e) {
        reportPdf = Blob.valueOf(e.getMessage());
    // Create email
    Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
    List<String> addresses = new List<String>();

    if (!String.isBlank(this.recipientEmail)) {
        addresses = this.recipientEmail.split(';');
    } else

    if (!String.isBlank(this.ccEmail)) {
        addresses = this.ccEmail.split(';');
    } else

    if (!String.isBlank(this.bccEmail)) {
        addresses = this.bccEmail.split(';');
    } else


    // Attach PDF to email and send
    Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();
    attachment.setFileName(TransferPage + '_' + docName + '.pdf'); 
    message.setFileAttachments(new Messaging.EmailFileAttachment[]{ attachment });
    Messaging.sendEmail(new Messaging.SingleEmailMessage[]{ message });
    ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO,
       'Email with PDF attachment sent to ' + this.recipientEmail));
    return null;

1 Answer 1


Yes you can use Messaging.renderEmailTemplate to accomplish this. This method will return the merged body.

String body=[Select id,Body from EmailTemplate where:Condition][0].body;
List<Messaging.RenderEmailTemplateBodyResult> renderResults = Messaging.renderEmailTemplate(contactId, oppId, new List<String>{unrendered});

System.debug('Merged Boy is \n'+ renderResults[0].getMergedBody())

Source: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_email_outbound_messaging.htm


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .