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
kdaviskdavis 

Count how many times email text has been used with schedule batch

Hey all,

 

So I have a requirement that my client wants to be able to count the number of times a canned email response is used. They are using quick texts for cases and they want to monitor how many times the message field is contained in the text body of an email, for every quick text record. They also want to break it up into three fields, how many emails contain the text in that last 30, 7, and one days. So I wrote up a scheduled class and a batch class to try and handle this and I wanted to get some feedback if I am approaching this the correct way. They also wants to run this every 24 hours. Code posted below.

 

Scheduled Class: 

 

global class emailCountScheduled implements Schedulable{


global void execute(SchedulableContext sc) {

List<QuickText> qt = new List<QuickText> ();
Map<String, QuickText> responseToQT = new Map<String, QuickText> ();
List<String> messages = new List<String> ();
Date dateFilter = Date.Today().addDays(-30);
String dateFilterString = String.valueOf(dateFilter);

qt = [SELECT Id, Message, Total_Use_1_Day__c, Total_Use_30_Days__c, Total_Use_7_Days__c FROM QuickText];

if(!qt.isEmpty()){
for(QuickText q : qt){
if(q.Message != null){
messages.add(q.Message);
responseToQT.put(q.Message, q);
}
}
}

String query = 'SELECT Id, Subject, Description, ActivityDate FROM task WHERE Subject LIKE \'%Email%\' AND ActivityDate > dateFilter';
query = query.replace('dateFilter', dateFilterString);

emailCountBatch b = new emailCountBatch(responseToQT,messages,query);

database.executebatch(b);
}
}

 

Batch class:

 

global class emailCountBatch implements Database.Batchable<sObject> {

global final String query;
global final Map<String, QuickText> responseObjects;
global final List<String> cannedResponses;

global emailCountBatch(Map<String, QuickText> qt, List<String> messages, String q) {

responseObjects = new Map<String, QuickText> ();
cannedResponses = new List<String> ();

responseObjects = qt; cannedResponses = messages; query = q;
}

global Database.QueryLocator start(Database.BatchableContext BC) {
return Database.getQueryLocator(query);
}

global void execute(Database.BatchableContext BC, List<sObject> scope) {
Map<String, List<sObject>> thirtyDays = new Map<String, List<sObject>> ();
Map<String, List<sObject>> sevenDays = new Map<String, List<sObject>> ();
Map<String, List<sObject>> oneDay = new Map<String, List<sObject>> ();

for(sObject s : scope){

String emailBody = String.ValueOf(s.get('Description'));

for(String m : cannedResponses){
if(emailBody.contains(m)){
if(!thirtyDays.containsKey(m)){
thirtyDays.put(m, new List<sObject> ());
}

if(thirtyDays.containsKey(m)){
List<sObject> objectList = thirtyDays.get(m);
objectList.add(s);
thirtyDays.put(m, objectList);
}

//Check if within 7 days
if(Date.ValueOF(s.get('ActivityDate')) > Date.Today().addDays(-7)){
if(!sevenDays.containsKey(m)){
sevenDays.put(m, new List<sObject> ());
}

if(sevenDays.containsKey(m)){
List<sObject> objectList = sevenDays.get(m);
objectList.add(s);
sevenDays.put(m, objectList);
}
}

//Check if within 1 day
if(Date.ValueOF(s.get('ActivityDate')) > Date.Today().addDays(-1)){
if(!oneDay.containsKey(m)){
oneDay.put(m, new List<sObject> ());
}

if(oneDay.containsKey(m)){
List<sObject> objectList = oneDay.get(m);
objectList.add(s);
oneDay.put(m, objectList);
}
}
}
}
}

for(String s : responseObjects.keySet()){
QuickText currentQT = responseObjects.get(s);
currentQT.Total_Use_30_Days__c += thirtyDays.get(s).size();
currentQT.Total_Use_7_Days__c += sevenDays.get(s).size();
currentQT.Total_Use_1_Day__c += oneDay.get(s).size();
}
}

global void finish(Database.BatchableContext BC) {
update responseObjects.values();
}
}

 

I appreciate any feedback. Thanks guys.