Skip to content

Instantly share code, notes, and snippets.

@cwest-consultch
Created February 16, 2024 02:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cwest-consultch/ef0c2feb5340db0fdfda566395224c2d to your computer and use it in GitHub Desktop.
Save cwest-consultch/ef0c2feb5340db0fdfda566395224c2d 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.
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;
}
// Send an email with all of the records created in the last day.
sendNewRecordsEmail(
new String[]{'cwest@consultch.com'},
'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