Integrate Pub/Sub and Message Events in LWC from Omniscript for Toast Notifications
Table of contents
Intro
Have you ever needed to show a toast message after an Omniscript action / step is completed? Or wanted to perform some action once an Omniscript is done?
Well, today is your lucky day! We're diving into the awesome capabilities Omniscript offers with Pub/Sub or Message events. We'll explore how to publish these events and listen to them in a Custom LWC, so you can do cool things like showing a toast message. Let's get started!
Pub/Sub Event
This event is a standard Pub/Sub event that can be triggered by Omniscript action or step elements. The event raised here can be listened to by any custom LWC on the lightning page, allowing us to take action on it.
For demonstration purposes, I created an Omniscript with two step elements. At the end of these steps, I make an Apex call. In the remote action, you can see that I have checked "Pub/Sub" under the Messaging Framework
.
This option ensures that a pub/sub event is emitted after the action is completed. Now, let's see how to listen to this event in an LWC component.
import {LightningElement} from 'lwc';
import pubsub from 'omnistudio/pubsub';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
export default class PubSubListener extends LightningElement {
connectedCallback() {
pubsub.register('omniscript_action', {
data: this.handleOmniActionData.bind(this),
});
}
handleOmniActionData(data) {
console.log('Data => ' + JSON.stringify(data));
//ShowToastEvent from here
}
}
We have imported import pubsub from 'omnistudio/pubsub';
and subscribed to omniscript_action
using the pubsub API. Similarly, we can also subscribe to omniscript_step
to listen to events raised from the Step element in Omniscript.
From the Chrome console logs, you can see that it sends all nodes related to the action. You can process the specific action you are interested in. For example, in the above image, we sent ActionCompleted
as a parameter, and if you view the JSON below, you will see that ActionCompleted
is printed successfully.
{
"VlocityInteractionToken": "8327282b-bab5-46d3-b3a5-929a19a6e517",
"OmniScriptId": "0jNIg000000fxX7MAI",
"ComponentId": "0jNIg000000fxX7MAI",
"OmniScriptType": "Util",
"OmniScriptSubType": "ShowCustomToastMessageAfterProcess",
"OmniScriptLanguage": "English",
"OmniScriptVersion": 1,
"OmniScriptTypeSubTypeLang": "Util_ShowCustomToastMessageAfterProcess_English",
"ElementLabel": "RemoteAction1",
"BusinessCategory": "",
"BusinessEvent": "",
"RemoteClass": "ValidationOperation",
"RemoteMethod": "customValidationAndSave",
"SendJSONPath": "",
"SendJSONNode": "",
"ResponseJSONPath": "",
"ResponseJSONNode": "",
"UseContinuation": false,
"PreTransformBundle": "",
"PostTransformBundle": "",
"InvokeMode": "",
"UseQueueableApexRemoting": "",
"ActionTargetName": "ValidationOperation",
"ActionTargetType": "Apex Class",
"ElementStepNumber": 3,
"OmniEleName": "RemoteAction1",
"ElementName": "RemoteAction1",
"OmniEleType": "Remote Action",
"ElementType": "Remote Action",
"ActionCompleted": "ActionCompleted",
"OmniScriptContextId": "500Ig000003DoH0IAK",
"TrackingService": "OmniScript",
"TrackingCategory": "UI",
"ReadyTime": 1721142075841,
"ElapsedTime": 337,
"StopTime": 1721142076178,
"Resume": false,
"ResponseSize": 47,
"RequestSize": 733,
"type": "Remote Action",
"name": "RemoteAction1",
"OmniScript": "Util_ShowCustomToastMessageAfterProcess_English"
}
For demo purpose I added this apex class to mimic an apex action
global with sharing class ValidationOperation implements omnistudio.VlocityOpenInterface, Callable {
global Boolean invokeMethod(String methodName,
Map <String, Object> inputMap,
Map <String, Object> outMap,
Map <String, Object> options) {
Boolean success = true;
if (methodName == 'customValidationAndSave') {
outMap.put('returnFromApexServer', 'Success');
}
for (Integer i = 0; i < 100000; i++) {
}
return success;
}
global Object call(String action, Map<String, Object> args) {
Map<String, Object> input = (Map<String, Object>) args.get('input');
Map<String, Object> output = (Map<String, Object>) args.get('output');
Map<String, Object> options = (Map<String, Object>) args.get('options');
return invokeMethod(action, input, output, options);
}
}
Now lets see the result.
In the same way, you can use this flow to pop up a toast message after an OmniScript flow is completed! You can either use it as shown above, or if you don't have any action at the end, just add a SetValue element at the end of the OmniScript and pass your parameters just like above. How cool is that?!
Window postmessage
This is another option for listening to messages. It uses the native JavaScript Message
event, which is triggered on windows. You can listen to this event using a native JavaScript listener.
export default class ToastMessageListener extends LightningElement {
connectedCallback() {
window.addEventListener('message', (event) => this.handleOmniStepLoadData(event))
}
handleOmniStepLoadData(event) {
if(event && event.data) {
console.log('Data => ' + JSON.stringify(event.data));
}
}
disconnectedCallback(){
window.removeEventListener('message', () => this.handleOmniStepLoadData(data))
}
}
Here, we don't need to import any listener because this is native to JavaScript.
The data in the event looks like this.
{
"OmniScript-Messaging": {
"VlocityInteractionToken": "9d4cd82d-e1f7-4fe8-8e09-8cb13b3ae1ab",
"OmniScriptId": "0jNIg000000fxX7MAI",
"ComponentId": "0jNIg000000fxX7MAI",
"OmniScriptType": "Util",
"OmniScriptSubType": "ShowCustomToastMessageAfterProcess",
"OmniScriptLanguage": "English",
"OmniScriptVersion": 1,
"OmniScriptTypeSubTypeLang": "Util_ShowCustomToastMessageAfterProcess_English",
"ElementLabel": "RemoteAction1",
"BusinessCategory": "",
"BusinessEvent": "",
"RemoteClass": "ValidationOperation",
"RemoteMethod": "customValidationAndSave",
"SendJSONPath": "",
"SendJSONNode": "",
"ResponseJSONPath": "",
"ResponseJSONNode": "",
"UseContinuation": false,
"PreTransformBundle": "",
"PostTransformBundle": "",
"InvokeMode": "",
"UseQueueableApexRemoting": "",
"ActionTargetName": "ValidationOperation",
"ActionTargetType": "Apex Class",
"ElementStepNumber": 3,
"OmniEleName": "RemoteAction1",
"ElementName": "RemoteAction1",
"OmniEleType": "Remote Action",
"ElementType": "Remote Action",
"ActionCompleted": "ActionCompleted",
"OmniScriptContextId": "500Ig000003DoH0IAK",
"TrackingService": "OmniScript",
"TrackingCategory": "UI",
"ReadyTime": 1721144417457,
"ElapsedTime": 323,
"StopTime": 1721144417780,
"Resume": false,
"ResponseSize": 47,
"RequestSize": 733
}
}
Conclusion
Here in the article, we explored how to listen to events triggered by any action and step elements of Omniscript.
There are mainly two types of events: pub/sub and the window's native message event. Now you can decide what to do after receiving an event, whether it's showing a toast message or performing another action.
Subscribe to my newsletter
Read articles from Nagendra Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Nagendra Singh
Nagendra Singh
Allow me to introduce myself, the Salesforce Technical Architect who's got more game than a seasoned poker player! With a decade of experience under my belt, I've been designing tailor-made solutions that drive business growth like a rocket launching into space. ๐ When it comes to programming languages like JavaScript and Python, I wield them like a skilled chef with a set of knives, slicing and dicing my way to seamless integrations and robust applications. ๐ฝ๏ธ As a fervent advocate for automation, I've whipped up efficient DevOps pipelines with Jenkins, and even crafted a deployment app using AngularJS that's as sleek as a luxury sports car. ๐๏ธ Not one to rest on my laurels, I keep my finger on the pulse of industry trends, share my wisdom on technical blogs, and actively participate in the Salesforce Stackexchange community. In fact, this year I've climbed my way to the top 3% of the rankings! ๐งโโ๏ธ So, here's to me โ your humor-loving, ultra-professional Salesforce Technical Architect! ๐ฅณ