0

We have 2 batch classes which run once both related objects are updated. However, everytime they are updated and the corresponding batch jobs are finished we got email notification.

How to limit this email notification so that at the end of the day we will get only one consolidated email for all batch class job finish. Below is the example of one batch class for contact

global class batchContactUpdate implements Database.Batchable<sObject>
{
    public final string query;
    global set<Id> UIds;
    global set<Id> BIds;
    public boolean flag;
    public string status;
    list<Contact> uptlst = new list<Contact>();

    global Database.QueryLocator start(Database.BatchableContext BC)
    {
        if(Test.isRunningTest()){
                return database.getqueryLocator ([select Id,lastname,firstname from Contact limit 100]) ;    
            }
            else{
                return database.getqueryLocator ([select Id,lastname,firstname from Contact]) ; 
            }        

    }

    global void execute(Database.BatchableContext BC, List<Contact> scope)
    {
         for(Contact c : scope)
         {
             if(flag == true)
             c.lastname = 'true';
             else
             c.lastname = 'testfalse';
             uptlst.add(c);
         }
         update uptlst;
    }  
    global void finish(Database.BatchableContext BC)
    {
     messaging.singleEmailMessage mail = new messaging.singleEmailMessage();
     AsyncApexJob a = [SELECT Id,
                             Status,
                             NumberOfErrors,
                             JobItemsProcessed,
                             TotalJobItems,
                             CompletedDate,
                             ExtendedStatus,
                             ApexClass.name,
                             CreatedBy.Email,
                             CreatedBy.Name
                      FROM AsyncApexJob 
                      WHERE Id =:BC.getJobId()];
    mail.ToAddresses = new string[]{ a.CreatedBy.Email,'[email protected]' , '[email protected]'};
   // mail.setReplyTo('');   // <-----------------------------------Set the ReplyTo---
    mail.setSubject('Batch Code Complete -- '+a.ApexClass.name);
    mail.setUseSignature(false);

    string td1='"border:1px solid green; width=200px;"';
    string td2='"width=200px; border:1px solid green; background-color:red; color:white; font-weight:bold;"';
    string tdHead='"border:1px solid green; width=200px; color:white; background-color:green; font-weight:bold;"';
    string ExtendedStatus='';
    if(a.ExtendedStatus!=null)
        ExtendedStatus=a.ExtendedStatus;
    string tdErrors=td1;
    if(a.NumberOfErrors>0)
        tdErrors=td2;
    string htmlBody = '<div style="border:2px solid green; border-radius:15px;"><p>Hi,</p><p><span style="color:brown; font-weight:bolder;">Salesforce</span> completed running <b>Apex Batch Code<>/b>.</p>'
    +'<p>Results:</p>'
    +'<center><table style="border:3px solid green; border-collapse:collapse;">'
    +'<tr><td style='+tdHead+'>Class Name</td><td style='+tdHead+'>'+a.ApexClass.name+'</td></tr>'
    +'<tr><td style='+td1+'>Completed Date</td><td style='+td1+'>'+a.CompletedDate+'</td></tr>'
    +'<tr><td style='+td1+'>Status</td><td style='+td1+'>'+a.Status+'</td></tr>'
    +'<tr><td style='+td1+'>Job Items Processed</td><td style='+td1+'>'+a.JobItemsProcessed+' / '+a.TotalJobItems+'</td></tr>'
    +'<tr><td style='+td1+'>NumberOfErrors</td><td style='+tdErrors+'>'+a.NumberOfErrors+'</td></tr>'
    +'<tr><td style='+td1+'>Extended Status</td><td style='+td1+'>'+ExtendedStatus+'</td></tr>'
    +'<tr><td style='+tdHead+'>Created By</td><td style='+tdHead+'>'+a.CreatedBy.Name+' ('+a.CreatedBy.Email+')</td></tr>'
    +'</table></center>'
    +'<p>Enjoy the <b>results</b>!</p><p><span style="font-family:"Courier New", Courier, monospace; color:green; font-weight:bold; font-size:larger;">Scott</span></p></div>';

    mail.setHtmlBody(htmlBody);
    List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
    mails.add(mail);
    Messaging.sendEmail(mails);

    }
}

3 Answers 3

3

Here's an approach that can extend to all your batch jobs, in addition to the two you noted

  1. Store the batch job result in a custom object called BatchLog__c
  2. Run a scheduled apex job once a day at a predictable time that queries BatchLog__c for all records created for a given datetime range. The apex job generates a consolidated email

This gives you a way to record more information, status results, diagnostics, etc. It also lets you write a daily batch job status email so you don;t have to look in several places within your inbox for all batch jobs done that day

0
0

You can do a check on the time before executing the email notification part, if you are sure usually when this batch job get done. Or you can do a count on the number of batches it run and execute the email notification part.

0

Thanks. however , i have the following batch class for contact

global class batchContactUpdate implements Database.Batchable<sObject>, Database.Stateful, Schedulable
 {
 public final string query;
 global set<Id> UIds;
 global set<Id> BIds;
 public boolean flag;
 public string status;
 public static String CRON_EXP = '0 0 15 * * ?';
 list<Contact> uptlst = new list<Contact>();

 global void execute( SchedulableContext SC )
    {
      // check to see if available slots first, otherwise re-schedule
      batchContactUpdate batch = new batchContactUpdate();
      Database.executeBatch( batch, 1 );
    }

global Database.QueryLocator start(Database.BatchableContext BC)

{
       datetime datePlus30 = System.now().addMinutes( 30 );

    if(Test.isRunningTest()){
            return database.getqueryLocator ([select Id,lastname,firstname from Contact limit 100]) ;    
        }
        else{
            return database.getqueryLocator ([select Id,lastname,firstname from Contact]) ; 
        }        

}

global void execute(Database.BatchableContext BC, List<Contact> scope)
{
     for(Contact c : scope)
     {
         if(flag == true)
         c.lastname = 'true';
         else
         {c.lastname = 'testfalse';}
         c.newpakge__Flag_Test__c = true;
         uptlst.add(c);
     }
     update uptlst;

}  



global void finish(Database.BatchableContext BC)
{
 messaging.singleEmailMessage mail = new messaging.singleEmailMessage();
 AsyncApexJob a = [SELECT Id,
                         Status,
                         NumberOfErrors,
                         JobItemsProcessed,
                         TotalJobItems,
                         CompletedDate,
                         ExtendedStatus,
                         ApexClass.name,
                         CreatedBy.Email,
                         CreatedBy.Name
                  FROM AsyncApexJob 
                  WHERE Id =:BC.getJobId()];
mail.ToAddresses = new string[]{ a.CreatedBy.Email,'[email protected]'};
// mail.setReplyTo('');   // <-----------------------------------Set the ReplyTo---
mail.setSubject('Batch Code Complete -- '+a.ApexClass.name);
mail.setUseSignature(false);

string td1='"border:1px solid green; width=200px;"';
string td2='"width=200px; border:1px solid green; background-color:red; color:white; font-weight:bold;"';
string tdHead='"border:1px solid green; width=200px; color:white; background-color:green; font-weight:bold;"';
string ExtendedStatus='';
if(a.ExtendedStatus!=null)
    ExtendedStatus=a.ExtendedStatus;
string tdErrors=td1;
if(a.NumberOfErrors>0)
    tdErrors=td2;
string htmlBody = '<div style="border:2px solid green; border-radius:15px;"><p>Hi,</p><p><span style="color:brown; font-weight:bolder;">Salesforce</span> completed running <b>Apex Batch Code<>/b>.</p>'
+'<p>Results:</p>'
+'<center><table style="border:3px solid green; border-collapse:collapse;">'
+'<tr><td style='+tdHead+'>Class Name</td><td style='+tdHead+'>'+a.ApexClass.name+'</td></tr>'
+'<tr><td style='+td1+'>Completed Date</td><td style='+td1+'>'+a.CompletedDate+'</td></tr>'
+'<tr><td style='+td1+'>Status</td><td style='+td1+'>'+a.Status+'</td></tr>'
+'<tr><td style='+td1+'>Job Items Processed</td><td style='+td1+'>'+a.JobItemsProcessed+' / '+a.TotalJobItems+'</td></tr>'
+'<tr><td style='+td1+'>NumberOfErrors</td><td style='+tdErrors+'>'+a.NumberOfErrors+'</td></tr>'
+'<tr><td style='+td1+'>Extended Status</td><td style='+td1+'>'+ExtendedStatus+'</td></tr>'
+'<tr><td style='+tdHead+'>Created By</td><td style='+tdHead+'>'+a.CreatedBy.Name+' ('+a.CreatedBy.Email+')</td></tr>'
+'</table></center>'
+'<p>Enjoy the <b>results</b>!</p><p><span style="font-family:"Courier New", Courier, monospace; color:green; font-weight:bold; font-size:larger;">Scott</span></p></div>';

mail.setHtmlBody(htmlBody);
List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
mails.add(mail);
Messaging.sendEmail(mails);

}
} 

but it is not helping me even i have wrote a scheduler class. Any help to start appreciated!!

1
  • Saswat -- this is not an answer, please edit your original question above with the new information
    – cropredy
    Apr 7, 2015 at 17:06

You must log in to answer this question.

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