Batch class finish method email exceeded

batchsingleemailmessage

I am trying to send the email with csv file attachment but it returns email limit is exceeded error, so I tried to send email using trigger there it work properly than why it is not working with batch class this is my code for sending single mail from finish method.

public class BatchUserChange implements Database.Batchable<sObject> {

    public BatchUserChange(){
        System.debug('CONDTRUCTOR');
    }
    
    public Database.QueryLocator start(Database.BatchableContext BC) {

        
        Id userId = UserInfo.getUserId();
        System.debug('userId in start method '+userId);
        return Database.getQueryLocator([SELECT Id, Name, OwnerId FROM Account WHERE OwnerId=:userId]);
    }

    public void execute(Database.BatchableContext BC, List<Account> acc) {
        System.debug('this is EXECUTE method ');
        System.debug('size ---- '+acc.size());
        User newOwner = [SELECT id, name FROM User WHERE name='kaumik gajjar'];
        System.debug('new user owner id :'+newOwner.id);
        for(Account a : acc){
            a.ownerId = newOwner.id;
        }
        System.debug('new list of acc to be update : '+acc);
        update acc;
    }

    public void finish(Database.BatchableContext BC) {
        
 
        List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();            
                List<String> sendTo = new List<String>();
                sendTo.add('[email protected]');
                mail.setToAddresses(sendTo);
                mail.setSenderDisplayName('test Email RR');
                mail.setSubject('test Email RR');
                String plaintxt = 'Hi oppopp';
                mail.setHtmlBody(plaintxt);
                mails.add(mail);
                Messaging.sendEmail(mails);
    }

}

Best Answer

Salesforce applies limits on the number of "external emails" that can be sent via Apex in a given 24 hour period. The limit depends on the type of org, but even with a production org this is just 5000.

I suggest you happened to roll into the next limit period when you tried to adopt trigger use, so hiding that the problem still exists.

The documentation is a little confusing, but what "external email" means in the Apex context is:

  1. Any email address set using setToAddresses, setCcAddresses or setBccAddresses in a message.
  2. A single email message sent to any target object via setTargetObjectId that is not a User record - this includes Leads and Contacts.

You should always try to use a User as the recipient and avoid explicitly setting an email address itself in Apex. Note that you can always try to reverse match an email address to a User record first, via something like:

List<String> emailAddresses = ...;
List<User> users = [SELECT Id, Email, Contact.Email FROM User WHERE User.Email IN :emailAddresses OR User.Contact.Email IN :emailAddresses];

You'll then have to deal with email addresses that couldn't be reverse matched to a User in this way by consuming your daily email limits.

It's worth also considering Daniel Ballinger's answer to this previous Q&A.

Related Topic