Salesforce and MuleSoft announced support for Pub/Sub API. Here is how to get started!
As one of the most widely used CRM solutions on the market, Salesforce plays a central role in the most critical business processes for many companies. To fully automate and optimise these business processes, companies need to integrate Salesforce CRM with other applications within their organisation.
This article discusses Salesforce’s Event Driven integration solutions and in particular the new Salesforce Pub/Sub API.
Event-driven architecture: A stronger way to connect systems
With event-driven architectures (EDA), events are the most important aspect of your system rather than the services that make up the system.
Here are just a few uses cases that can benefit from using events based solution:
- Property onboarding: a Property Management company onboarding a new Property development in Salesforce, following the Lead and then Opportunity process. The sales manager Mark the Opportunity status as Closed Won. In the back end multiple systems are involved, eg: Property is Created in the Asset Management systems, allowing asset and many more details to be added later, Property accounts are created into the Financial system to allow payment to be made from tenants.
- Order fulfilment: a customer orders his favourite book with a few clicks. Behind the scenes, multiple systems perform several operations: order is created, payment processed, delivery scheduled, and an email sent confirming the order and details.
- Data synchronisation: a company wants to keep its customer data synchronised within its Reporting systems, so all changes to the customers in Salesforce must be propagated to the Data Warehouse system
Types of Events supported by Salesforce
Technically there are 5 types of event notification approaches supported by Salesforce:
Push Topic
Push Topic notifications are events sent by Salesforce when the record changes. They are based on a SOQL query that defines how the event will be produced. Records can be tracked when they are created, updated, deleted or undeleted.
Generic Event
Generic events are custom notifications Salesforce can produce using an arbitrary string as the payload and are not tied to Salesforce data changes.
Platform Event
Platform events are also a custom notification, but here you can define a custom schema specifying the fields and data types to be sent as part of the notification.
Change Data Capture Event
Change Data Capture events are triggered when a record changes in Salesforce. You just need to configure which Object you would like to receive notifications. Records can be tracked when they are created, updated, deleted or undeleted.
Real-Time Event
In addition to this, Salesforce has an out of the box Real-Time Event to help monitoring and detecting standard events in Salesforce in near real-time. These would include event data for auditing or reporting purposes.
Of course any of these above approaches has pros and cons, see the table below for a quick comparison:
What the New Pub/Sub API brings?
In order to implement event-driven integrations today, engineers have a few different options:
- Bulk API, SOAP API or REST API: allows developers to publish Platform Events
- Streaming API, allows developers to subscribe to any Change Data Capture event, Platform Event, or Real-Time Event Monitoring event.
With the new Pub/Sub API, all these functionalities are consolidated into one comprehensive API. The Pub/Sub API allows users to publish events, subscribe to events, request schema, and request topic information all within one API. It eradicates the need for building out a custom CometD Streaming API client.
Pub/Sub API has been in a customer pilot since Fall 2021 and starting from July 6, 2022 it is now Generally Available.
We’ve also started building products that use Pub/Sub API, like our Makepositive MuleSoft accelerators for Salesforce Commerce Cloud and Salesforce Service Cloud.
How to Publish and Subscribe Salesforce Platform Events with Pub/Sub API and MuleSoft
- Login to Salesforce (you can use any Developer org)
Platform Event Creation in Salesforce
- Click on gear icon top right and then select setup option
- Search platform event in quick find search and click on New Platform Event
- Provide Label name and click on save
- Create any custom fields required in Custom Fields & Relationships, see a sample below
Optional – Enqueue Events from Salesforce as per Object changes, by using a Flow
- Click on gear icon top right and then select setup option
- Search and select flows (under process automation) in quick find search
- Click on New flow and select an option as below, then click Create
- Configure the Event trigger as required selecting the source Object and the trigger action
- The trigger flow will be created in flow builder as per default
- Click on + button and click, select create records, set the desired mapping and click done once completed
- After that provide the flow label name and then save, click on activate button to activate the flow
Anypoint Studio MuleSoft Project
- Open Anypoint Studio and create a new Mule Project
- Add the new Salesforce Pub/Sub Connector, via Drag and Drop or adding the below to the POM.xml
<dependency>
<groupId>com.mulesoft.connectors</groupId>
<artifactId>mule4-salesforce-pubsub-connector</artifactId>
<version>1.0.1</version>
<classifier>mule-plugin</classifier>
</dependency>
- Create a new PubSub Connector configuration:
- As per Salesforce’s Basic Auth connection configuration, we need to provide Salesforce username, password and security token to test the connection
- In order to get the Token, click on Salesforce User Setting from Top Right Icon and then on Reset My Security Token to get a fresh token
- See a Mule Config sample below using Basic Auth
- As per Salesforce’s Basic Auth connection configuration, we need to provide Salesforce username, password and security token to test the connection
<salesforce-pub-sub:pubsub-config name=“Salesforce_PubSub_Config” doc:name=“Salesforce PubSub Config”>
<salesforce-pub-sub:basic-connection username=“${sfdc.username}” password=“${sfdc.password}” securityToken=“${sfdc.token}” />
</salesforce-pub-sub:pubsub-config>
- Below is the Full Mule Config XML used for the POC
<?xml version=“1.0" encoding=“UTF-8”?>
<mule xmlns:ee=“http://www.mulesoft.org/schema/mule/ee/core” xmlns:salesforce-pub-sub=“http://www.mulesoft.org/schema/mule/salesforce-pub-sub”
xmlns:http=“http://www.mulesoft.org/schema/mule/http”
xmlns=“http://www.mulesoft.org/schema/mule/core” xmlns:doc=“http://www.mulesoft.org/schema/mule/documentation” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=“http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/salesforce-pub-sub http://www.mulesoft.org/schema/mule/salesforce-pub-sub/current/mule-salesforce-pub-sub.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd”>
<salesforce-pub-sub:pubsub-config name=“Salesforce_PubSub_Config” doc:name=“Salesforce PubSub Config” doc:id=“17a9349d-3567-4024-9678-30933f3cd470” >
<salesforce-pub-sub:basic-connection username=“${sfdc.username}” password=“${sfdc.password}” securityToken=“${sfdc.token}” />
</salesforce-pub-sub:pubsub-config>
<configuration-properties doc:name=“Configuration properties” doc:id=“22115149-9e49-4b15-82d3-e07b198b2225" file=“dev.yaml” />
<http:listener-config name=“HTTP_Listener_config” doc:name=“HTTP Listener config” doc:id=“1767ec86-0259-4dfc-a9c4-2a5996f9a795" >
<http:listener-connection host=“0.0.0.0” port=“8081" />
</http:listener-config>
<flow name=“publisher-flow” doc:id=“ac404e35-6431-4a32-9afc-a0fee82cbc52" >
<http:listener doc:name=“Listener” doc:id=“567f43ed-927c-49dd-9495-ecaa6e6fccee” config-ref=“HTTP_Listener_config” path=“/pubsub”/>
<ee:transform doc:name=“Transform Message” doc:id=“15c9f926-a50c-4d5d-8d1c-d09775bbee6c” >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/java
---
[{ “CreatedDate”: 1.659958888253E12,
“CreatedById”: “0055j000004GTmZAAW”,
“Name__c”: “raju”,
“LastName__c”: “malik”,
“Language__c”: “British”
},{
“CreatedDate”: 1.659958888253E12,
“CreatedById”: “0055j000004GTmZAAW”,
“Name__c”: “john”,
“LastName__c”: “solley”,
“Language__c”: “British”
}]]]></ee:set-payload>
</ee:message>
</ee:transform>
<salesforce-pub-sub:publish-event doc:name=“Publish event” doc:id=“2b6193d3-c988-4d9e-95fc-41b569014793" config-ref=“Salesforce_PubSub_Config” topic=“/event/pubsub_event__e”/>
</flow>
<flow name=“subscriber-flow” doc:id=“3845760a-baac-484a-bf5b-2a3ce11b8607" >
<salesforce-pub-sub:subscribe-channel-listener doc:name=“Subscribe channel listener” doc:id=“6e7156a6-2df5-4501-b095-03e89a0fbe6a” config-ref=“Salesforce_PubSub_Config” channelName=“/event/pubsub_event__e” eventBatchSize=“10”>
<salesforce-pub-sub:replay-option >
<salesforce-pub-sub:latest />
</salesforce-pub-sub:replay-option>
</salesforce-pub-sub:subscribe-channel-listener>
<logger level=“INFO” doc:name=“Logger” doc:id=“be0a663c-b654-4ce0-8c0a-2937d14ba1bc” message=‘#[output application/json
---
{
“Response”:payload
}]’/>
</flow>
</mule>
Please note that:
“publisher-flow” is publishing Platform events into Salesforce
- CreatedDate and CreatedById are standard fields in Salesforce
- CreatedDate value is in milliseconds
- Make sure both of the the above fields are sent, including the related custom fields while publishing the event
- Additionally the correct Salesforce Topic in the Publish Component has to be selected
“subscriber-flow” is consuming Platform events from SF
- The channel listener in the Subscribe component needs to be selected:
- Make sure the connector configuration is set as required, pls see an explanation of the possible values:
- Replay option: there are 4 different option to configure
- Latest: Subscriber receives only new events that are broadcast after the client subscribes.
- Earliest: Subscriber receives all events, including past events that are within the retention window of the server and new events sent after subscription.
- Custom replay id: Subscriber receives all events that are higher than the specified Replay Id value. The value is ignored if the replay option is set on Earliest, Latest, or Replay id from object store.
- Replay id from object store: Subscriber receives only events with a replay ID higher than the specified value in object store. If no value is found, it defaults to Earliest. Provide values for the Object Store Name and the Object Store Key fields to connect to the desired object store and retrieve the replay ID value.
- Batch events size:
- Specify a value for the Batch events size field.
- Total number of events included in a server batch. Lower values indicate a small memory footprint with more server calls, while bigger values indicate a bigger memory footprint with fewer API calls.
- Replay option: there are 4 different option to configure
Final thoughts
The Salesforce Pub/Sub connector fully enables the Salesforce event bus to be used like any JMS Server/Anypoint MQ, with of course limitations.
In designing a solution using this approach make sure:
- The Salesforce Event Retention period is understood, this is between 1 and 3 days, meaning that even if the Event is not consumed the same will be Deleted
- The ReplayID can be used as part of an Acknowledgement process by saving the Last Replay ID successfully consumed in the Object Store (persistent) to support error management approaches and eventual server restart
- Exactly one delivery Principle of JMS was not fully supported by the Salesforce Streaming API, this is to now be tested with Pub/Sub API, if not supported it is recommended dequeuing events from a Single Worker Application and includes mechanism to Stop processing or applying duplicate messages
Here are some resources to help you get started:
- Pub Sub API Developer Documentation
- Pub Sub API GitHub Repo
- MuleSoft Blog
- Salesforce Developers’ Quick Take Video — Introducing the New gRPC-based Pub Sub API
- Salesforce Developers’ Blog — Pub/Sub API: Building Event-Driven Integrations Just Got Even Easier
References:
https://blogs.mulesoft.com/news/mulesoft-connector-for-salesforce-pub-sub-api/
https://medium.com/salesforce-architects/announcing-pub-sub-api-generally-available-3980c9eaf0b7