Automate This! — Send Case Notifications Automagically with Flow


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 Michelle Hansen uses custom metadata and Send Email actions to notify Sales and Customer Service teams about pertinent cases in a timely manner.

Do you remember The Skeleton Dance song from your childhood, the one where the leg bone is connected to the knee bone? We learned (as most of us over a certain age know from experience) that even very distant bones, like those in your feet and neck, are connected. Well, the same can be said for businesses. What’s going on in your customer service department can have a significant impact on your Sales team and vice versa. Keeping everyone informed about what’s going on, and ensuring your business runs smoothly, can go a long way toward ensuring you both meet your internal goals and retain satisfied customers.

The challenge

As we continue to sell additional solutions to existing customers, it’s not only vital that we continue to provide outstanding customer service but also that our Sales teams are made aware of any problems arising for customers with whom they are engaged in an active sale. To ensure they address these issues, we need to notify our Sales team of any cases created for accounts where there’s an open opportunity. Specifically, the opportunity owner(s) should receive an email with case details that invites them to follow the case to stay informed. We also want to ensure that all cases opened are assigned to a customer service agent within 10 minutes to ensure prompt customer service. If a case is still in New status after that duration, the customer service manager (CSM) should be emailed.

While in past years, we may have leveraged workflow rules or processes to achieve this, the Winter ’21 announcement that flows are the future means that record-triggered flows are the best tool to fulfill our requirements.

Map the process

To get started, we want to map out what should happen, when, and under what conditions. We can do this by looking at our requirements.


  1. We want to email the open opportunity owner(s).
  2. We want to email the CSM.


  1. When a case is created
  2. Ten minutes after a case is created

Under what conditions

  1. At least one open opportunity associated to the Account
  2. For all cases

This gives us some important information we will use to design our flow:

  1. We need to optimize the flow for Actions & Related Records (After Save).
  2. We need both an immediate path and a scheduled path.
  3. We need to look for opportunity records and owner(s) (Get Records).
  4. We need to confirm the case status after 10 minutes (Decision).
  5. We need to know who the CSM is (Custom Metadata).

Create a process map

Documenting new functionality in your org is key to ensuring you can maintain and extend it into the future, and it also serves a dual purpose as training material. While many options for process mapping/diagramming exist, I personally use Lucidchart. The resulting process map is shown below. This is not an exact layout of the flow; rather, this helps us plot out the process and the order in which things need to be done. I also find it helpful to document the actual flow itself in a similar fashion, but that’s a topic for another blog post.

A process map in Lucidchart.

Why custom metadata?

If you haven’t yet heard, it’s widely considered bad practice to hard code information in automation, especially information that can potentially change. While there are several strategies we could employ to solve this requirement, we opted to use custom metadata types (CMDT) for several reasons:

  1. Unlike a custom object, CMDT (both the object and records) can be deployed between orgs and don’t count toward the org’s object limit. This means that when you create or refresh a sandbox, all of this data—including the records—is automatically included because the records are metadata, like your configuration. Custom Object data and Custom Settings have to be recreated or imported each time.
  2. CMDT records can be accessed in automation, formula fields, and validation rules.
  3. Setting up a CMDT object allows us to build records for additional routing scenarios in the future without the need to add multiple fields—or a dreaded multi-select picklist field—on the User object, if the same user should be a recipient in multiple scenarios.
  4. Separating routing from the User object allows us to identify non-Salesforce users as recipients, if necessary.
  5. It’s as simple as creating a custom object!

Build the CMDT object

CMDT is located in the Setup menu (Setup > Custom Code > Custom Metadata Types). First, create a new object called Routing Recipients, with four custom fields to hold the information you want to store and access in your flow: First/Group Name, Last Name, Email Address, and User/Group ID. By including all of this information, you eliminate the need to do an additional Get Records on the User object—the most commonly needed fields are all included.

The configured CMDT.

Next, click Manage Routing Recipients to create the first record in your new Routing Recipients CMDT object. Create a record labeled Unclaimed Case, and complete the custom fields with the information for your CSM.

Unclaimed case CMDT record.

Flow overview

Your flow is triggered on Case record creation and has two paths. The Run Immediately path searches for any open opportunities for the same account. If any are found, the flow then loops through each open opportunity to get the owner’s email address and add it to a collection variable/list of email addresses. You can then use that collection of email addresses as the recipients for an email notifying each opportunity owner that a new case has been opened for their prospective customer. The 10 Minutes After Create path checks if the status of the case is still New. If so, it gets the recipient information from your CMDT object to send the CSM an email notification.

The configured flow for your process.

Build the flow—Identify Start Criteria

First, you need to identify your Start Criteria, which determines when this flow will run. Since this is dependent on the creation of a new Case record, choose a record-triggered flow and click Create. Then, select the Case object and trigger the flow when a record is created, since both actions only need to happen relative to a new case, not if an existing case is updated. Leave your criteria set at none so this runs every time a case is created. You need to run this every time for two reasons:

  • First, you have to start the 10-minute timer since every Case unclaimed needs to be dealt with.
  • Second, you have to check for open opportunities on every Case’s account.

Finally, you want to set this as an After Save (optimized for Actions and Related Records) since you’re using the Send Email action.

Configured start flow element.

Build the flow—Create the scheduled path

Once you’ve configured the Start element, you can edit it to add a scheduled path. For those familiar with Flow, this looks similar to building a decision outcome. (A scheduled path is equivalent to a time-based trigger workflow or a scheduled action in Process Builder.) Name it “10 Minutes After Create” and choose the “When Case is Created” Time Source. Setting the Offset Number to “10” and Offset Option to “Minutes After” rounds out the parameters for your scheduled path.

The configured scheduled path.

Build the flow—Run Immediately

Get open opportunities using Get Records
Looking at your requirements, you first need to use a Get Records to search the database for any open opportunities related to the same account your case is opened on. After setting your Get Records to retrieve opportunities, you’ll use the following three criteria set to “All Conditions Are Met (AND)” to narrow down your list:

  1. AccountId Equals $Record.AccountId
  2. StageName Does Not Equal Closed Won
  3. StageName Does Not Equal Closed Lost

The first criterion makes sure that the Opportunity object’s account ID is the same as the account ID on the case that triggered your flow, which is represented by a special global variable called $Record. You can identify Salesforce global variables by the dollar sign ($), and the record variable is a placeholder for whichever record triggered the flow to run. Then, leverage dot notation to get from the object level to the field level, which is how you specify that you want to use the value of the Case (Record) AccountId (.AccountId) field.

The second two conditions outline the two stages you want to exclude: Closed Won and Closed Lost. When using “Does Not Equal” with multiple options of the same type, it’s necessary to use AND, not OR. In our scenario, the opportunity’s stage cannot be “Closed Won” AND ALSO cannot be “Closed Lost.” To exclude both requires AND. While in the English language it’s common to say, “It can’t be Closed Won or Closed Lost,” if we write this logic with an OR statement it would include all Closed opportunities. This is because a Closed Lost opportunity doesn’t equal Closed Won (condition 2 evaluates to TRUE) and a Closed Won opportunity doesn’t equal Closed Lost (condition 3 evaluates to TRUE).

Finally, store All Records and Automatically store all fields.

Configured Get Records to locate open opportunities associated with the Case’s account.

Check for results with a Decision element
Best practice after any Get Records is to confirm that records were actually found before you try to continue, and specify what should happen if no results are returned. To do this, use a Decision element that checks to see if the output of your Get Records is empty (meaning, we didn’t find any records). If it’s not empty, continue with notifying the opportunity owner(s). However, if no open opportunities are found, you don’t have any further actions to take immediately and will end the flow.

Configured Decision to check whether any open opportunities were found.

Find opportunity owners with a loop
Since it’s plausible that for some companies there could be multiple open opportunities, and that different salespeople could be handling them, you want to ensure you don’t miss notifying anyone about a new case. To capture the email address of each opportunity owner, you need to use a loop. This allows you to look at each record from your “Get Open Opptys” Get Records element individually and grab the email address from that record owner’s user for use later in your flow. You’re going to hold all of these in a collection variable, which is a flow resource specifically designed to hold multiple values of the same type. Note the naming convention for the collection variable—it starts with “cvar” to identify it.

The cvarOpptyOwnerEmails collection variable to hold opportunity owner emails.

Add email addresses to a collection and de-duplicate email collection—Assignment
Inside the loop, you want to get the owner’s email for the current Opportunity record and add it to a collection that will be used as your email recipients. However, you may encounter a situation where more than one opportunity is owned by the same person. To avoid sending more than one email to the sales manager about the same case, you need to de-duplicate the collection. To achieve this, remove all instances of the current email address from the collection before you add the current email to the collection. If it wasn’t there before, that’s not an issue—the flow simply won’t find anything to remove before adding the current email. This will guarantee that only one instance of each email address will be in your collection variable. Use dot notation to traverse the relationship between records to get to the Email Address field without needing a separate Get Records element.

Start with the current Opportunity (Open_Opptys_Loop), then access the Owner’s User Record (Owner), and specify the field you want (Email). The resulting value for both variables in the screenshot below is {!Open_Opptys_Loop.Owner.Email} (what you see when you’re building/editing it) or Current Item from Loop Open_Opptys_Loop > Owner ID > Email (what shows when viewing it like the screenshot below).

Configured assignment to remove duplicate emails and add the email to the collection variable.

Send Email to opportunity owners—Action
Once you’ve built the list of recipients, you can focus your attention on the email you want to send. Use a text template to format the body with the information you want to include, create the subject, and then use your collection variable to specify recipients.

Text templates are powerful tools that allow you to mix literal text and merge fields from any records the flow has access to. You can also use either a WYSIWYG (what you see is what you get) rich text editor or HTML markup to format the body of the email exactly as you want, including hyperlinks.

In this situation, I chose to use the HTML markup in a plain text template and then have it render as rich text in the email action for finer control of the formatting. Again, note the naming convention of the Text Template, which begins with “tt”.

The configured text template resource.

The email action itself can use a combination of flow resources and literal text to set the values. For example, the subject includes both.

The configured email action.

Build the flow—10 Minutes After Create

Checking Case Status—Decision
Once the 10-minute mark after record creation has been reached, the scheduled path fires. You need to confirm the status value to determine how to proceed by using a Decision element. Essentially, you’re once again asking a question and choosing your path forward based on the answer. In this case, your question is, “Is the Case Status still New?” Your decision outcomes align with the possible answers. If “Yes,” you proceed and if “No,” you stop.

The configured Case Status = New? Decision element.

Get the email recipient—Get Records
Since your decision outcome took the “Yes” path, meaning proceed with the notification, you must retrieve the information about your recipient. Remember that CMDT you created earlier? Now it’s time to use a Get Records element to pull that information into the flow. Another key advantage of this approach is that if your CSM ever changes jobs or leaves the company, you can quickly and easily update the custom metadata record and your flow will continue to run without any hiccups or modifications needed.

Configured Get Records to retrieve the CMDT routing recipient record.

Email the CSM—Action
Now that the recipient information is available, it’s time to build out the email notification for the unassigned case. Once again, you’ll use a text template to format the body of the email, but instead of using the HTML tags, this text template leverages the WYSIWYG rich text editor.

Configured text template to email the CSM.

This time, you’re only sending an email to one recipient, so instead of the Email Addresses (collection) option, use the Email Addresses (comma-separated) input. Since you also want this email body to render in rich text, you need to ensure both the Rich-Text-Formatted Body input is toggled on and the field is set to True using {!$GlobalConstant.True}. This flow uses the current user as the email sender, which is the default; however, options do exist to set this to either the Default Workflow User or an Org-Wide Email Address by completing the Sender Address and Sender Type fields.

Configured “Send Email” core action.

And that’s a wrap! With one record-triggered flow, you’re able to combine, streamline, and automate activities that facilitate communication between departments and ensure prompt customer service, resulting in increased customer satisfaction and retention!


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

Increase productivity and create starter flows fast with Einstein for Flow

Increase Productivity by Creating Starter Flows Fast Using Einstein for Flow | 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, learn how Eduardo Guzman enhanced productivity and […]

How I Created a Solution to Test Scheduled Flows Easier During UAT

How I Created a Solution to Test Scheduled Flows Easier During UAT | 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, let’s see how Nancy Brown created a […]