Sending html email from APEX using templates

apexapex-email-serviceemailemail-templatesingleemailmessage

When I am doing a test send using the data in the quote object record, I am getting an html formatted email with values.

In the doc: https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_classes_email_outbound_single.htm

It says:

setTargetObjectId(targetObjectId) Required if using a template, optional otherwise. The ID of the contact, lead, or user to which the email will be sent. The ID you specify sets the context and ensures that merge fields in the template contain the correct data.

setWhatId(whatId) If you specify a contact for the targetObjectId field, you can specify an optional whatId as well. This helps to further ensure that merge fields in the template contain the correct data.

Not sure what values should be set for these:

mail.setTargetObjectId(); 

mail.setWhatId();

Merge fields in my classic email template are like: {!Quote.Opportunity_Amount__c}

I am not sure I the SELECT should be like instead:

EmailTemplate et = [SELECT Id, Subject, Description, HtmlValue, DeveloperName, Body FROM EmailTemplate WHERE Name = 'My template name'];

Following is the code snippet I am using:

for (Quote q: Qt){
     EmailTemplate et = [SELECT Id, Subject, Body FROM EmailTemplate WHERE DeveloperName =:emailTemplateName];
                List<string> toAddress = new List<string>();
                toAddress.add(q.Customer_Email__c);
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                    mail.setTemplateId(et.Id);
                    mail.setToAddresses(toAddress);
                    mail.setSubject(et.subject);
                    mail.setHTMLBody(et.Body);
                    mail.setTargetObjectId();
                    mail.setWhatId();
                    mail.setSaveAsActivity(false);
                    mail.setUseSignature(false);
                List<Messaging.SingleEmailMessage> allmsg = new List<Messaging.SingleEmailMessage>();
                allmsg.add(mail);

                try {
                    Messaging.sendEmail(allmsg,false);
                    return;
                } catch (Exception e) {
                    System.debug(e.getMessage());
                }
}

Best Answer

If you are using an email template, want to send an email using that template (and can afford for Salesforce to perform a query to load that template) and have mailmerge in the template, the easiest way to achieve this is to:

  1. Call setTemplateId with the ID of the required email template. Do not separately call setSubject, setHTMLBody or setPlainTextBody; the template will be automatically queried for you and mailmerge will be processed for you. This mailmerge processing won't happen if you set subject/body explicitly.
  2. Call setTargetObjectId passing in the ID of the recipient. Note that this must be a User, Contact, Lead or Person record ID. Also note that if it is not a User or Lead ID then the email send counts against your daily email sending limit.
  3. Call setWhatId passing in the ID of the record referenced in the template's mailmerge.

If at all possible, always try to map a Contact ID to a User ID (in case you have Community Users) before using as the recipient of the email; that way you don't eat into your email daily limits.

Related Topic