Flow Use Case – New Task Button with picklist for selecting the record type

When our org migrated to Lightning, we were faced with an interesting issue: we had many task record types and in order to enable our end users to create tasks from the activity composer, we had to create a different quick action for each task record type. The result wasn’t pretty

Too many tabs

Our users wanted a simple button where they could create a task with one click and be able to select the task record type.
When I set out to build the solution, I started by using a Get Records element to query the record type object but soon realized that I can’t filter this list based on the record types available to the current user.

I was able to provide a nice solution using the new invocable action and quickChoice component found here on this site. I used the Get Record Type Info by Object action to generate a list of record types available to the current user. Then I fed the record type labels and Ids into the Quick Choice component. Finally I created the task and used the Navigate to Record action to open the new task in edit mode.

Get the available record types
You need to check this box to store the output value
The new task Id is fed into this action
And this is the completed flow
Here is the end user experience

Preventing duplicate junction object records by GORAV SETH

GORAV SETH demonstrates how you can use the new flow before save trigger combined with duplicate rules to prevent creation of duplicate junction object records.
Check it out

Chris Van Der Merwe: Work with Business Hours via New Flow Actions

Chris has written the first of a promised series of actions that allow easy declarative, automated manipulation of Business Hours information.

Check it out!

Using Serialization with Flow to Store Session Data and Enable Custom Resume

There are several techniques that can be applied to let users pause a flow and resume it. The simplest technique is to enable the Pause button in each of the flow’s screens, and then give the user access to the Paused Flows lightning component, from where they can resume. However, this is not always workable. It doesn’t work, for example, for guest users running the Flow via Community Cloud, and there is often not a good place to put the Paused Flow component where it can be easily found without being in the way.

Another approach is to use Salesforce Surveys, which runs on the Flow engine.

A third way of dealing with this scenario is to add actions to the flow that store and retrieve the values users enter after each screen. If the user loses connectivity, or quits, they can return later and the values they had previously entered will be loaded into the appropriate screen fields.

There are a lot of ways to do this, with varying degrees of complexity, but they share in common a core concept: A custom object that represents an individual flow session. The different values that the user enters are serialized into a single big string that gets stored in a flow session record.


We have a flow called Health Survey. To enable custom resume, we have defined a custom object called Flow_Session__c. This object has two important fields: SessionData, which stores all the values that the user has entered, and SessionToken, which makes it possible for the record to be matched to the user when they return.

In our Health Survey flow, the user is first shown to Screen 1, where they fill in a variety of fields and then click Next. Here we have a design decision: do we want to update the HealthSurveySession record every time the user clicks next? Or do we want the updating to only happen when the user clicks a Save or Pause button? Either way will work. Let’s assume that we’re going to autosave the user’s date each time they click Next.

That means that we’ll need to extract the form data provided by the user in Screen 1, and save it to our HealthSurveySession record.

Storing and Retrieving Answer Data

Take a look at this version of our flow, which supports a single screen of input data:

After each screen, the flow has a Serialize Health Data action that takes all of the fields that the user has been able to edit so far in the flow, serializes their values (serializing means taking an object and converting it into a string) and returning the serialized string. After each step, the Flow Session can be saved with this latest version of the session data.

Before each screen, there’s a Deserialize Health Data action that loads in the string from the current Flow Session (if one exists), and converts it into a HealthSurveySessionData object. This object is then used to map values into the screen. In this way, the values from the previous session get loaded in as defaults when the screen renders:

Where does this useful but focused object come from? It’s defined in Apex as a class and accessed in Flow using Apex-Defined Types.

Here’s what the class looks like:

As you can see, this class doesn’t do anything at all. It’s just a data structure. It’s the Apex equivalent of defining a Custom Object and adding a bunch of Custom Fields.

Let’s go back to our Flow Session. Here’s what one looks like after a user has filled in a screen:

The data that we need to reload into the screen is all there in Session Data. The deserialization process is extremely simple:

Notice how the output of this action is a HealthSurveySessionData object. That’s what gets fed to the inputs of the flow screen. The actual deserialization is carried out with a single line of Apex.

As fields are added to the Flow over time, the HealthSurveySessionData class will need to be updated. However, the two actions will not need modification.

Install Package

This package installs the classes and demo flow described above.

Unmanaged 1.0

Wiki Resources

David Entremont: Increase Your Limits with the “Save Records Later” Action (Queueable Apex)

David Entremont has built a collection processor (a flow action designed to accept a collection of any type) that taps into Queueable Apex. If you use this to save your collection instead of Update Records or Create Records, it will be batched as a job to be run in the background. You can’t count on exactly when the save will complete, and this action returns a jobID that can be used to queue for status.

Why use this instead of standard data elements? Well, background jobs have more lenient limits. Here’s the best descriptions I’ve seen:

One of the main benefits of running asynchronous Apex is higher governor and execution limits. For example, the number of SOQL queries is doubled from 100 to 200 queries when using asynchronous calls. The total heap size and maximum CPU time are similarly larger for asynchronous calls.

Not only do you get higher limits with async, but also those governor limits are independent of the limits in the synchronous request that queued the async request initially. That’s a mouthful, but essentially, you have two separate Apex invocations, and more than double the processing capability. This comes in handy for instances when you want to do as much processing as you can in the current transaction but when you start to get close to governor limits, continue asynchronously.


You can learn more here:




Install V0.1 Unmanaged (REQUIRES SPRING ’20)

View Source


Using Before-Save Flow and a Validation Rule to Prevent a Record Creation/Update based on its Sibling Records’​ data

Salesforce Spring ’20 Release brings us a powerful enhancement – Flow Builder before-save updates.

In the following article, Gidi Abramovich demonstrates how to use this feature to prevent users from creating/updating a record, based on its sibling records’ data.

Check It Out

Extend Formula-building to Non-Admins with Formula Builder, Expression Builder and the ‘Evaluate Formula’ Action


You can use formulas in both Flow….

and Process Builder:

But these tools only are available to admins building flows and processes. Recently we’ve been tinkering with rich flow-based applications where we wanted to let users who are running flows create formulas and see them put to use. These use cases tend to involve flows that automate or improve on various pieces of Salesforce administration. For example, we’re prototyping an approval process that’s based on flow. In the classic Salesforce Approval Processes feature, you can specify the Entry Criteria for an Approval Process with a formula:

In the Flow-based approach to approval processes, it’s in a flow where this entry criteria formula gets entered:

The Formula Builder component visible above outputs a single formula string that can be stored for later use (in this case, to be used each time a record is submitted for approval). At that later point, in a separate flow, the string is passed to an Evaluate Formula invocable action that processes the formula string and returns a result.

Deep Dive Video


This package provides a set of tools that provide graphical formula and expression creation as LWC’s and also provides a portable, Apex-based formula engine. This package is optimized for use in Flow but these LWC’s can be useful across a range of Lightning applications.

This package includes three main elements:

FormulaBuilder LWC

ExpressionBuilder LWC

Evaluate Formula invocable Action

There are also some demo flows you can use.

Formula Builder

Add the Formula Builder to Flow screens and store the resulting formula string for later evaluation by the Evaluate Formula invocable action.

In the Approvals example shown above, the formula is being defined as part of a flow that creates the approval definition. The formula string is stored as one of the pieces of the definition as a string in a normal record. Later, when an object is submitted for approval, a separate flow is triggered. That flow loads the appropriate Approval Process Definition record, extracts the formula string from its field, and passes it to an invocable action called Evaluate Formula. This action takes as its input a formula string (such as the one defined above) and two optional attributes:

Attributes supported on the formulaBuilder LWC

formulaValueThe formula string
contextObjectTypeStandard or custom object API name. Fields from this object will be displayed in the Fields picklist of the formula builder, and at save time, the field references will be saved as part of the formula string. For example, if this is “Quote”, then user will be able to select from Quote object fields in the Insert Field picklist, and insert (or type) values like “Quote.Value”.

When Evaluate Formula invocable action evaluates a string, it will look for a passed-in recordId value and use that to replace tokens like Quote.Value with the appropriate runtime value. The solution currently supports a single contextObjectType.
supportedSystemTypesSpecify in a comma separated list the names of the system variables you want users to also be able to use in the formula. Values supported by the Evaluate Formula action at this time are User, Organization, Profile, Setup. The formula builder will add these to the Insert Field picklist and allow the insertion of tokens like $User.userid. Evaluate Formula will use the context of the running user to replace these tokens with appropriate values.

Supported Functions

Currently, the Formula Builder and Formula Evaluator support the following functions:


Supported System Variables

The following System Variables are supported, along with all of their fields:

$Record (note that tokens using $Record will look for a context input labeled ‘recordId’ and use that record)

If you need a function or variable that’s not here, feel free to leave a comment proposing it. And if you can write Apex code, feel free to add it to the code yourself!

Supported Operators

The following Operators are supported:  [‘+’, ‘-‘, ‘/’, ‘*’, ‘==’, ‘!=’, ‘>’, ‘<‘, ‘>=’, ‘<=’, ‘<>’];

You can use the EvaluateFormula action independently of the Formula Builder (and independently of Flow). It should be able to handle any formula that Salesforce understands if you use supported functions from the list above.

Expression Builder LWC

This package also includes a graphical LWC-based Expression Builder:

The expression builder also outputs a single formula string, so it too can be evaluated at runtime by the same Evaluate Formula invocable action. Unlike formulas generated by the Formula Builder, formulas generated from Expression Builder only return true or false.


formulaValueThe formula string that the expression builder inputs and outputs
contextObjectTypeStandard or custom object API name, determines set of fields which user will be able to choose from ‘Insert Field’ picklist
supportedSystemTypesSpecify in a comma separated list the names of the system variables you want users to also be able to use in the formula. Values supported by the Evaluate Formula action at this time are User, Organization, Profile, Setup. The ‘cost’ of adding more of these to your instance might be felt in either or both of 1) the time it takes to populate the Insert Field picklist at init time and 2) the handiness of negotiating a large picklist with many values.
customMergeFieldsAllows the specification of a specific set of mergefields. See ‘Specifying CustomMergeFields’ below


Does not currently support quote marks

Only the following dataTypes are currently supported:

“Evaluate Formula” Invocable Action

To make use of the formula strings generated by the Formula Builder and the Expression Builder pass them to the Evaluate Formula action in a Flow. This demo flow shows the output from a Formula Builder getting handed to the Evaluate Formula action, which will output a calculated result:

This image has an empty alt attribute; its file name is image-53.png

Note that in real use cases, the formula builder and the Evaluate Formula action will be in separate Flows. One will be run at configuration time, and one will run later, perhaps when triggered by an event.

This action is based around the Apex Formula Engine built by Enrico Murru.

This action takes the following inputs:

StringformulaString (required)
StringrecordId (optional)

It evaluates the formula, pulling data where appropriate from the record that you pass in, and also calculating the values of any global variables in the formula string. It evaluates any of the supported functions and comes up with a final result. The result is returned in one or both of these outputs:


If the formula has any strings that begin with the name of the object type of the passed in recordId, the action will lookup the record whose Id has been passed in and use the appropriate values. There is no support currently to pass in upstream Flow variables/mergefields.

How Formula Evaluation Works

Evaluation of formulas takes part in two steps. In the first step (Token Replacement), any tokens in the formula are replaced by the value of what they’re pointing to. Then the resulting formula string is passed to the formula engine for calculation (Value Calculation).

Token Replacement

Here are the supported tokens:

Token TypeReplacement Process
References to SObject fields, like Quote.AmountIf the first word in the string matches an existing SObject type name, look for a ‘recordId’ value in the provided context data, look up that record, access the appropriate field data and substitute it into the formula
References to system variables like $User.usernameIf it’s a supported system variable, query for the appropriate field data.

Supported formula functions like “AND” and “ABS” are not changed during this first step.

Value Calculation

In the second step, the now-tokenless formula string is passed to the core formula evaluator, which evaluates the formula and returns an appropriate value. For convenience, the action comes with a string output and a number output, and it will try to set either or both of them if there are legitimate values. Here are the three supported cases:

A StringExample Formula “Alex” + “Flow”Returns “AlexFlow”
A NumberExample Formula “32.1 + (2/1)”Returns 34.1 and “34.1”
A BooleanExample Formula “43000 > 23”Returns “true”

The Formula Evaluator is implemented as a set of Apex classes and can be called invocably via runtimes that support invocable actions, which currently includes Flow, Process Builder, Einstein Bots, and Einstein Next Best Action. It has support for many functions and operators (see below for the full list). The evaluator was created by Salesforce MVP Enrico Muru. Support for context data was added by two excellent freelance developers: Andrii Kraiev and Aleksander Antonyuk.

Demo Flow 1: Simple Formula Create and Evalute

Test Formula Builder and Evaluate Formula by running this flow, which is included in the package:

Note that the formula builder in the Enter Formula screen is configured to use Account as the context object type. As a result, when you run this flow, you’ll be able to select from Account fields for inclusion in the formula builder:

In this demo flow, the output of the Formula Builder is passed directly to the Evaluate Formula invocable action (this isn’t likely how you’ll really use your formula strings). Note that you need to pass a specific Account recordId into this flow if you want any Account references to be properly resolved. However, you can enter simple formulas like: 5 + 7 or LEFT(“foobar”, 3) and see them immediately evaluated.

July 2020 updates:

Added new expression builder attribute customMergeFields:
This attribute is used to hold developer-defined values, it accepts the following structure:
label(String): Label
value(String): Value
dataType(String, supported values: "DOUBLE,DATETIME,STRING"): determines the type of the value
renderAs(String, supported values: "number,datetime,date,text") : determines input type, which will be rendered to enter the value

For example if you need to let the user to create an expression, where you would only allow choosing three attributes/values, will look like this:

label: "Record Name",
value: "Name",
dataType: "STRING",
renderAs: "text"
label: "Revenue",
value: "Revenue",
dataType: "DOUBLE",
renderAs: "number",
label: "Close Date",
value: "CloseDate",
dataType: "DATETIME",
renderAs: "date"

This will render the following in the field selection combo box:

And completed component with all values set may look like this:

dataType controls the data conversion that happens when expressions are converted to formulas, this is why it is important to pass in the proper type. dataType may be different from renderAs, the possible use case is when the developer does not want to render the date picker to set the date field, so if dataType = date, and valueType = text, this will render string input for setting the date field, instead of date picker.
NOTE: as all these values are added to the lightning-combobox component where it is prohibited to have two identical values, the developer must guarantee that all values are unique for the whole data set.


Version 1.0 Unmanaged 5/11/20

View Source

Jen Lee: Building Modularity and Reuse into Flows, Permission Set Actions, and More

Video is up from Jen’s recent presentation at Cactusforce. I love how real her examples are. You can learn a lot of best practices from studying her Flows.