Exercise 1: Record Watcher
Goal
We will show how to add an Asynchronous Message Bus (AMB) Record Watcher to an existing workspace. This will allow our app to respond to changes in the data, for instance when a new record is added or changed and needs to update the UI without the typical polling technique.
In this example, we will notify the user if an active case which they are assigned to changes while on the CSM Landing Page.
About the Record Watcher
There are two key concepts with the AMB Record Watcher--the action and the operation.
Actions
The Action is the activity that occurred to engage the record watcher and fire the event. It is centered around the state of the condition in relation to the record watcher. Did it enter the state? Did it exit the state? Or did something on the record that already satisfied the state change?
Consider the following response for the action
property for the condition "assigned to is me".
- entry: A change happened to cause a record to satisfy the condition that did not formerly satisfy that condition. E.g. the assigned to field changes from blank to myself or a new record assigned to me is inserted.
- change: A record that already satisfies the condition changes. E.g. the description of the record changes.
- exit: A record that formerly satisfied the condition no longer does so, e.g. assigned to field changes to another person.
Operation
The Operation is an old-fashioned GlideRecord operation--insert, update, delete. As you can see you could have a combination of actions and operations that aren't exactly 1:1. I.e. a "change" action and "update" operation may seem like the same thing, but in fact an update operation on a record may cause it to "enter" the condition.
You can use these values in combination with the filter to make sure that you only respond to the specific situations that you want to and don't cause too much noise.
Using a record watcher on the UIB page
Open CSM/FSM Workspace in UI Builder (UIB)
-
Change the scope to "CSM Configurable Workspace". You can also switch scope directly within UI Builder.
-
Open UI Builder by going to All > Now Experience UI Framework > UI Builder
-
Find the experience CSM/FSM Configurable Workspace in the list and click the name to open it.
-
Create a duplicate of CSM Landing Page (near the top) by clicking the three vertical dots or snowman icon at the right-end of the line and Duplicate variant.
-
Name the new variant CSM Landing Page Active and choose Create.
-
The newly created variant will open in Editor mode. Select the Settings pill at the top and change the Order to 0 so that we're sure it's the version that is rendered by default.
-
Click Save towards the bottom of the screen then switch back to Editor.
Edit Landing Page and Add Watcher for My Active Cases
Next, we want to add an AMB Record Watcher which will show a message whenever a case to which you are assigned changes. This way we won't miss any critical inputs when they occur.
-
Switch back to the Editor tab using the pill at the top.
-
In the Data and scripts panel at the bottom left of your window, choose Data resources > + Add data resource, select Record Watcher, then select Add.
-
Use the i icon next to the name to rename the data resources as follows:
-
Data resource label: My Active Cases Watcher
-
Data resource ID: my_active_cases_watcher
-
-
Choose Apply.
-
Set the following properties on the data resource:
-
Table: Case [sn_customerservice_case]
-
Choose Edit filter conditions and fill in Assigned to | is
-
Mouse over the value where it says --None-- and choose the data binding icon. In the future we'll refer to this as
<data binding>
whenever you need to use it. -
This pops open the (new in Washington DC) visual data binding window. Choose Page properties > session > user > sys_id and use the little up arrow to the right, double click, or drag the data pill up into the blank white space.
-
Click Apply and click Apply again.
-
Set Subscribe to true.
-
-
Save the page.
Add script to investigate events
Before we wire this up, we need to figure out what sort of data the record watcher events provide. To do this we could try to track down the documentation, but instead, we are going to create a generic script (save it for future use--I have a version of this script in every project that I work on) that will reveal the payload of those events. Events are also very contextual, so this will give us the payload values for the context in which we're working.
-
Under Data and Scripts in the bottom left of the screen, mouse over Client scripts and click the “+” on the right to add a new script.
-
Name your script Debug events and add the following code:
function handler({api, event, helpers, imports}) {
console.log(event.name, event);
} -
Save the page.
-
Open the My Active Cases Watcher data resource you created in the last section.
-
Click into the Events tab.
-
Choose +Add event mapping and choose the Message received event.
-
Add the Scripts > Debug Events event handler and click Add.
-
Close the data resource and Save the page.
-
Select Preview > Open URL Path and open your page in a separate window. Right-click on a blank spot on the page, choose Inspect, and then make sure that the Console is open.
-
Now you need to give the record watcher something to respond to. Go back to Core UI in a separate tab and navigate to All > Customer Service > Cases > My Cases and click New to create a case assigned to you. You can continue to trigger the record watcher by adding work notes.
-
Go back to your workspace page and note the console entry just added in your workspace in the console, something like this:
By inspecting this object we can deduce what values we can use for deciding when to notify the user. In this case we can drill down to payload.data.action to know that a record changed, payload.data.changes to get a list of fields that changed and payload.data.record to get the newly changed value for standard field types.
Add an alert when a case is updated
Now that we know what to look for, let's do something practical with this info. We'll add an event handler to alert the user if any changes happen to a CSM case to which they are assigned.
-
Open the My Active Cases Watcher data resource back up, open the events tab, and add another event handler to the Message received event.
-
Choose Page-level event handlers > Add alert notifications and change the Mode from Form to Script. You'll use a script here as it allows for a more dynamic message.
-
You'll want to add to the items array so that the script looks like this:
function evaluateEvent({api,event}) {
return {
items: [{
"status": "info",
"content": `Your case ${event.payload.data.display_value} has been updated`,
"action": {
"type": "dismiss"
}
}]
};
} -
Below the script box, choose Advanced and choose to trigger Conditionally (you may have to scroll down to reveal more options).
-
Mouse over the field and choose data binding icon to open the visual data binding window.
-
Double-click into the area with the message Add a data output to this area, etc.
-
Paste in (@payload.data.action == "change") and choose Apply.
-
Choose Add.
-
Close the data resource modal and Save the page.
-
Now test the page by going to your test tab and refreshing. Then go back to the record in Core UI and add a work note.
-
You should see a message on the workspace landing page whenever you add a work note to a case assigned to you.
Challenges
Display different message on assignment vs update
Try using the same techniques but this time show a different message on "entry" to let the user know that a new record has been assigned to them and that they should refresh their list of cases. You will use the same techniques as the prior section but instead use the condition on the "Add alert notifications" event handler of (@payload.data.action == "entry")
;
Update the list when assigned
Another real-world example would be to tell the user they have had a record assigned to them and update the My active cases list on the landing page. On the CSM workspace landing page the controls do not have a way to directly force a refresh, but we can work around that.
The only thing we can do to manipulate the components is to change the state. We will add an arbitrary date to the filter for "updated after" and change that value to different times of the day on 1970-01-01.
-
In the bottom left hand part of the screen select “Client state parameters” and add a new state parameter called "updatedAfter".
-
Go to the "My active cases" list in the middle of the screen and click "Edit filter" in the Config panel on the right and add "Updated after @state.updatedAfter" to the filter:
-
Go back to the record watcher Events tab under Message received and add "Update client state parameter" using Script mode to update the value of this state parameter.
-
Mode: Script
function evaluateEvent({api, event}) {
var msSinceMidnight= new Date()-new Date().setHours(0,0,0,0);
const newDate = new Date(msSinceMidnight);
const [dtString] = newDate.toISOString().split('.');
return { propName: "updatedAfter", value: dtString };
} -
When to trigger:
((@payload.data.action == "entry") || (@payload.data.action == "exit"))