Jennifer Lee and Sunil Matthew in a new episode of "Automate This!"

Automate This! — Migrate Processes to Flow and Use Custom Notifications

By

Welcome to another “Automate This!” In this live-streamed video series, we cover all things automation, from use cases and best practices to showcasing solutions built by #AwesomeAdmin Trailblazers like you. With automation, you can remove manual tasks, drive efficiency, and eliminate friction and redundancy. In this episode, let’s see how Sunil Mathew used Flow and custom notifications to ensure support agents stayed in the loop on their cases.


The context

Previously, after a case was created and picked up by a support agent, email communications were handled in Outlook, with the Salesforce Email-to-Case address copied so the emails would end up in Salesforce.

There are a variety of reasons why this was a bad process that needed some modernization.

  • What if the Salesforce Email-to-Case address was removed from the email thread?
  • This is a poor branding experience, with emails coming from agents instead of a unified group email.
  • If subsequent issues arise, clients were emailing agents directly instead of opening a case through the Email-to-Case. This causes delays, frustration, and inaccurate data.
  • With the eventual change from Reference ID to Email Header for email threading, this process would no longer work.

We spent months with our support team to modernize their process, and moved them to use the Send Email action on their Lightning record page. Huzzah! We customized the action to work for them. They are now able to email using Salesforce email templates, and from our common support email address.

The business need

One side effect of this new process is that support agents will no longer get email notifications when an email comes in for a case they are working. This was a major concern for the team, as they have tight service-level agreements (SLAs) and want to ensure customer satisfaction on all cases. The stopgap was to create a Salesforce report that would show any cases with newer Email Message records. Although this report was accurate, it was cumbersome, as it required support agents to proactively check and refresh the report. There must be a better option?

How I solved it

Enter custom notifications!

What are custom notifications? With the rollout and proliferation of Lightning Experience, you may have noticed the notification bell at the top right corner of your Salesforce window.

Location of the notification bell in the Salesforce window

But did you know that in addition to receiving system notifications from Salesforce, you can actually push out custom notifications to users using this functionality as well? There are some great benefits to custom notifications.

  • Can be sent out using dev tools like Apex and the API, and declarative tools like Flow
  • Passive alerts—agents don’t have to do anything to receive them!
  • Keeps agents in app—reduces context switching between Salesforce and Outlook
  • Can specify a target record when the notification is clicked
  • Can send them to a user, collection of users, public group, queue, or account/opportunity team

The automation: Process Builder version

Our initial implementation of these custom notifications was done in Process Builder. Let’s take a look at how it was set up there.

Process Builder that executes custom notification logic

We can see that we kick this process off at the creation of an Email Message record. In the Decision nodes, we check to make sure the Email Message is for an Incoming email. We confirm that the parent case of the email message record is a support case, is still open, and whether it’s owned by a User or Queue. Based on which node is true, we execute a scheduled action. Here’s what the Send Custom Notification action looks like in Process Builder.

Send Custom Notification action in Process Builder

Within the Send Custom Notification action, you can set the notification recipient(s), the title, and the body for the custom notification. In this case, the recipient is a user, and I’m identifying the OwnerId field on the Case object as the reference. Here’s where you can change the recipient to be a public group, queue, etc.

The automation: Migrate to Flow

This gets the job done, but we know Flow will be the one declarative automation tool going forward. The best practice for admins going forward is to not only build using Flow but also migrate other declarative automation to Flow, when possible. Flow allows complex logic and branching that can really power up your automations and take them to the next level.

There are some great blog posts on how to develop a Flow strategy so that no matter what flow you build, you have a well-developed perspective on what flow-building looks like for you in your org. One thing we noticed is that when we release an enhancement to one team, other teams start to get wind of that and want it for themselves. So here, my Start criteria is more broad, but the Decision elements within the flow narrow the scope. If another internal team wants to adopt their own process for when incoming emails arrive, I can add their criteria within the Decision element as an additional flow path (more on that later), opposed to creating an additional flow or editing the Start criteria. I built this flow with the strategy to minimize the number of record-triggered flows per object.

Flow overview

Overview of how the flow looks

Visually, I love auto-layout!

This record-triggered flow triggers off the Email Message object. Email Message is a system object provided by Salesforce in Service Cloud and captures all inbound and outbound emails related to a case. When an email is created, an Email Message is created. For our use case, we only want our automation to start if the Email Message is marked as “Incoming”, which means that the email did not originate from your Salesforce instance. Also note that this is an after-save flow, as we will utilize the Run Asynchronously option to break up the transactions.

Did you know? A transaction is a group of operations that are executed together. By breaking up transactions within a flow, you allow one set of operations to save before moving on to the next. That also helps us understand an after-save flow, as it comes after some of these operations have occurred (compared to a before-save flow, which runs at the front end of a transaction). An after-save flow gives you the capability of tapping into related records, performing outbound actions, and running asynchronously.

The Start element of the flow and the chosen criteria

Run Asynchronously

We will utilize an Asynchronous path to break up the transaction. The main reason is that if creating the custom notification fails, we do not want the Email Message creation to be rolled back.

Scheduled Path details of the flow

Decision

Since a flow can have complex and branching logic, each of these branches are colloquially known as flow paths. Paths can be split out at the start of a flow via Scheduled Paths, or through criteria evaluation in a Decision element. In this flow, we’re configuring two flow paths. These paths are nearly identical except that we’re checking to see if the current case owner is a user or a queue. We confirm this in the logic by checking the OwnerId and seeing if the prefix is 005 (user) or 00G (queue). All objects have a unique three-character prefix for their record IDs. The record ID’s prefix for standard or system objects can be found by searching online.

Note #1: I purposely did not use the ‘Default’ outcome, as we have some enhancements on our roadmap to expand the usage of this flow and this Decision.

Note #2: Since this is a record-triggered flow, when you see $Record anywhere in the flow (conditions, assignments, actions, etc.), it’s referencing the record which kicked off the flow.

Decision element checking to see if the Case is owned by a user

Decision element checking to see if the Case is owned by a queue

Assignments

Based on the outcome from the Decision element, we’re going to send the flow down one of the paths to assign values to two variables. A variable is a container that stores a value for use in your flow. When creating a variable, you state the type of data it can store (text, number, date, etc.). Then, within the logic of the flow, you can assign a value to that variable. The business rule here is that if the case is owned by a user (for example, a support agent), then send the custom notification to that agent. If the case is owned by a queue, send the custom notification to a public group that contains all the support managers.

This brings us to a key rule with all Salesforce automation: Don’t hard code IDs! Hard coding IDs within automation is generally seen as a no-no, as it makes it difficult to read and hard to update. And, if the ID doesn’t exist in production, when you deploy the change to production, guess what? The ID won’t match what’s in production and, as a result, your flow will fail. Instead, it’s best to store the ID in one centralized place, so that if you need to change that ID, you can do it once and all your automation and logic will automatically reference the new value. In our org, we typically store an ID value as a custom label. A custom label can then be used in Flow, validation rules, Lightning pages, etc. We stored the ID of the Customer Support MGMT Public Group to a custom label named groupCustomerSupportMGMT.

Flow Assignment element showing assignment values when Case is owned by a user

Flow Assignment element showing assignment values when Case is owned by a queue

Action

We’ve arrived at the Custom Notification action. This is the core action to create custom notifications. Let’s get this notification built out!

  • Custom Notification Type ID
    • We store the ID in a custom label and reference the custom label in the Flow action.
  • Notification Body
    • Created a Text Template resource and referenced it here. A text template is essentially a dynamic rich-text area block of text. It allows you to use formatting and access merge fields from the flow, as well as data from the triggering record and related records to build out your text.
  • Notification Title
    • This value was assigned to the variable in the Assignment element.
  • Recipient IDs
    • This value was assigned to the variable in the Assignment element.
  • Sender ID
    • This default user is where the custom notification is generated. Again, we store the user ID in a custom label and reference that in the flow. Notice a trend?
  • Target ID
    • This is the record that a user will be redirected to when they click on the custom notification. Since this flow was triggered from the Email Message, {$Record.Id} takes the user to that record. You can also do {!$Record.Parent.Id} to take you to the related case, or use other dot notation to take you to a different related record.

The Send Custom Notification action in Flow and the various datapoints needed to execute this action

To specify the custom notification Type ID, you have to create a Custom Notification Type first and capture the ID here. To create a Custom Notification Type, go to Setup > Notification Builder > Custom Notifications and create a new Type by identifying the channels that it will support.

Creating a Custom Notification Type

To find the ID for the Custom Notification Type you just created, you can do a quick SOQL query in the Developer Console:

SELECT Id,CustomNotifTypeName FROM CustomNotificationType

How to SOQL query Custom Notification Types to find the ID

The result

Now, when an email comes into a case, a badge will appear on the custom notification bell. Clicking on the bell will bring you to a list of notifications. Here, you can click to go directly to that Email Message. Notifications come in real time and clients are left delighted with the quick communication turnaround!

The custom notification live in Salesforce, from the notification bell

Your turn

It’s now your turn to use custom notifications to delight your users and clients. What are some use cases within your business where custom notifications can bring value?

Resources

Want to see more good stuff? Subscribe to our channel!

SUBSCRIBE TODAY
Copy Files from One Object Record to Another.

Copy Files from One Object Record to Another | Automate This!

Welcome to another “Automate This!” In this live-streamed video series, we cover all things automation, from use cases and best practices to showcasing solutions built by Awesome Admin Trailblazers like you. With automation, you can remove manual tasks, drive efficiency, and eliminate friction and redundancy. In this episode, see how Eric Smith created a subflow […]

READ MORE
Eliminate Manual Record Matching.

Eliminate Manual Record Matching | Automate This!

Welcome to another “Automate This!” In this live-streamed video series, we cover all things automation, from use cases and best practices to showcasing solutions built by Awesome Admin Trailblazers like you. With automation, you can remove manual tasks, drive efficiency, and eliminate friction and redundancy. In this episode, Christina Nava uses a screen flow to […]

READ MORE
Harness Custom Settings and Flow for Dynamic Round Robins.

Harness Custom Settings and Flow for Dynamic Round Robins | Automate This!

Welcome to another “Automate This!” In this live-streamed video series, we cover all things automation, from use cases and best practices to showcasing solutions built by Awesome Admin Trailblazers like you. With automation, you can remove manual tasks, drive efficiency, and eliminate friction and redundancy. In this episode, see how Warren Walters creates custom Auto […]

READ MORE