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 Commented Apr 7, 2015 at 17:06

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.