Working with Salesforce PushTopics

Mike Var
4 min readJun 19, 2022

--

Photo by Julien Maculan on Unsplash

Salesforce PushTopic events are a part of the Salesforce Streaming API

Basically, PushTopics is a way to receive notifications for changes to Salesforce data that match a SOQL query you define. They are good for surfacing notifications within the Salesforce UI (lighting component, etc) based on record changes.

According to the Salesforce Data Integration guide, PushTopics is no longer ideal for some use-cases and can be replaced with Platform Events. Anyway, it's good to understand the "topic" and how it can be used.

The below example is available in the Github Repository

Contents

  1. PushTopic general considerations
  2. How to create a push topic
  3. Subscribe to a PushTopic event using LWC
  4. PushTopic events vs Platform Events
  5. References

1. PushTopic general considerations

We will not touch the PushTopic limits, since those are available in this official Salesforce article: PushTopic Streaming Allocations

2. How to create a push topic

There are two steps:

  1. Choose a custom object or one of the standard objects (see a list of standard objects available by this link)
  2. Define fields you’d like to track and operations (on create / update / delete / undelete)
  3. Insert a PushTopic

A sample code for creating a PushTopic event and tracking account name changes will look like this:

PushTopic pushTopic = new PushTopic();
pushTopic.Name = 'AccountNameUpdates';
pushTopic.Query = 'SELECT Id, Name FROM Account';
pushTopic.ApiVersion = 54.0;
pushTopic.NotifyForOperationCreate = true;
pushTopic.NotifyForOperationUpdate = true;
pushTopic.NotifyForOperationUndelete = true;
pushTopic.NotifyForOperationDelete = true;
insert pushTopic;

The code snippet can be executed as Anonymous Apex in a code editor (like VS Code) or a developer console. If the execution was successful, we can move forward to monitoring the event in a Lightning Web Component (LWC) and empApi.

3. Subscribe to a PushTopic event using LWC

Salesforce LWC library includes an example with Emp API that basically looks like this:

Link to the component in the GitHub repository: pushTopicsMonitor

The Channel Name input contains a PushTopic name that was created before. A push topic subscription starts with /topic/ + PushTopic Names

All push topics can be queried via a SOQL Query like this:

Select ID, Name FROM PushTopic

Component .HTML file:

<template>
<lightning-card title="PushTopic Example" icon-name="standard:topic">
<div class="slds-m-around_medium">
<div class="slds-grid_vertical">
<div class="slds-col">
<p>
Use the buttons below to subscribe and unsubscribe to a
streaming channel!
</p>
</div>
<div class="slds-col slds-size_1-of-3 slds-m-top_medium">
<lightning-input
label="Channel Name"
value={channelName}
onchange={handleChannelName}
></lightning-input>
</div>
<div class="slds-col slds-m-top_medium">
<lightning-button
variant="success"
label="Subscribe"
title="Subscribe"
onclick={handleSubscribe}
disabled={isSubscribeDisabled}
></lightning-button>
<lightning-button
variant="destructive"
label="Unsubscribe"
title="Unsubscribe"
onclick={handleUnsubscribe}
disabled={isUnsubscribeDisabled}
class="slds-m-left_x-small"
></lightning-button>
</div>

<div class="slds-col slds-m-top_medium">
<h2>Messages:</h2>
<div class="slds-m-around_medium">
{topicMessages}
</div>
</div>
</div>
</div>
</lightning-card>
</template>

.JS controller:

import { LightningElement, track } from 'lwc';
import {
subscribe,
unsubscribe,
onError,
setDebugFlag,
isEmpEnabled,
} from 'lightning/empApi';

export default class TestEmpApi extends LightningElement {

channelName = '/topic/AccountNameUpdates';
isSubscribeDisabled = false;
isUnsubscribeDisabled = !this.isSubscribeDisabled;
@track topicMessages = '';

subscription = {};

// Tracks changes to channelName text field
handleChannelName(event) {
this.channelName = event.target.value;
}

// Initializes the component
connectedCallback() {
// Register error listener
this.registerErrorListener();
}

// Handles subscribe button click
handleSubscribe() {
// Callback invoked whenever a new event message is received
const messageCallback = (response) => {
// Response contains the payload of the new message received
this.topicMessages = JSON.stringify(response);
};

// Invoke subscribe method of empApi. Pass reference to messageCallback
subscribe(this.channelName, -1, messageCallback).then((response) => {
// Response contains the subscription information on subscribe call
console.log(
'Subscription request sent to: ',
JSON.stringify(response.channel)
);
this.subscription = response;
this.toggleSubscribeButton(true);
});
}

// Handles unsubscribe button click
handleUnsubscribe() {
this.toggleSubscribeButton(false);

// Invoke unsubscribe method of empApi
unsubscribe(this.subscription, (response) => {
console.log('unsubscribe() response: ', JSON.stringify(response));
// Response is true for successful unsubscribe
});
}

toggleSubscribeButton(enableSubscribe) {
this.isSubscribeDisabled = enableSubscribe;
this.isUnsubscribeDisabled = !enableSubscribe;
}

registerErrorListener() {
// Invoke onError empApi method
onError((error) => {
console.log('Received error from server: ', JSON.stringify(error));
// Error contains the server-side error
});
}
}

The channel is available in this variable:

channelName = '/topic/AccountNameUpdates';

AccountNameUpdates push topic was created with the query as this:

pushTopic.Query = 'SELECT Id, Name FROM Account';

That means that the subscription will work for any account Name changes and will disregard other fields:

4. PushTopic events vs Platform Events

According to Salesforce Data Integration decision guides, there is a difference between use cases for PushTopic and Platform Events and their capabilities:

References:

Salesforce article: PushTopic Events

GitHub Repository: link

--

--