0

I have a requirement that, Need to update some bulk contact records and send an email to particular contact when contact gets updated using batch class. To achieve this, i created following class

Global class BatchExampleonContact implements Database.Batchable<sObject>{

    global String query;
    global String field;
    global String value_to_change;

    global BatchExampleonContact(String query, String field, String value_to_change) {

        this.query = query;
        this.field = field;
        this.value_to_change = value_to_change;
    }
    global Database.QueryLocator start(Database.BatchableContext bc) {
        return database.getQueryLocator(query);

    }
    global void execute(Database.BatchableContext bc, List<sObject> scope) {
        List<Contact> con = new List<Contact>();
        for(sObject s: scope) {
            //s.put(field, value_to_change);
            contact c = (contact)s;
            c.Description = value_to_change;
            con.add(c);
        }
        update con;
    } 
    global void finish(Database.BatchableContext BC){
        String[] toAddresses= new String[]{};
        List<contact> cons = Database.query(query);
        for(contact c: cons){
            toAddresses.add(c.Email);
            System.debug('toAddresses'+toAddresses);
        }
        AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed, 
                          TotalJobItems FROM AsyncApexJob WHERE Id = :BC.getJobId()];
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        mail.setToAddresses(toAddresses);
        System.debug(toAddresses);
        mail.setSubject('Batch apex Job Completed ' + a.Status);
        mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems +
                         ' batches with '+ a.NumberOfErrors + ' failures.');
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }

}

While coming to update the record, Its working(Record getting updating) good. But, the email is not going to particular contact if email count is more than 10 emails if we call the class for the first time in the day. Mails are not going if we call class second time in the day and it is giving the following error.

First error: SendEmail failed. First exception on row 0; first error: SINGLE_EMAIL_LIMIT_EXCEEDED, Email limit exceeded: []

As my research in salesforce online i got to known that, We can not send emails to an external users not more than 10. We can send number of emails to internal users(Limit does not apply for internal users) in Developer edition. Of course i am also using same one.

According my class i am thinking so, My class is getting external users not internal users.

If my estimation is correct, How can i overcome my problem, which means how to add contact emails to internal usage and how to send an email according to my scenario?

Please provide solution to my problem. But i need to send the emails using batch class only.

Thanking you.

4
  • Your code is sending email to every possible contact processed by batch and not to a particular contact as per your description. Do you need to send email to every contact processed by batch. Commented Oct 3, 2016 at 12:39
  • @Mukesh Verma, Yeah. I need to send email to every contact processed by batch.
    – KS Kumaar
    Commented Oct 3, 2016 at 12:42
  • As per salesforce Docs 'You can specify up to 100 recipients for the To field and up to 25 recipients for the CC and BCC fields in each SingleEmailMessage'. It seems email limit is getting hit because number of contacts entering batch are more than hundred. Commented Oct 3, 2016 at 12:51
  • @Mukesh Verma, I have only 36 contacts in my org
    – KS Kumaar
    Commented Oct 3, 2016 at 13:00

3 Answers 3

1

As you are sending emails to Contact so you should use setTargetObjectId

global void finish(Database.BatchableContext BC){
        String[] toAddresses= new String[]{};
        List<Messaging.SingleEmailMessage> allMails = new List<Messaging.SingleEmailMessage>();
        List<contact> cons = Database.query(query);
        for(contact c: cons){

        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        mail.setTargetObjectId(c.Id);

        mail.setSubject('Batch apex Job Completed ' + a.Status);
        mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems +
                         ' batches with '+ a.NumberOfErrors + ' failures.');
        allMails.add(mail);  
     }
       Messaging.sendEmail(allMails)

}

This will not count as Internal limit. But if you have 100+ contacts you need to break this code.

13
  • 1
    +1, there is one more limitation that we can send only 1000 email per day in sandbox. same like in production as well. if we send email to user then this limit doesn't count.
    – Ratan Paul
    Commented Oct 3, 2016 at 13:12
  • @Ratan Thanks. I am not sure this limit apply with contact Commented Oct 3, 2016 at 13:15
  • I am getting the same exception. First error: SendEmail failed. First exception on row 4; first error: SINGLE_EMAIL_LIMIT_EXCEEDED, Email limit exceeded: []
    – KS Kumaar
    Commented Oct 3, 2016 at 13:24
  • Please observe my post. I am using Developer Edition....
    – KS Kumaar
    Commented Oct 3, 2016 at 13:28
  • 1
    @KSKumaar in developer org you can send only 15 email per day and in sandbox you can send 1000 emails per day. developer.salesforce.com/docs/atlas.en-us.apexcode.meta/… if the targetobjectId is contact
    – Ratan Paul
    Commented Oct 3, 2016 at 13:30
0

Here is a way by which you can write finish method without hitting the limit:

global void finish(Database.BatchableContext BC){
    AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed, 
                      TotalJobItems FROM AsyncApexJob WHERE Id = :BC.getJobId()];
    List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
    List<contact> cons = Database.query(query);
    for(contact c: cons){
      if(c.Email!=null){
        Messaging.SingleEmailMessage mail =  new Messaging.SingleEmailMessage();      
         List<String> sendTo = new List<String>();
        sendTo.add(c.Email);
        mail.setToAddresses(sendTo);
        mail.setSubject('Batch apex Job Completed ' + a.Status);
        mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems +
                     ' batches with '+ a.NumberOfErrors + ' failures.');        
        mails.add(mail);
        }
    }

    if(mails.size()>0)
    Messaging.sendEmail(mails);
}

This logic creates a list of separate email to every contact and sends them all together.

1
  • This is the error which i am facing again First error: SendEmail failed. First exception on row 4; first error: SINGLE_EMAIL_LIMIT_EXCEEDED, Email limit exceeded: []
    – KS Kumaar
    Commented Oct 3, 2016 at 13:12
0

To bulikfy your single email message.

List<Messaging.SingleEmailMessage> allMails = new List<Messaging.SingleEmailMessage>();
//now do your loop
    .... {

        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        mail.setToAddresses(emailsLeads);
       // mail.setCcAddresses(ccAddresses);
        String subject='GoToMeeting Invitation Details for '+subject;
        String body='test'; 
        mail.setHtmlBody(body); 
        mail.setSubject(subject);
        allMails.add(mail);
 ....
 }
//Finished your loop? Now you have an array of mails to send.
//This uses 1 of your 10 calls to sendEmail that you are allowed
Messaging.sendEmail(allMails);
3
  • Hi @Shravan, In this mail.setToAddresses(emailsLeads), How can i add emailsLeads, I mean using array of String or List of String?
    – KS Kumaar
    Commented Oct 3, 2016 at 12:41
  • @Ks Kumaar, go with your existing logic. String[] toAddresses= new String[]{};
    – S B
    Commented Oct 3, 2016 at 12:50
  • This is the error which i am getting if we follows above one Initial expression is of incorrect type, expected: Initial expression is of incorrect type, expected: Messaging.SingleEmailMessage
    – KS Kumaar
    Commented Oct 3, 2016 at 12:53

You must log in to answer this question.

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