You are here:
React to Changes with Apex Triggers
To automate your business with external change events, use Apex triggers.
Codey Outfitters can customize Salesforce to send email or SMS notifications on items that are low on stock or have been updated to an attractive price. Gear and other items that are in high demand can be monitored for low stock and automatically ordered. Before customizing Salesforce, make sure that you’re tracking data changes on the external object that you want to track. To track items that are running low on stock, Codey Outfitters creates an Apex trigger named LowOnStock. Next, the company selects the trigger’s sObject and the change event that publishes changes for the external object Products__x: Products__ChangeEvent.
Here’s an example of a simple rule that sends a notification when an item is low on stock.
trigger LowOnStock on Products__ChangeEvent (after insert) {
// Get the change event’s product ID for added and updated products
Set<Id> productIds = new Set<Id>();
for (Products__ChangeEvent event: Trigger.new) {
if (event.ChangeEventHeader.getChangeType() != 'DELETE') {
String productId = event.ChangeEventHeader.getRecordIds()[0];
productIds.add(productId);
}
}
if (productIds.size() > 0) {
ProductNotifications.notifyOnLowOnStockProductUpdates(productIds);
}
}
The product notifications class queries the external Product objects for the given changed product IDs and LowOnStock threshold value. Looking up the current Product records on the external system for qualifying products is a callout and is scheduled as an Apex future.
public class ProductNotifications {
// Notify subscribers on product updates that are low on stock.
// This method is run asynchronously as it is performing a callout to the external
// system to get the latest product details
@future (callout=true)
public static void notifyOnLowOnStockProductUpdates(Set<Id> productIds) {
// Look up the current stock threshold to filter the products with
Integer productStockThreshold = ...;
List<Products__x> lowOnStockProducts =
getProductsLowOnStock(productIds, productStockThreshold);
// Notify subscribers
notifySubscribers(lowOnStockProducts,
‘These items are running out of stock. Act soon!’);
}
// Get the external Product objects for each Product ID
public static List<Products__x>
getProductsLowOnStock(Set<Id> productIds, Integer productStockThreshold) {
return [SELECT Id, ExternalId, Name__c, ProductId__c, Stock__c, UnitPrice__c
FROM Products__x
WHERE Stock__c < :productStockThreshold AND Stock__c > 0 AND
Id IN :productIds];
}
// Notify subscribers by sending an email or SMS
public static void notifySubscribers(String message, List<Products__x> products) {
...
}
}
You can discover the metadata for change events through the sObject describe API. For example, the sObject describe for Products__ChangeEvent shows the following standard change event fields.
| Field | Type | Description |
|---|---|---|
| Id | String | The change event’s Salesforce ID. This ID isn’t the Salesforce ID of the record that changed, but the event that carries the record’s changes. |
| ReplayId | String | The position of the event notification in the event stream on a channel. |
| ChangeEventHeader | Complex Type | The type of data change event. |
Each change event object defines fields that hold the updated value at the time the record was updated. The OData producer can also include fields that haven’t changed. To see the current values, query the external object using the record ID in the change event header.
The following table shows sample Products__x fields. Event change objects are tailored to their tracked external object. For a change event, not all fields are necessarily present.
| Field | Type | Description |
|---|---|---|
| Id | String | Product record’s Salesforce ID in your org |
| ExternalId | String | Product record’s external ID |
| DisplayUrl | String | URL representing the record in the external system |
| CreatedOn__c | DateTime | When the record was created in the external system |
| UpdatedOn__c | DateTime | When the record was last updated on the external system |
| Name__c | String | Product name in Product__x |
| OrderLimit__c | Integer | Number of items that can be ordered at a time |
| Stock__c | Integer | Number of items in stock |
| UnitPrice__c | Decimal(8,2) | Item’s unit price |
The following fields are change event header complex type fields. To access
ChangeEventHeader fields from Apex, use its getter method. For example, to access the
field ChangeType, use eventObject.ChangeEventHeader.getChangeType().
| Field | Type | Description |
|---|---|---|
| commitUser | String | User who published the event. |
| sequenceNumber | Integer | Change event sequence number. Each change is listed in the order in which it’s received. |
| entityName | String | API name of the external object. |
| changeType | ChangeType enum | Specifies whether a record was updated, created, or deleted. The enum values for external change events are Create, Update, and Delete. |
| changeOrigin | String | Delta link that’s used to request the changes made since the previous or initial change request. The OData producer calculates the delta token while executing the previous change request. |
| transactionKey | String | Unique identifier for the transaction. |
| commitTimestamp | Long | Specifies when the change event notification is published in milliseconds since January 1, 1970. |
| recordIds | Array of type String | Salesforce ID of the external object record that is updated, created, or deleted. To see the current values of the record fields, query the external object using this record ID. This array always has exactly one Salesforce ID. |
| nulledFields | Array of type String | List of field names set to null. |

