[SalesForce] How to send a VF template but override the To address

So we have a trigger that automatically emails a Case Contact when a new Comment is added.

However for some users, we require that email to go to an alternate email address, NOT the one in the Contact's "Email" field.

How would this be done? How do you force Apex to use a particular email address, when also using a Visualforce Template?

thanks

Best Answer

Looking at an example I implemented some time back, when using SingleEmailMessage with a VF template, you must invoke setTargetObjectId(targetObjId) on the object of type SingleEmailMessage. And targetObjId must be a Contact, Lead or User.

  • You can specify additional To recipients by calling setToAddresses(..), passing in a list of email addresses. Note that the SFDC Apex documentation is wrong here - it says Optional. A list of email addresses to which you are sending the email. The maximum number of email addresses allowed is 100. This argument is allowed only when a template is not used. This is not true, you can use with a template.
  • targetObjId is used by the VF template if needed to supply merge fields like Dear {!recipient.firstName}. In effect, as per the doc, targetObjId references the standard controller for Contact, Lead, or User.
  • But, if your VF template doesn't use {!recipient.xxx}, then you can do what I ended up doing which was create a dummy Contact no-reply@mydomain.com with corresponding email address and use that as targetObjId. In your example, the real recipients were unconditionally set using the setToAddresses(..) method call on SingleEmailMessage

Not a perfect solution but to the intended recipient, they will receive the email as if they were the intended recipient. The recipient is already conditioned to ignore the no-reply email address in the To: line

Here is my Util.sendTemplatedEmail method; you can adapt as needed; the caller is responsible for reserving the email message before invoking to avoid governor limits

//  -------------------------------------------------------------------------
//  sendTemplatedEmail
//  -------------------------------------------------------------------------
public static void sendTemplatedEmail(String[] toRecipients, String[] ccRecipients, String templateParmName, ID targetObjId, Id whatId, ID orgWideEmailId, Boolean saveAsActivity ) {
    //  templateId  must be ID of an Email template
    //  targetObjId must be a Contact Id -- also used in merge fields of template recipient.xxxx
    //  whatId      must be an SObject that is used in the merge fields of the template relatedTo.xxxx
    //  fromId      if non null, use current user, otherwise, use this ID (most likely an org wide no reply id)
    //  bcc         not permitted when using templates

    Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
    String templateApiName = EnvironmentVariable.getString(templateParmName);  // Uses custom setting to allow dynamic switching of email template name .. details not included
    Id templateId;  
    try {templateId = [select id, name from EmailTemplate where developername = : templateApiName].id;}
    catch (Exception e) {
        throw new MyException ('[UTIL-06] Unable to locate EmailTemplate using name: ' + templateApiName + 
                                    ' as indicated in Custom Settings ' + templateParmName);
    }


    email.setToAddresses(toRecipients);
    email.setCcAddresses(ccRecipients);
    email.setTargetObjectId(targetObjId);
    email.setWhatId(whatId);
    email.setorgWideEmailAddressId(orgWideEmailId);
    email.setTemplateId(templateId);
    email.setSaveAsActivity(saveAsActivity);            // save email as activity on the targetObjId (i.e. Contact)

    System.debug(LoggingLevel.INFO,'** entered sendTemplatedEmail, to:' + toRecipients + ' cc:' + ccRecipients +  ' templateId:' + templateId + ' targetObjId:' + targetObjId + 
                                    ' whatId:' + whatId + ' orgWideEmailId: ' + orgWideEmailId);
    try {
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
        return;
    }
    catch (EmailException e) {throw new MyException('[UTIL-07] sendTemplatedEmail error. ' + e.getMessage());}

}
Related Topic