Before Insert Trigger

This before Insert and Update trigger will capture incoming data before it gets committed to the database and allows us to be more transparent and have a starting point on in case of debugging.

The full blog post: https://salesforcepanda.com/capturing-api-request/
To the youtube video: https://youtu.be/48aGuvLjONU

The trigger always needs a starting point. So depending on your use case you might have to build more then one – this is unfortunately not a one size fits all solution.

In our use case we want to capture incoming data for the wishlist object. Some assumptions: Wishlist records gets only created via the endpoint. If not further specified the trigger will always fire, also when you create a wishlist record via the UI. You could put some criteria in like “only when user has profile X” to narrow it down.

Example:

// Define the Profile ID that should trigger the logic
    String allowedProfileId = '00e9Q000002jVBNQA2';
    
    // Get the current user's Profile ID
    String currentUserProfileId = UserInfo.getProfileId();

    // If the user's Profile ID does not match, exit the trigger early
    if (currentUserProfileId != allowedProfileId) {
        return; // Exit the trigger if the Profile ID is not the one we're looking for
    }Code language: JavaScript (javascript)

Here is the trigger:

Trigger

trigger APIRequestWishlist on Wishlist__c (before insert, before update) {
List<API_Request__c> requestLogs = new List<API_Request__c>();
    
String currentUserId = UserInfo.getUserId();

    
    // Handle Insert Case
    if (Trigger.isInsert) {
        for (Wishlist__c wishlist : Trigger.new) {
            API_Request__c log = new API_Request__c();
            log.RequestBody__c = JSON.serialize(wishlist);  // Storing job ad data as JSON
            log.Method__c = 'insert';
            log.sObject__c = 'wishlist';
            log.userId__c = currentUserId;
            requestLogs.add(log);
        }
    }

    // Handle Update Case
    if (Trigger.isUpdate) {
        for (Wishlist__c newWishlist : Trigger.new) {
            Wishlist__c oldWishlist = Trigger.oldMap.get(newWishlist.Id);
            
            // Map to capture the changes.
            Map<String, Map<String, Object>> changes = new Map<String, Map<String, Object>>();
            
            // Get all populated fields from the new record.
            Map<String, Object> newFields = newWishlist.getPopulatedFieldsAsMap();
            
            // Loop through the fields and compare old and new values.
            for (String fieldName : newFields.keySet()) {
                Object newVal = newFields.get(fieldName);
                Object oldVal = oldWishlist.get(fieldName);
                
                // Check if the values are different. This handles nulls gracefully.
                Boolean isChanged = (newVal == null && oldVal != null) ||
                                    (newVal != null && oldVal == null) ||
                                    (newVal != null && oldVal != null && !newVal.equals(oldVal));
                                    
                if (isChanged) {
                    // Record the change for this field.
                    changes.put(fieldName, new Map<String, Object>{
                        'old' => oldVal,
                        'new' => newVal
                    });
                }
            }
            
            // If any changes were detected, log them.
            if (!changes.isEmpty()) {
                API_Request__c logRecord = new API_Request__c();
                logRecord.RequestBody__c = JSON.serialize(newWishlist); // Storing updated job ad data as JSON
                logRecord.ChangedFields__c = JSON.serialize(changes); // Log changed fields
                logRecord.Method__c = 'update'; // Indicate the method
                logRecord.sObject__c = 'wishlist';
                logRecord.UserId__c = currentUserId;
                requestLogs.add(logRecord);
            }
        }
    }

    // Insert the collected request logs if any
    if (!requestLogs.isEmpty()) {
        insert requestLogs;  // Save the request logs
    }
}
Code language: JavaScript (javascript)

Trigger creates a record in our API request object before the wishlist record gets created. We save the content of the call in the requestBody__c field and display it in a nicer structure using a LWC called jsonViewer

Before update – this will check which field has changed and what the value was before and after – saving all these information in a field called ChangedFields__c

Some values are hardcoded like:

  • Method – “insert” or “update”
  • sObject – Wishlist (in my case)

Thats for more transparency and debugging.

Be aware. There will be no recordId of the created wishlist record as we trigger BEFORE insert. You can switch this to after insert but then again run in danger of other processes interferring. 

  • Custom object: API_Request__c
    • Custom fields:
      • ChangedFields__c – Long Text Area(32768)
      • Method__c – Text(255)
      • RequestBody__c – Long Text Area(32768)
      • sObject__c – Text(255)
      • userId__c – Text(255)

Leave a Reply

Your email address will not be published. Required fields are marked *