Below is my batch which sends emails to contacts based on the accounts passed in the scope. I want to mark the date on the Account on which the email has been sent to its contacts. Is there any way I can get all those contacts for which email has been successfully sent so that I can populate the date on the related Account? I have tried to use Messaging.SendEmailResult but it seems we cannot get contact details with this.

global List<Account> start(Database.BatchableContext BC){  
    List<Account> accountList = Database.query(query);
    return accountList;

global void execute(Database.BatchableContext bc,  List<Account> scope) {
    Set<Id> accountIdSet = new Set<Id>();
    List<Messaging.SingleEmailMessage> messages = new List<Messaging.SingleEmailMessage>();
    for(Account acc : scope){
        List<Contact> contactList = 
            SELECT Id, AccountId, Name 
            FROM Contact
            WHERE AccountId IN : accountIdSet
            for(Contact con : contactList){
                Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
            Messaging.SendEmailResult[] results = Messaging.sendEmail(messages);
            for(Messaging.SendEmailResult res : results){
global void finish(Database.BatchableContext bc) {

Any help would be appreciated. Thanks!

  • 1
    successfully sent means what? not bounced? Messaging.SendEmailResult only returns errors if the SingleEmailMessage was malformed
    – cropredy
    Oct 27, 2022 at 17:20
  • @cropredy Yes exactly "Successfully sent" means the email was not bounced. Oct 27, 2022 at 17:23
  • 1
    you have to solve a different way - see help.salesforce.com/s/…
    – cropredy
    Oct 27, 2022 at 17:29
  • @cropredy Okay I got your point I can send the bounced email to the sender but I have some other requirement where I want to populate the date on the Account if the email to its related contacts has been successfully sent. Oct 27, 2022 at 17:34

1 Answer 1


Keep in mind that the results are in the same order as the inputs, so you can just:

Map<Id, Account> accounts = new Map<Id, Account>();
for(Integer index = 0, size = contactList.size(); index < size; index++) {
  Contact contactRecord = contactList[index];
  Messaging.SendEmailResult result = results[index];
  if(result.isSuccess()) {
      new Account(
  • Thanks one more question I have come through is that Can I update Accounts in finish? Updating accounts in finish is the best way or we can do it in the excute method? Oct 27, 2022 at 17:29
  • 1
    @DeepanshuRajta The execute method is just fine. Also, I'd recommend changing your start method to use Database.getQueryLocator instead. You're limiting yourself to 50,000 accounts with the way you wrote the start method.
    – sfdcfox
    Oct 27, 2022 at 17:41
  • Thanks for helping me out and recommending me the best way. Oct 27, 2022 at 17:45

You must log in to answer this question.

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