Platform events are part of Salesforce’s enterprise messaging platform, providing an event-driven messaging architecture to enable apps to communicate inside and outside of Salesforce. An event-driven (or message-driven) software architecture consists of event producers, event consumers, and channels. The architecture is suitable for large distributed systems because it decouples event producers from event consumers, thereby simplifying the communication model in connected systems. One or more subscribers can listen to the same event and carry out actions.
Systems in request-response communication models make a request to a web service or database to obtain information about a certain state. The sender of the request establishes a connection to the service and depends on the availability of the service. Also, the external system pushing data into Salesforce is dependent on the completion of the transaction, i.e. if data is being pushed into an sobject and if there are triggers running on the data being pushed, then the external system must wait until all the business logic in the trigger completes its execution.
In comparison, systems in an event-based model obtain information and can react to it in near real-time when the event occurs. Event producers don’t know the consumers that receive the events. Any number of consumers can receive and react to the same events. Both parties are also not dependent on each other.
The only dependency between producers and consumers is the semantic of the message content.
A platform event is a special kind of Salesforce entity, similar in many ways to an
sObject
. But
- Unlike custom or standard objects, you can’t update or delete event records. All platform event fields are read-only by default.
- You can set read and create permissions for platform events. Grant permissions to users in profiles or in permission sets.
- You can’t restrict access to a particular field. Field-level security permissions don’t apply and the event message contains all fields.
- Because event publishing is equivalent to a DML insert operation, DML limits and other Apex governor limits apply.
Publish Immediately vs Publish After Commit
Platform event messages are published either immediately or after a transaction is committed, depending on the publish behavior you set in the platform event definition.
- Publish Immediately: The event message is published when the publish call executes. Select this option if you want the event message to be published regardless of whether the transaction succeeds. Also choose this option if the publisher and subscribers are independent, and subscribers don't rely on data committed by the publisher. For example, the immediate publishing behavior is suitable for an event used for logging purposes. With this option, a subscriber might receive the event message before data is committed by the publisher transaction. The
allOrNone
header is ignored when publishing through the APIs. Some events can be published even when others fail in the same call.
- Publish After Commit: The event message is published only after a transaction commits successfully. Select this option if subscribers rely on data that the publishing transaction commits. For example, a process publishes an event message and creates a task record. A second process that is subscribed to the event is fired and expects to find the task record. Another reason for choosing this behavior is when you don't want the event message to be published if the transaction fails. The
allOrNone
header value takes effect. If allOrNone
is set to true, no events are published if at least one event fails in the same call.
High-Volume Platform Events
In API version 45.0 and later, your new custom event definitions are high volume by default. High-volume platform events offer better scalability than standard-volume platform events.
High-volume platform events are published asynchronously. After the publishing call returns with a successful result, the publish request is queued in Salesforce. The event message might not be published immediately.
High-volume platform event messages are stored for 72 hours. You can retrieve past event messages when using CometD clients to subscribe to a channel.
To know about high-volume platform event default allocations, check the
documentation.
Publishing Platform Events
- To publish event messages with Process Builder, add a Create a Record action to the appropriate process. Where you'd usually pick an object to create, select the custom platform event.
- To publish event messages with flows, add a Create Records element to the appropriate flow. Where you'd usually pick an object to create, select the custom platform event.
- To publish event messages with Apex, call the
EventBus.publish
method. Each EventBus.publish
method call is considered a DML statement, and DML limits apply. The below code is taken from the documentation to show how to publish platform events with Apex.
List<Low_Ink__e> inkEvents = new List<Low_Ink__e>();
inkEvents.add(new Low_Ink__e(Printer_Model__c='XZO-5', Serial_Number__c='12345', Ink_Percentage__c=0.2));
List<Database.SaveResult> results = EventBus.publish(inkEvents);
for (Database.SaveResult sr : results) {
if (sr.isSuccess()) {
System.debug('Successfully published event.');
} else {
for(Database.Error err : sr.getErrors()) {
System.debug('Error returned: ' + err.getStatusCode() + ' - ' + err.getMessage());
}
}
}
- Publish events with Salesforce APIs such as SOAP API, REST API, or Bulk API. To publish a platform event message using REST API, send a POST request to the following endpoint:
/services/data/v48.0/sobjects/Event_Name__e/
When publishing an event message, the result that the API returns contains information about whether the operation was successful and the errors encountered. If the
success
field is
true
, the event was published for a standard-volume event. For a high-volume event, the publish request is queued in Salesforce and the event message might not be published immediately. If the
success
field is
false
, the event publish operation resulted in errors, which are returned in the
errors
field.
The returned result also contains the
Id
system field. The
Id
field value is not included in the event message delivered to subscribers. It is not used to identify an event message, and is not always unique. Subscribers can use the
ReplayId
system field, which is included in the delivered message, to identify the position of the event in the stream.
Subscribing to Platform Events
const jsforce = require("jsforce");
const dotenv = require("dotenv");
const express = require("express");
const session = require("express-session");
dotenv.config({
path: "./config/config.env"
});
const app = express();
// Configure express-session to store Session Id and Instance URL
app.use(
session({ secret: "keyboard cat", resave: true, saveUninitialized: true })
);
const oauth2 = new jsforce.OAuth2({
loginUrl: process.env.SF_LOGIN_URL,
clientId: process.env.SF_CLIENT_ID,
clientSecret: process.env.SF_CLIENT_SECRET,
redirectUri: process.env.SF_REDIRECT_URI
});
app.get("/oauth2/auth", function(req, res) {
res.redirect(
oauth2.getAuthorizationUrl({ scope: "api id web refresh_token" })
);
});
app.get("/oauth2/callback", function(req, res) {
var conn = new jsforce.Connection({ oauth2: oauth2 });
conn.authorize(req.query.code, function(err, userInfo) {
if (err) {
return console.error(err);
}
console.log(userInfo);
console.log(conn.accessToken, conn.refreshToken, conn.instanceUrl);
req.session.accessToken = conn.accessToken;
req.session.instanceUrl = conn.instanceUrl;
res.redirect("/");
});
});
app.get("/", function(req, res) {
if (!req.session.accessToken || !req.session.instanceUrl) {
res.redirect("/oauth2/auth");
return;
}
// Connect and output query results
const conn = new jsforce.Connection({
accessToken: req.session.accessToken,
instanceUrl: req.session.instanceUrl
});
res.send(req.session.instanceUrl);
subscribeToEvents(conn, res);
});
function subscribeToEvents(conn, res) {
conn.streaming.topic("/event/DemoEvent__e").subscribe(function(message) {
console.log(message);
});
}
const PORT = process.env.PORT || 3000;
app.listen(PORT, console.log(`Server running on ${PORT}`));
field. The
field value, which is populated by the system when the event is delivered to subscribers, refers to the position of the event in the event stream. Replay ID values are not guaranteed to be contiguous for consecutive events. A subscriber can store a replay ID value and use it on resubscription to retrieve events that are within the retention window.
You can replay platform events that were sent in the past 24 hours. You can replay platform events through the API (CometD) but not Apex. The process of replaying platform events is the same as for other Streaming API events. You can use workbench to replay the platform events.
Salesforce provides events with predefined fields, called standard platform events. An example of a standard platform event is
, which monitors OAuth 2.0 authentication activity. Another example is
- a batch retry framework, to understand how to handle such event). You can subscribe to a standard platform event stream using the subscription mechanism that the event supports. Check the
to learn about the allocations available for platform event definitions, publishing and subscribing to platform events, and event delivery in CometD clients. The below table provides information about the default allocation for the high-volume events.