0

I have a requirement where I am sending email via batch class. I have created an email template and I want to send data to the merge fields of the template from the code that I am writing. Since the mail will be sent for more than 1 record so I am using a for loop for the Messaging.SingleEmailMessage. The issue is with the HTMLBody component. In the for loop I am observing that the HTMLBody is iterating but the merge fields are not getting captured accordingly. This implies I am receiving email for all the expected records but the email content keeps repeating only for the first record. Please let me know how will I be able to send the email for all the concerned records and the email template will have the data accordingly.

Below is the part of the email code that I have been writing :-

for(Test__c res : finalResourceEmailList){
            htmlBody = htmlBody.replace('{!Test__c.Name}', res.Name);
            htmlBody = htmlBody.replace('{!Test__c.Notification_Date__c}', String.valueof(res.Notification_Date__c));
            htmlBody = htmlBody.replace('{!Test__c.Id}', res.Id);
            
            plainBody = plainBody.replace('{!Test__c.Name}',res.Name);
            plainBody = plainBody.replace('{!Test__c.Notification_Date__c}',String.valueof(res.Notification_Date__c));
            plainBody = plainBody.replace('{!Test__c.Id}', res.Id);
            
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            mail.setTemplateId(et.Id);
            mail.setTargetObjectId(res.OwnerId);
            mail.setSubject(et.Subject);
            mail.setHTMLBody(htmlBody);
            mail.setPlainTextBody(plainBody);
            mail.setSaveAsActivity(false);
            mail.setUseSignature(false);
            allmsg.add(mail);
        }

if(allmsg.size() > 0 ){
            Messaging.SendEmailResult[] results = Messaging.sendEmail(allmsg);
        }

2 Answers 2

1

You're overwriting the values in htmlBody and plainTextBody, so this results in the merge fields being lost after the first record. Further, you already have a template Id, so you shouldn't need to set subject, htmlBody or plainTextBody. Use setWhatId instead.

for(Test__c res : finalResourceEmailList){
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    mail.setTemplateId(et.Id);
    mail.setTargetObjectId(res.OwnerId);
    main.setWhatId(res.Id);
    mail.setSaveAsActivity(false);
    mail.setUseSignature(false);
    allmsg.add(mail);
}
2
  • I got the error "WhatId is not available for sending emails to UserIds"
    – Rivu Indra
    May 18, 2023 at 11:37
  • thanks for your help, I have been able to solve the issue
    – Rivu Indra
    Jun 2, 2023 at 7:25
1

Since you're using a template ID, you don't need to set the body with all the merge fields. Just provide the object via setWhatId. Since you are sending to a User, you will need to use the renderStoredEmailTemplate to avoid the error "WhatId is not available for sending emails to UserIds".

for(Test__c res : finalResourceEmailList){
    Messaging.SingleEmailMessage mail = Messaging.renderStoredEmailTemplate(et.Id, res.OwnerId, res.Id);
    email.setTargetObjectId(res.OwnerId);
    mail.setSaveAsActivity(false);
    mail.setUseSignature(false);
    allmsg.add(mail);
}

I ran into this issue myself recently, and this other answer was tremendously helpful. https://salesforce.stackexchange.com/a/144498

You must log in to answer this question.

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