function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Soundar Rajan PonpandiSoundar Rajan Ponpandi 

Too Many Email Invocations: 11 in batch class

HI,

I am facing Too manu email Invocations in batch calss. Can you please guide me where i did a mistake.
 
global class GD_LeadEscalation implements Database.Batchable<sObject>,Database.Stateful {
    
    global final String escalationQuery = 'Select Id,ownerId,Name,GD_Assigned_To_Email__c,GD_Lead_Status__c,GD_Escalated__c,GD_Stop_Escalation__c'
        + ' from GD_Lead__c where GD_Stop_Escalation__c = false and (GD_Lead_Status__c != \'Converted\' OR GD_Lead_Status__c != \'Unqualified\')';
   
    contact con = [select id, Email from contact where email <> null limit 1];
    EmailTemplate template = [select id from EmailTemplate where DeveloperName='GD_Lead_Escalation_Template' limit 1];
    boolean lev1 = false;boolean lev2 = false;boolean lev3 = false;
    list<GD_Lead__c> LeadEscList = new List<GD_Lead__c>();
    
    global Database.QueryLocator start(Database.BatchableContext BC){
        return Database.getQueryLocator(escalationQuery); 
    }
    
    global void execute(Database.BatchableContext BC,List<GD_Lead__c> scope){
        for(GD_Lead_Escalation_Setup__mdt monitor : [select id,GD_Escalation_Emails__c,GD_Escalation_Days__c,GD_Escalation_Days1__c,GD_Level_Of_Escalation__c from GD_Lead_Escalation_Setup__mdt]){
            if(monitor.GD_Level_Of_Escalation__c == 'Level 1'){
                for(GD_Lead__c leadRecord : scope){
                    if(leadRecord.GD_Escalated__c == Decimal.valueOf(monitor.GD_Escalation_Days__c)){
                        leadRecord.GD_Escalation_Level__c = 'Level 1';
                        leadRecord.GD_EscalatedFlag__c = true;
                        lev1 = true;
                        LeadEscList.add(leadRecord);
                    }
                }
            }
            
            if(monitor.GD_Level_Of_Escalation__c == 'Level 2'){
                for(GD_Lead__c leadRecord : scope){
                    if(leadRecord.GD_Escalated__c == Decimal.valueOf(monitor.GD_Escalation_Days__c)){
                        leadRecord.GD_Escalation_Level__c = 'Level 2';
                        lev2 = true;
                        LeadEscList.add(leadRecord);
                    }
                }
            }
            
            if(monitor.GD_Level_Of_Escalation__c == 'Level 3'){
                for(GD_Lead__c leadRecord : scope){
                    if(leadRecord.GD_Escalated__c == Decimal.valueOf(monitor.GD_Escalation_Days__c)){
                        leadRecord.GD_Escalation_Level__c = 'Level 3';
                        lev3 = true;
                        LeadEscList.add(leadRecord);
                    }
                }
            }
        }
        system.debug('LeadEscList ' + LeadEscList.size());
        if(LeadEscList.size() > 0 ){update LeadEscList;}
    } 
    
    global void finish(Database.BatchableContext BC){   
        
        list<string> cCEmails_lev1 = new list<string>();
        list<string> cCEmails_lev2 = new list<string>();
        list<string> cCEmails_lev3 = new list<string>();
        
        EmailTemplate template = [select id from EmailTemplate where DeveloperName='GD_Lead_Escalation_Template' limit 1];       
        for(GD_Lead__c leadRecord : LeadEscList){
            List<Messaging.SingleEmailMessage> lstMsgs = new List<Messaging.SingleEmailMessage>();
            Messaging.SingleEmailMessage msg = new Messaging.SingleEmailMessage();
           
            for(user u: [select id,name, manager.email, manager.GD_No_Escalation__c, manager.manager.email, manager.manager.GD_No_Escalation__c, manager.manager.manager.email, manager.manager.manager.GD_No_Escalation__c from user where id=: leadRecord.OwnerId]){
                if(lev1 = true){
                    if(u.manager.email != null && u.manager.email != '' && u.manager.GD_No_Escalation__c == false /*&& u!=null && !u.isEmpty()*/){
                        string mngrEmail_1 = u.manager.email;
                        cCEmails_lev1.add(mngrEmail_1);
                    }
                }
                if(lev2 = true){
                    if(u.manager.manager.email != null && u.manager.manager.email != '' && u.manager.manager.GD_No_Escalation__c == false ){
                        string mngrEmail_1 = u.manager.email;
                        string mngrEmail_2 = u.manager.manager.email;
                        cCEmails_lev2.add(mngrEmail_1);
                        cCEmails_lev2.add(mngrEmail_2);
                        
                    }
                }
                
                if(lev3 = true){
                    if(u.manager.manager.manager.email != null && u.manager.manager.manager.email != '' && u.manager.manager.manager.GD_No_Escalation__c == false ){
                        string mngrEmail_1 = u.manager.email;
                        string mngrEmail_2 = u.manager.manager.email;
                        string mngrEmail_3 = u.manager.manager.manager.email;
                        cCEmails_lev3.add(mngrEmail_1);
                        cCEmails_lev3.add(mngrEmail_2);
                        cCEmails_lev3.add(mngrEmail_3);
                        
                    }
                }
                
            }
            msg.setTemplateId(template.id);
            msg.setWhatId(leadRecord.id);
            msg.setTargetObjectId(con.id); 
            msg.setSaveAsActivity(false);
            String[] repEamail = new String[] {leadRecord.GD_Assigned_To_Email__c};
            msg.setToAddresses(repEamail);
            if(lev1 = true){msg.setCcAddresses(cCEmails_lev1);}
            if(lev2 = true){msg.setCcAddresses(cCEmails_lev2);}
            if(lev3 = true){msg.setCcAddresses(cCEmails_lev3);}
            lstMsgs.add(msg);
            Savepoint sp = Database.setSavepoint();
            Messaging.sendEmail(lstMsgs);
            Database.rollback(sp);
            List<Messaging.SingleEmailMessage> lstMsgsToSend = new List<Messaging.SingleEmailMessage>();
            for (Messaging.SingleEmailMessage email : lstMsgs) {
                Messaging.SingleEmailMessage emailToSend = new Messaging.SingleEmailMessage();
                emailToSend.setToAddresses(email.getToAddresses());
                emailToSend.setCcAddresses(email.getccAddresses());
                emailToSend.setPlainTextBody(email.getPlainTextBody());
                emailToSend.setHTMLBody(email.getHTMLBody());
                emailToSend.setSubject(email.getSubject());
                lstMsgsToSend.add(emailToSend);
            }
            Messaging.sendEmail(lstMsgsToSend);
        }
    }
}

Thanks & Regards,
Soundar.
Best Answer chosen by Soundar Rajan Ponpandi
David Zhu 🔥David Zhu 🔥
You still have three places calling sendEmail() method in loops.

for(GD_Lead__c leadRecord : leadList_1){
...................
   Savepoint sp = Database.setSavepoint();
   Messaging.sendEmail(lstMsgs);
   Database.rollback(sp);
}

for(GD_Lead__c leadRecord : leadList_2){
...................
   Savepoint sp = Database.setSavepoint();
   Messaging.sendEmail(lstMsgs);
   Database.rollback(sp);
}

for(GD_Lead__c leadRecord : leadList_3){
...................
   Savepoint sp = Database.setSavepoint();
   Messaging.sendEmail(lstMsgs);
   Database.rollback(sp);
}
 

All Answers

David Zhu 🔥David Zhu 🔥
Salesforce has limit for number of times the sendEmail() method can be invoked from Apex in a transaction.  You can only use sendEmail() method 10 times.

In the code you provide, the sendEmail() method is in the loop. This is not the best practice. You may need to move that piece out of the loop.

for(GD_Lead__c leadRecord : LeadEscList){
     .......
    Messaging.sendEmail(lstMsgsToSend);
}
Soundar Rajan PonpandiSoundar Rajan Ponpandi
Hi David,

Thanks for your quick response, Yes I agree I was sending a mail inside of the loop. So it's showing an error, Here i have changed my coding as well. Now this sendEmial() method is in out side of the for loop still i am getting the same error.

I have 43 records to sending an email, so it's crossing 10 times. 

How can i handle this esception ?
 
global class GD_LeadEscalation implements Database.Batchable<sObject>,Database.Stateful {
    
    list<GD_Lead__c> leadList_1 = new list<GD_Lead__c>();
    list<GD_Lead__c> leadList_2 = new list<GD_Lead__c>();
    list<GD_Lead__c> leadList_3 = new list<GD_Lead__c>();
    string level_1;
    string level_2;
    string level_3;
    EmailTemplate template = [select id,body from EmailTemplate where DeveloperName='GD_Lead_Escalation_Template' limit 1];
    contact con = [select id, Email from contact where email <> null limit 1];
    global final String leadEscalation = 'Select Id,ownerId,Name,GD_Assigned_To_Email__c,GD_Lead_Status__c,GD_Escalated__c,GD_Stop_Escalation__c, GD_EscalatedFlag__c'
        + ' from GD_Lead__c where GD_Stop_Escalation__c = false and (GD_Lead_Status__c != \'Converted\' OR GD_Lead_Status__c != \'Unqualified\')';
    
    global Database.QueryLocator start(Database.BatchableContext BC){
        return Database.getQueryLocator(leadEscalation); 
    }
    
    global void execute(Database.BatchableContext BC,List<GD_Lead__c> scope){
        
        for(GD_Lead_Escalation_Setup__mdt monitor : [select id,GD_Escalation_Emails__c,GD_Escalation_Days__c,GD_Escalation_Days1__c,GD_Level_Of_Escalation__c from GD_Lead_Escalation_Setup__mdt]){
            if(monitor.GD_Level_Of_Escalation__c == 'Level 1'){
                level_1 = monitor.GD_Escalation_Days__c;
            }
            if(monitor.GD_Level_Of_Escalation__c == 'Level 2'){
                level_2 = monitor.GD_Escalation_Days__c;
            }
            if(monitor.GD_Level_Of_Escalation__c == 'Level 3'){
                level_3 = monitor.GD_Escalation_Days__c;
            }
        }
        
        for(GD_Lead__c leadRecord : scope){
            if(leadRecord.GD_Escalated__c == decimal.valueOf(level_1) && leadRecord.GD_Stop_Escalation__c == false && leadRecord.GD_Lead_Status__c != 'Converted'){
                system.debug('Level 1 ****' + level_1);
                leadRecord.GD_Escalation_Level__c = 'Level 1';
                leadRecord.GD_EscalatedFlag__c = true;
                leadList_1.add(leadRecord);
            }
            if(leadRecord.GD_EscalatedFlag__c == true && leadRecord.GD_Escalated__c == decimal.valueOf(level_2) && leadRecord.GD_Stop_Escalation__c == false && leadRecord.GD_Lead_Status__c != 'Converted'){
                system.debug('Level 2 ****' + level_2);
                leadRecord.GD_Escalation_Level__c = 'Level 2';
                leadList_2.add(leadRecord);
            }
            if(leadRecord.GD_EscalatedFlag__c == true && leadRecord.GD_Escalated__c == decimal.valueOf(level_3) && leadRecord.GD_Stop_Escalation__c == false && leadRecord.GD_Lead_Status__c != 'Converted'){
                system.debug('Level 3 ****' + level_3);
                leadRecord.GD_Escalation_Level__c = 'Level 3';
                leadList_3.add(leadRecord);
            }
        }
        if(leadList_1.size() > 0){update leadList_1;}
        if(leadList_2.size() > 0){update leadList_2;}
        if(leadList_3.size() > 0){update leadList_3;}
    }
    
    global void finish(Database.BatchableContext BC){ 
        List<Messaging.SingleEmailMessage> lstMsgs = new List<Messaging.SingleEmailMessage>();
        for(GD_Lead__c leadRecord : leadList_1){
            list<string> cCEmails_lev1 = new list<string>();
            for(user u: [select id,name, manager.email, manager.GD_No_Escalation__c, manager.manager.email, manager.manager.GD_No_Escalation__c, manager.manager.manager.email, manager.manager.manager.GD_No_Escalation__c from user where id=: leadRecord.OwnerId]){
                if(u.manager.email != null && u.manager.email != '' && u.manager.GD_No_Escalation__c == false){
                    string mngrEmail_1 = u.manager.email;
                    cCEmails_lev1.add(mngrEmail_1);
                }
            }
           Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
           
            message.setTemplateId(template.id);
            message.setWhatId(leadRecord.id);
            message.setTargetObjectId(con.id); 
            message.setSaveAsActivity(false);
            String[] repEamail = new String[] {leadRecord.GD_Assigned_To_Email__c};
            message.setToAddresses(repEamail);
            message.setCcAddresses(cCEmails_lev1);
            lstMsgs.add(message);
            Savepoint sp = Database.setSavepoint();
            Messaging.sendEmail(lstMsgs);
            Database.rollback(sp);
        }
        
        //Level 2
        for(GD_Lead__c leadRecord : leadList_2){
            list<string> cCEmails_lev2 = new list<string>();
            for(user u: [select id,name, manager.email, manager.GD_No_Escalation__c, manager.manager.email, manager.manager.GD_No_Escalation__c, manager.manager.manager.email, manager.manager.manager.GD_No_Escalation__c from user where id=: leadRecord.OwnerId]){
                if(u.manager.email != null && u.manager.email != '' && u.manager.GD_No_Escalation__c == false){
                    string mngrEmail_1 = u.manager.email;
                    cCEmails_lev2.add(mngrEmail_1);
                }
                if(u.manager.manager.email != null && u.manager.manager.email != '' && u.manager.manager.GD_No_Escalation__c == false){
                    string mngrEmail_2 = u.manager.manager.email;
                    cCEmails_lev2.add(mngrEmail_2);
                }
            }
           Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
           
            message.setTemplateId(template.id);
            message.setWhatId(leadRecord.id);
            message.setTargetObjectId(con.id); 
            message.setSaveAsActivity(false);
            String[] repEamail = new String[] {leadRecord.GD_Assigned_To_Email__c};
            message.setToAddresses(repEamail);
            message.setCcAddresses(cCEmails_lev2);
            lstMsgs.add(message);
            Savepoint sp = Database.setSavepoint();
            Messaging.sendEmail(lstMsgs);
            Database.rollback(sp);
        }
        
        //Level 2
        for(GD_Lead__c leadRecord : leadList_3){
            list<string> cCEmails_lev3 = new list<string>();
            for(user u: [select id,name, manager.email, manager.GD_No_Escalation__c, manager.manager.email, manager.manager.GD_No_Escalation__c, manager.manager.manager.email, manager.manager.manager.GD_No_Escalation__c from user where id=: leadRecord.OwnerId]){
                if(u.manager.email != null && u.manager.email != '' && u.manager.GD_No_Escalation__c == false){
                    string mngrEmail_1 = u.manager.email;
                    cCEmails_lev3.add(mngrEmail_1);
                }
                if(u.manager.manager.email != null && u.manager.manager.email != '' && u.manager.manager.GD_No_Escalation__c == false){
                    string mngrEmail_2 = u.manager.manager.email;
                    cCEmails_lev3.add(mngrEmail_2);
                }
                if(u.manager.manager.manager.email != null && u.manager.manager.manager.email != '' && u.manager.manager.manager.GD_No_Escalation__c == false){
                    string mngrEmail_3 = u.manager.manager.manager.email;
                    cCEmails_lev3.add(mngrEmail_3);
                }
            }
            Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
            message.setTemplateId(template.id);
            message.setWhatId(leadRecord.id);
            message.setTargetObjectId(con.id); 
            message.setSaveAsActivity(false);
            String[] repEamail = new String[] {leadRecord.GD_Assigned_To_Email__c};
            message.setToAddresses(repEamail);
            message.setCcAddresses(cCEmails_lev3);
            lstMsgs.add(message);
            Savepoint sp = Database.setSavepoint();
            Messaging.sendEmail(lstMsgs);
            Database.rollback(sp);
        }
        
        List<Messaging.SingleEmailMessage> lstMsgsToSend = new List<Messaging.SingleEmailMessage>();
        for (Messaging.SingleEmailMessage email : lstMsgs) {
            Messaging.SingleEmailMessage emailToSend = new Messaging.SingleEmailMessage();
            emailToSend.setToAddresses(email.getToAddresses());
            emailToSend.setCcAddresses(email.getccAddresses());
            emailToSend.setPlainTextBody(email.getPlainTextBody());
            emailToSend.setHTMLBody(email.getHTMLBody());
            emailToSend.setSubject(email.getSubject());
            lstMsgsToSend.add(emailToSend);
        }
        Messaging.sendEmail(lstMsgsToSend);        
    }
}

Thansk and Regards,
Soundar.
David Zhu 🔥David Zhu 🔥
You still have three places calling sendEmail() method in loops.

for(GD_Lead__c leadRecord : leadList_1){
...................
   Savepoint sp = Database.setSavepoint();
   Messaging.sendEmail(lstMsgs);
   Database.rollback(sp);
}

for(GD_Lead__c leadRecord : leadList_2){
...................
   Savepoint sp = Database.setSavepoint();
   Messaging.sendEmail(lstMsgs);
   Database.rollback(sp);
}

for(GD_Lead__c leadRecord : leadList_3){
...................
   Savepoint sp = Database.setSavepoint();
   Messaging.sendEmail(lstMsgs);
   Database.rollback(sp);
}
 
This was selected as the best answer