Messaging.renderStoredEmailTemplate’s whoId and whatId explanation

apexemailemail-templatevisualforce

I want to send an email in which the body is a custom vf component. My approach was to create an email template:

<messaging:emailTemplate subject="{!relatedTo.Name} - {!relatedTo.Transfer_Amount__c} - {!relatedTo.Beneficiary__r.Name} - {!relatedTo.Company__r.Name}" recipientType="User" relatedToType="Bank_Instruction__c">
    <messaging:HtmlEmailBody >
         <c:BankInstructionDetailsComp bankInstrId="{!relatedTo.Id}" />
    </messaging:HtmlEmailBody>
</messaging:emailTemplate>

Then, I created a record detail button, which calls a visualforce page:

<apex:page controller="SendBankInstrDetailsController" showChat="false" showHeader="false" sidebar="false">
<apex:pageMessages ></apex:pageMessages>
<apex:form id="frm">
    <apex:pageBlock mode="edit">
        <apex:pageBlockSection columns="2" collapsible="true">
            <apex:inputText value="{!email}" label="Email Address" required="true" style="width:350px" styleClass="mail"/>
            <apex:commandButton action="{!sendDetailsByEmail}" value="Send" styleClass="btnSharing"/>
        </apex:pageBlockSection>
    </apex:pageBlock>
</apex:form>

</apex:page>

Controller:

public with sharing class SendBankInstrDetailsController {

public String bankInstructionId {get;set;}
public String email {get;set;}

public SendBankInstrDetailsController() {
    bankInstructionId = System.currentPageReference().getParameters().get('id');
    email = UserInfo.getUserEmail();
}

public PageReference sendDetailsByEmail(){

    try{
        EmailTemplate temp = [SELECT Id FROM EmailTemplate WHERE Name = 'Send View Details'];

        Messaging.SingleEmailMessage mail = Messaging.renderStoredEmailTemplate(temp.Id, null, bankInstructionId);

        mail.setToAddresses(new List<String>{email});

        Messaging.sendEmail(new List<Messaging.SingleEmailMessage>{mail});
    }catch(Exception e){
        System.debug(e.getStackTraceString());
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, e.getMessage()));
    }

    return null;
}

}

What I want to ask is the detailed purpose of the "whoId" and "whatId" parameter in the renderStoredEmailTemplate (I read the documentation on that method and didn't understand the explanation).Is "whatId" the id of the record that is referenced in the relatedTo of the email template? On another hand, I'm passing null to whoId as I don't really get what I should be sending there.
What does the "whoId" stand for? What happens if I pass null as value? If I don't set the "toAdresses" on the email (which is optional, I don't understand why as I never specify the recipients email). Is that what the whoId is for? Does it take the current user email as recipient by default if no toAdresses is set?

Best Answer

WhoId populates the values for recipient merge fields, while WhatId populates the values for the relatedTo merge fields. If you don't specify these values, you don't get merged data. Note that emailing by email address is limited to 5,000 recipients a day. You get unlimited email sends to users, so this would be recommended.

EmailTemplate temp = [SELECT Id FROM EmailTemplate WHERE Name = 'Send View Details'];
Messaging.SingleEmailMessage mail = Messaging.renderStoredEmailTemplate(temp.Id, null, bankInstructionId);
mail.setTargetObjectId(UserInfo.getUserId());
mail.setSaveAsActivity(false); // can't save as activity when emailing users
Messaging.sendEmail(new List<Messaging.SingleEmailMessage>{mail});
Related Topic