Showing posts with label notifications. Show all posts
Showing posts with label notifications. Show all posts

Sunday, 5 May 2019

Custom Notifications in Summer 19 Part 1 - Process Builder

Custom Notifications in Summer 19 Part 1 - Process Builder

Introduction

The Summer 19 Salesforce release is around a month away (check the trust site for the official dates) and my trusty pre-release org has been upgraded which allows me to play with some of the new functionality.

One of the items in the release notes that caught my eye was custom notifications, possibly because I’d been on the pilot and had been looking forward to using it in anger, possibly because I had some solutions that used the old method (see below) of sending notifications and it hurt my eyes every time I looked at it. Either way, I was keen to jump in.

The Old Way

To be clear (oh dear, I’m sounding like a UK politician) we’ve always been able to send notifications through custom code, but it’s been clunky, to put it nicely. You can read the full details in Salesforce1 Notifications from Apex, but the short version is that you have to programmatically create a chatter post using the ChatterConnect API and @mention the user you wanted to notify, and they received a notification that you had mentioned them and had to go to the chatter post to find out what you wanted, Not particularly elegant, I’m sure you’ll agree.

The New Way

Custom notifications are a much better solution - still not perfect but a big improvement on what we currently have. At the moment they are sent from Process Builder, so there’s still a little bit of hoop jumping required to send from Apex code.

Defining the Notification

Before you can send a custom notification, you need to define one via Setup -> Notification Builder -> Notification Types. Click New to create a new notification - for my first example I’m creating a custom notification for when a high priority case is received. Note that I can specify which channels a notification will be sent through. This is a nice feature as I’m more likely to want to notify Mobile users as a rule, as they are out of the office and may not be checking Salesforce that often. That said, as this is a high priority case notification, I’m sending it out everywhere that I can:

Once I have my notification, I can create a process that uses it -note that this is the only way that I can fire a notification directly.

Process Builder

My process is defined for the Case subject, when a record is created or edited:

The high priority case test looks for cases that are new or edited to change the priority field, and the priority field is ‘High’:

And the High Priority Case action sends me a notification that we are not in a good place.

After saving and activating the process, creating a new case with a priority of ‘High’ gives me red bell icon on desktop and my mobile, and a notification that is entirely appropriate to the case - clicking on the detail takes me through to the case itself. which is exactly what I want.

In Part 2 of this post I’ll show how notifications can be started from Apex. You still need a process builder to actually send the notification, but the logic around it can live elsewhere.

Related Posts

 

Friday, 27 December 2013

Browser Notifications with the Streaming API

The Streaming API is great for sending information to a user’s browser when a record matches the criteria for a subscribed Topic - there’s an example of this in the Developerforce Wiki. However, we all know that user attention spans are short and it is highly likely that they will have moved on to another window or tab, maybe to get on with some work in another Salesforce org or sandbox.

Browser notifications provide a way to notify a user of changes, even when they have minimised the browser window. The Notification API is still in draft and is currently supported by Chrome, Firefox and Safari - for more details see the caniuse page. In this post I’ll demonstrate how the to generate a notification to the user when a case that they own is updated.  I’ll use the Streaming API to subscribe to updates to all cases, and interrogate the update to determine if the case is owned by the currently logged in user.  If it is, a browser notification will be displayed. The code relies on the Streaming API JavaScript resources being installed as described in the introductory Developerforce Wiki page.

Notifications are different to browser popups, in that they require user approval before they will be shown. This is a one shot deal, so once permission to display has been granted for a Force.com instance it will be retained across multiple sessions. Unfortunately the permission cannot be requested programmatically - the first notification has to be in response to a user action,  clicking a button for example.

The Notification.permission property indicates if permission has been granted or refused for the current site. Unfortunately there is a bug in the Google Chrome implementation of Notifications, which means that the property is always set to ‘undefined’, which in reality indicates that the user has not been asked to grant permissions.  The only way to confirm this in Chrome is to create a new Notification and interrogate the permission property - if the user hasn’t already granted permission they will be asked to via a dialog, while if they have already granted permission the notification will be displayed.  For that reason, the test notification needs to display something non-threatening! 

The following code creates the test notification if required and checks the resulting permission.  Note that it also updates the Notification.permission property so that this only has to be done once.

if (Notification && typeof Notification.permission==="undefined")
{
   var testNotification = new window.Notification('This is a test');

   if (testNotification.permission)
   {
      Notification.permission=testNotification.permission;
   }
}

Once this code has executed, the Notification.permission can be relied on - it may still be undefined, in which case it means that the user hasn’t granted permission (remember, the permission cannot be requested programmatically, so if the user has never been asked, the code above will simply update the Notification.permission to undefined).  Based on the value of this property, I can conditionally show or hide the following section to encourage the user to click a button to enable notifications.

<button id="notifyon" style="display:none">Enable Chrome Notifications</button>
<button id="sendnotify" onclick="notify();">Send Notification</button>

The streaming API part of the code subscribes to a topic and writes information to the page whenever an update to the subscription is received.  It also executes the notify function when an update is received to a record that the currently logged in user owns:

$.cometd.subscribe('/topic/{!topic}', function(message) {
  $('#content').append('<p>Notification: ' +
              'Channel: ' + JSON.stringify(message.channel) + '<br>' +
              'Record name: ' + JSON.stringify(message.data.sobject.Name) +                        '<br>' +
              'Record owner: ' + JSON.stringify(message.data.sobject.OwnerId) +
              '<br>' +
              'Created: ' + JSON.stringify(message.data.event.createdDate) + '<br>' +
              'ID: ' + JSON.stringify(message.data.sobject.Id) + '<br>' +
              'Number: ' + JSON.stringify(message.data.sobject.CaseNumber) + '<br>' +
              'Event type: ' + JSON.stringify(message.data.event.type)+ '<br/>' +
              'Mine : ' + (message.data.sobject.OwnerId=='{!$User.id}'?'Yes':'No') +               '</p>');

    if (message.data.sobject.OwnerId=='{!$User.id}')
    {
        notify(message.data.sobject, message.data.event.type);
    }
});

The notify function instantiates a notification only if the user has granted permission:

function notify(sobject, eventtype)
{
	// If notifications are granted show the notification
	if (Notification && Notification.permission === "granted")
	{
		var millis=new Date().getTime();
	    	var tag = 'CU:' + millis;
	   	var n = new Notification("Case Update",  {
		   		icon : '{!URLFOR($Resource.notifyimg)}',
	  			tag: tag,
	   			body: 'Case ' + sobject.CaseNumber + ' ' + eventtype
	    	});
		n.onclick = function(){
    			window.focus();
    			this.cancel();
		};
	}
}

Each notification needs a unique identifier - if the browser recognises an identifier it won’t display the notification on the assumption the user has already seen this.

An onclick handler for the notification is created to allow the user to close the notification immediately rather than waiting for it to expire.

If I open the Visualforce page in a browser window and click the ‘Enable Chrome Notifications’ button, Chrome will request permission to display notifications:

Screen Shot 2013 12 27 at 15 30 21 

once I allow notifications, a notification confirming this is displayed:

 Screen Shot 2013 12 27 at 15 30 33 

I can then switch to another browser tab or minimise the window completely.  If I then update a case that I own in another browser, a notification is displayed to tell me that it has been updated:

Screen Shot 2013 12 27 at 15 34 41

The full code is available from the following Gists: