Forked from cwest-consultch/sendNewRecordsEmail.cls
Created
February 16, 2024 02:25
-
-
Save westc/7773f8a4c8a87bac364c1383781bbad2 to your computer and use it in GitHub Desktop.
Apex - Function that sends an email of all of the new records of a given type created after a given datetime.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static boolean sendNewRecordsEmail(String[] toAddresses, String sobjectName, DateTime createdAfter) { | |
String strCreatedAfter = createdAfter.formatGMT('yyyy-MM-dd\'T\'HH:mm:ss\'Z\''); | |
// Get the count of records after the createdAfter date/time. | |
String restSOQL = String.join( | |
new String[]{ | |
'SELECT count(Id) record_count', | |
'FROM ' + sobjectName, | |
'WHERE CreatedDate > ' + strCreatedAfter | |
}, | |
'\n' | |
); | |
String origin = URL.getCurrentRequestUrl().toExternalForm().replaceFirst('^(\\w+\\W+[^/]+)[\\s\\S]*$', '$1'); | |
String restEndpoint = origin + '/services/data/v60.0/query/?q=' + EncodingUtil.urlEncode(restSOQL, 'UTF-8'); | |
HttpRequest req = new HttpRequest(); | |
req.setEndpoint(restEndpoint); | |
req.setMethod('GET'); | |
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId()); | |
req.setHeader('Accept', 'application/json'); | |
req.setHeader('Content-Type', 'application/json'); | |
HttpResponse res = (new Http()).send(req); | |
// Process the response | |
if (res.getStatusCode() != 200) { | |
throw new CalloutException(res.getBody()); | |
} | |
Map<String,Object> topLevel = (Map<String,Object>)JSON.deserializeUntyped(res.getBody()); | |
Object[] records = (Object[])topLevel.get('records'); | |
Map<String,Object> firstRecord = (Map<String,Object>)records[0]; | |
Integer recordCount = (Integer)firstRecord.get('record_count'); | |
// If no records were found return false. | |
if (recordCount == 0) return false; | |
// Get an array of all of the field names. | |
// Use Schema to dynamically retrieve the object's fields | |
Schema.SObjectType objType = Schema.getGlobalDescribe().get(sobjectName); | |
if (objType == null) { | |
throw new QueryException('Object not found: ' + sobjectName); | |
} | |
Map<String, Schema.SObjectField> fields = objType.getDescribe().fields.getMap(); | |
String[] fieldNames = new List<String>(fields.keySet()); | |
String[] fieldLabels = new String[0]; | |
for (String fieldName : fieldNames) { | |
fieldLabels.add(fields.get(fieldName).getDescribe().getLabel()); | |
} | |
// Gets up to 1,000 of the newest records. | |
// NOTE: Only getting up to 1,000 records to try to avoid too big of a | |
// footprint when creating the CSV. | |
String soql = String.join( | |
new String[]{ | |
'SELECT ' + String.join(fieldNames, ','), | |
'FROM ' + sobjectName, | |
'WHERE CreatedDate > ' + strCreatedAfter, | |
'ORDER BY CreatedDate DESC', | |
'LIMIT 1000' | |
}, | |
'\n' | |
); | |
SObject[] realRecords = Database.query(soql); | |
// Create the CSV | |
String fileName = sobjectName + '.csv'; | |
String fileContents = ''; | |
List<String[]> rows = new List<String[]>(); | |
rows.add(fieldLabels); | |
for (SObject record : realRecords) { | |
String[] row = new String[0]; | |
for (String fieldName : fieldNames) { | |
Object value = record.get(fieldName); | |
row.add(value == null ? '' : String.valueOf(value)); | |
} | |
rows.add(row); | |
} | |
Integer colCount = fieldNames.size(); | |
Pattern p = Pattern.compile('[",\\n\\r]'); | |
for (Integer rowsLeft = rows.size(); rowsLeft > 0; rowsLeft--) { | |
String[] rowValues = rows.remove(0); | |
for (Integer colIndex = 0; colIndex < colCount; colIndex++) { | |
rowValues[colIndex] = p.matcher(rowValues[colIndex]).find() | |
? '"' + rowValues[colIndex].replaceAll('"', '""') + '"' | |
: rowValues[colIndex]; | |
} | |
fileContents += String.join(rowValues, ',') + '\n'; | |
} | |
// Create a new email message | |
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); | |
// Set the recipient email address | |
email.setToAddresses(toAddresses); | |
// Set the email subject and body | |
email.setSubject('Newest ' + sobjectName + ' Records'); | |
email.setPlainTextBody(String.join( | |
new String[]{ | |
'This is an automated report from Salesforce informing you that ', | |
String.valueOf(recordCount), | |
' record', | |
recordCount == 1 ? '' : 's', | |
' were created since ', | |
strCreatedAfter, | |
'. The attached CSV is an export of ', | |
recordCount > realRecords.size() ? String.valueOf(realRecords.size()) : 'all', | |
' of these records.' | |
}, | |
'' | |
)); | |
// Attach the file to the email | |
Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment(); | |
attachment.setFileName(fileName); | |
attachment.setBody(Blob.valueOf(fileContents)); | |
email.setFileAttachments(new Messaging.EmailFileAttachment[]{attachment}); | |
Messaging.sendEmail(new Messaging.SingleEmailMessage[]{email}); | |
// Since records were found and an email was sent return true. | |
return true; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Send an email with all of the records created in the last day. | |
sendNewRecordsEmail( | |
new String[]{'[email protected]'}, | |
'CHC_Callout__c', | |
DateTime.now().addDays(-1) | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment