from Chris Emmett: A Great 1 Minute Intro to Loops
Probably destined for the Academy Award for 2020 for Best Flow Short. Check it out!

Probably destined for the Academy Award for 2020 for Best Flow Short. Check it out!

This Post was most recently updated on:ย 1/11/25
Key Contributors: Nick Sauer, Clifford in Frankfurt
1/11/25: Thanks to Jeroen, this component is now reactive
9/21/24: Thanks to Declan, you can get a more accurate count by excluding HTML
4/16/23: Thanks to Clifford in Frankfurt, this extension now fully supports the ability to enable or suppress specific formats
Input Rich Text sports a nice toolbar and allow rich text creation. It also provides Find and Replace, Autoreplace, and Blocklists. As you can see below, these new features are available via a swanky bottom toolbar, and can be turned on or off as a group. Clifford in Frankfurt has added additional ability to control which features are enabled or suppressed.
Note that this isn’t the only choice you have. Here’s a powerful alternative extension to consider, with a different mix of features.
You can pass in a map of terms that you want to automatically replace.
How it Works:

Use Case Example: Business has the need to enter customer-facing details that:
IMPORTANT: Use enabledAdvancedTools = true input attribute if you want to leverage these enhanced features. Otherwise leave empty and regular input Rich Text component will be used.
| Parameter | I | O | Information |
|---|---|---|---|
| enabledFormats | X | An optional comma-seperated list of allowed formats. By default, the list is computed based on enabled categories. Example: bold, image | |
| disabledCategories | X | An optional comma-separated list of button categories to remove from the toolbar. Example: INSERT_CONTENT, ALIGN_TEXT | |
| enableAdvancedTools | X | Boolean. Set to true if you want to use enhanced rich text. Default is false (regular input component) | |
| autoReplaceMap | X | JSON formatted key:value map. (example => {“Test”: “GreatTestโข”} ) | |
| disallowedSymbols | X | Comma-separated list of words to block. Example: /,@,* | |
| disallowedWords | X | Comma-separated list of words to block. Example: bad,worse,worst | |
| warnOnly | X | Boolean. Set to True if you want to allow Next even where disallowed Symbol or Word remains. Default is false. | |
| characterLimit | X | Integer. Set character limit. This will enable character count and limit, and if warnOnly is not true, then will block next. | |
| value | X | X | Input and output Rich Text that youโll be editing |
| label | X | X | Input to provide field-level label if desired |
| excludeHTMLCharacterCount | X | Set to True if you want to exclude HTML characters in the character count |
Component Input Example:

Installation:
1.7 Unlocked 1/11/25 Production Sandbox – Reactivity added
Resources:
Also see https://unofficialsf.com/copy-paste-of-images-in-flow/
Old Versions
1.6 Unlocked 9/21/24 Production Sandbox – Additional support for turning on formats
1.5 Unlocked 4/16/23 Production Sandbox – Additional support for turning on formats
1.4.1 Unlocked 7/3/21 (Production or Dev) 7/3/21 – Eric Smith – Added an * next to the Input Label when the Required attribute is True
1.4.1 Unlocked 6/3/21 (Sandbox)
1.4 Unlocked 6/25/21 (Production or Dev)
1.4 Unlocked 6/25/21 (Sandbox)
6/25/21 โ Eric Smith โ Added a Required attribute and adjusted the bottom margin to better match standard components
MetadataService is a subset of Andy Fawcett’s legendary Apex-Mdapi metadata service project, slimmed down and packaged to be useful to Flow Developers as a dependency.
If you’re using these metadata deployment and retrieval services in your own Flow Action or Screen Component, consider simply requiring that this package be installed as a prerequisite
Learn more here.
V1.0 Unmanaged 7/5/20
There are some powerful data structures that are currently available only through retrieval and deployment via the metadata API. For example, the Process Builder Converter tool works by first retrieving a process builder process as a piece of flow metadata, then editing the metadata so it can be opened in Flow Builder, and then deploying the modified flow metadata as a new, separate flow.
In general, using metadata deployment and retrieval is the last resort you should use. If your data is accessible via the UI API, the Tooling API, or via a REST interface, those are likely to be preferable. One reason is that metadata deployment may trigger a recompilation of all of the apex classes on your org, and that will pause your deployment until it’s finished. So while metadata deployment will generally go very quickly on developer edition orgs, it might be much slower on a production org. (As a note, you can control whether your metadata deployments trigger a recompilation with this checkbox:

Despite these issues, sometimes Metadata deployment is a great tool to use. The Process Builder example is a good one.
Another example involves creating, editing, and deleting ListViews via a Flow Action. While ListViews can be read via UI API and REST, they can only be created, edited, or deleted by doing metadata deployment of ListView metadata.
There are two sets of tools you can use to build Flow Actions and Screen Components that use Metadata Deployment and Retrieval.
The first tool is the legendary Apex Metadata Service created by Andy Fawcett. This abstracts a lot of gnarly SOAP transactions into nice clean API’s. Here’s an example of a Flow Action making use of the Metadata Service to create ListViews:

The reason this works is that MetadataService has gone and created a wrapper class for each piece of Salesforce metadata. In the code above, you can see that we’re able to reference MetadataService.ListView(). Once we have one of the ListView objects, we can simply fill it with updated values, and then call createMetadata on it. There are similar methods for updating, deleting and reading.
You can peruse the vast set of available objects by scrolling through the main class file here.
When we went to create the process builder converter, though, we weren’t able to use the above method. The reason is that the current MetadataService only has updated metadata through API version 42, from 2017. We needed to create flow metadata that used brand new additions that had only been added in version 48.0
You can see here, that the Flow definition in Metadata Service (era 2017)…

lacks the brand new metadata element that stores new Flow triggering information:

Hopefully, someone will update the MetadataService to the latest API. In the meantime, you can solve this problem because the MetadataService also provides direct access to lower level deploy and retrieve methods that don’t require you to populate one of the metadata objects.

When you operate at this lower level, you have to directly parse and modify the metadata xml. Then you have to zip it up with base 64 encoding, and then you call MetadataService’s ‘deploy’ method directly. This has been implemented asynchronously, so we carry it out via a Flow screen component called TransferMetadata that can sit there on a flow screen and poll until a response is received.
While this may sound a little intimidating, you can just take and copy the code we used.
To streamline the efforts of developers who want to build tools like Create or Edit ListViews, we’ve packaged the necessary MetadataService files into a useful package that you can just require as a dependency. This package leaves out some extraneous files from the repo but has everything necessary to carry out deployment and retrieval.
In general we’re starting to move towards base libraries to avoid collisions and simplify packaging for new actions and developments.
Install it here.
Use UpsertRecords when you want to take a collection that may or may not already exist in the database and save it. If the records in the collection have valid Id values, the corresponding records in the database will be updated with the flow’s collection. If not, new records will be created and saved.
UpsertRecords provides functionality similar to the Apex ‘upsert‘ command. You can optionally provide the name of a field on your object that is the externalId and you can specify that you want partial saving to work even if some of the saves fail (‘all or none’).
This functionality is available in the CollectionActions package starting with version 1.19.2
You can provide either a collection or an individual record (and in fact can provide both), but because of a limitation in the action configuration framework, you have to specify both types, even if you’re only using one, like this:

| Attribute | Type |
| inputCollection | List<SObject> |
| inputRecord | SObject |
| externalIdFieldName | String |
| allOrNone | Boolean |
This action currently has an output called ‘placeholder’ that should just be ignored. If an error occurs during the upsert, the error message will be thrown back to the flow
Install the Collection Actions package, starting with 1.19.2
June was a big month for Flow demo videos. First we had Summer ’20 Release Readiness Live, with special cameos by my mother-in-law’s dog, a baby, and a dubious plant.
A week later, at TrailheaDX, another Flow presentation was given. This one included a sneak preview of two upcoming blockbuster features: Multicolumn Screens and Autolayout Canvas.
Check it out!
Setup and Installation steps (View Part 1 for demo video and details on the building blocks)
STEP 1: Install package
OR
STEP 2: Setup the environment
STEP 3: Create Users of the app.
STEP 4: Assign permissions
STEP 5: Add Data to custom objects
| Name | Description | Action Reference | Acceptance Label | Rejection Label | ||
| 1 | Priority Message: Tax Day | Tax day is in 6 weeks! Get more detail. | Tax_Flow | Accept | Reject | |
| 2 | Priority Message: Well Being Survey | Our records indicate that you have not taken the Well Being Survey. Please take a few minutes to complete it. | Well_Being_Survey_Flow | Accept | Reject | |
| 3 | Work.com Contact Risk Alert | Alert! You have recently come in contact with someone who has tested positive for COVID -19. Please contact the health center for more details. | Contact_Risk | Accept | Reject | |
| 4 | Return to Work Shift Days | Shift_Flow | Accept | Reject | ||
| 5 | Training Recommendation | Your manager has identified that you will benefit from the Great Salesforce Leaders training. Click to enroll. | Enrollment_Flow | Accept | Reject |
STEP 6: Set up the flow component to accept input for which messages and their respective priorities to be surfaced on the NBS Component

Drag a flow component.Choose the manage tactical plan. activate it for the org default
Also set component visibility , add filter, Save and Activate.
[If the following error message displays then do this additional step below]
This step maybe required on a non-scratch org - go to Setup - My Domain โRegister a domain โLogin โDeploy to users.
Once done go back to UserProfile
Order priorities(these are passed in from the flow) - these are all messages that are available. Once ordered - it gets saved on the EmployeeDailyTacticalPlan record as shown below
STEP 7: Set up the NBA component (This is another flow component with a custom LWC -NOT THE STANDARD NBA COMPONENT)
We use a custom component here to show the modularity of the strategy builder. This demo can also be built with the standard NBA component and that is not covered here.

Set component visibility so it is viewed by the second user
STEP 8: Login and test the component


Employee experience is the new HR superpower. Customer experience is no longer only for customers, with the Salesforce Platform you can not only seamlessly create amazing digital experiences for employees but also deliver them personalized and optimized. Especially in light of the new โwork anywhereโ normal that fused home and work life, digital employee experience plays a key role in not just productivity but also employee motivation.
On this employee experienced focussed app, Einstein NBA can be leveraged to deliver
and much more. Powered with the insights from Einstein prediction builder – NBA combines data, business rules and AI to provide relevant and real time individualized recommendations.
Note: Prediction builder is not integrated in the app below but simulated with prediction scores.
This app also showcases how Lightning flows can be used in conjunction with Next Best Action. There are numerous applications of how flow and NBA can be integrated into apps for powerful outcomes such as the one in this example. The example also shows a custom LWC component to display Recommendations and not the standard display component -this illustrates the modularity of the strategy builder and how it can be used with a custom component because it is exposed as a service.
This sample application uses a sophisticated pattern to provide team managers with a simple flow that they can use for prioritization, while enabling IT to add or subtract recommendation tactics behind the scenes. This is a powerful way to address the desire of customers to mix backend power with business user configuration.
The individual tactics are modeled as Apex classes. The same example can be extended for several use cases of how system integrators can use Next Best Action to provide increased value by making use of Apex to create tooling that team managers can use to cater to the specific use case.
(View setup and installation steps in Part-2 of the blog)




