Advanced NBA: Using Apex Actions to Empower Team Manager to Set Team Priorities via Next Best Action Recommendations

Next Best Action enables you to provide agents, salespeople, and other employees with a customized list of prioritized recommendations every morning. In this sample app, which can be installed as a package, prioritization of tactics is managed by service team leaders, who can establish and change the priorities freely without the involvement of admins.

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.

The individual tactics are modeled as Apex classes. The use of Apex to create tooling that team managers can use makes this a compelling example of how system integrators can use Next Best Action to provide increased value.

Install Package

Unmanaged 1.0

New Intro to NBA Video – Force501

Nice intro video from Force501

Dreamforce Slides – Put Predictions into Action: Einstein Prediction Builder and Next Best Action

These are the slides Einstein and Next Best Action product managers presented at this admin track session. The video recording will be published officially by Salesforce in the next 1-2 months.

The session synosis was: Join us in this session to learn how you can harness the power of both Einstein Prediction Builder and Einstein Next Best Action to produce intelligent predictions and actionable recommendations to your end users that are powered by Einstein! You’ll also hear from Einstein Product Management on how you can get started with these products and what’s coming in the roadmap. Don’t miss it!


Did you present at Dreamforce? If so, you’re encouraged to create a post like this, which you can link back to your own site/blog/company. If you need an account on this site to blog, contact a site admin or use the feedback form on the home page.

Dreamforce Slides – Enterprise Application Development With Flow and Next Best Action

These are the slides I presented for this developer track session. Here’s the video.

The session synosis was: As a developer, you can leverage Flow and Next Best Action to multiply the impact of your code. Learn how you can turn your work into declarative building blocks, and how you can delegate management and configuration not just to your organization’s admins, but out into the business units themselves. See state-of-the-art sample apps featuring invocable actions, and get a preview of developer-oriented automation tools coming in 2020.


Did you present at Dreamforce? If so, you’re encouraged to create a post like this, which you can link back to your own site/blog/company. If you need an account on this site to blog, contact a site admin or use the feedback form on the home page.

Execute an NBA strategy and Display the Results in a Custom Recommendation Component

We’ve previously shown how you can take the official, out-of-the-box Next Best Action component and surface it in a Flow screen, where it will show recommendations. We wanted to support some additional use cases, though, so we’ve built a toolkit for complete customization of the Next Best Action presentation experience.

This solution consists of two parts:

  • A Flow Action that sends an execution request to the Next Best Action engine and receives back a list of recommendations
  • An open-source LWC Next Best Action display component that can be easily customized.

The Execute Strategy Flow Action lets you specify a strategy, a recordId, and the maximum number of results you want, and returns recommendations in the same data structure that the Apex api endpoint uses. You can take these recommendations and process them with your Flow. You can also pass them “as is” to the included Next Best Action “Compact” display component, which expects the same data structure.

The Compact NBA component is something of a test bed for features that Salesforce is considering for the main Next Best Action component. It has the following features:

  1. Works in flow screens unmodified
  2. Packs more recommendations into less space
  3. Supports multiple screens of recommendations (up to 25)
  4. When a recommendation is responded to, it disappears, and any recommendations that are ‘behind’ it slide up.
  5. Open-source. You can modify it easily to meet your custom needs

The Compact NBA component reports all reactions to the Recommendation Reaction endpoint for reporting. It does not support images or Community Cloud pages.


ExecuteStrategy Flow Action

maxResultsup to 25. Default is 4


Input Parameters

<property name=”displayDescription” label=”Display Description” type=”Boolean” default=”false” role=”inputOnly”></property>        <property name=”displayTitle” label=”Display Title” type=”Boolean” default=”true” role=”inputOnly”></property>        <property name=”recordId” label=”Record Id” type=”String” role=”inputOnly”></property>        <property name=”strategyName” label=”Strategy Name” type=”String” role=”inputOnly”></property>        <property name=”displayMode” label=”Display Mode” type=”String” datasource=”ShowAll, ShowPages” default=”ShowAll” role=”inputOnly”></property>        <property name=”maxRecommendations” label=”Max Recommendations” type=”Integer” default=”25″ role=”inputOnly”></property>        <property name=”recommendations” label=”Recommendations” type=”apex://NBARecommendationsList” role=”inputOnly”></property>

For more information on the use of Apex-Defined data like the recommendation attribute, see this.

For another variation on incorporating NBA Recommendations into Flow, check out this post on how you can include the standard Out Of The Box NBA component in Flow screens.

This solution has not yet been packaged, but the classes and LWC’s are available here:

Next Best Action Recommendations Component Available for Flow Screens

The Next Best Action component is available for use in Flow Screens.

Learn more here.

Additional tools for incorporating NBA Recommendations into Flow, including open-source components that can be customized.

How To: Use the Map Element in the Strategy Builder

We discussed examples of how to use the Generate and Enhance elements in a previous post. With the Map element, you can modify existing Recommendation fields and create new fields that can be passed to Flow as input variables. In this post, we’ll take a closer look at the Map element. Like Generate and Enhance, the output is always a list of recommendations, however, unlike the other two elements, Map doesn’t require you to write any Apex code and relies instead on expressions and formulas.

Use Case 1: Modify Existing Recommendation Fields with Expressions

Suppose you have a Recommendation with the Description, “Thank you for being a loyal customer. We truly appreciate your business!” Now, with the Map element, you can personalize this Description by appending the name of the contact. For example, “Lauren Boyle, Thank you for being a loyal customer. We truly appreciate your business!” You can use this concept to make a variety of easy enhancements using the full power of the Salesforce formula operators and functions.

To do so, first add a Load element to the canvas and load all of the recommendations you want to change (you could also choose to add a Generate element and pass in dynamically generated recommendations). Then, add the Map element to the canvas. In the Map Values to Fields section, set the Description field to be $Record.Contact.Name+ “, ” + Description.

Make sure the Map element (Personalized Thank You) is placed after the Load element. It will transform the Descriptions of all recommendations flowing into it.

When you execute the strategy, your recommendations will look like the image on the right and include the contact name for the current case.

Use Case 2: Create New Fields That Can Be Passed as Inputs to Flow as Input Variables

The Einstein Next Best Action Lightning Component passes two default variables to all Flows – contextRecordId and recommendationId. In the Flow, you can do a Get Records and retrieve the current record on which the strategy is displayed (e.g. Case or Account) or the accepted recommendation. See this post for detailed instructions. With the Map element, you can create new “virtual” fields and pass them to the flow as input variables, in addition to the default ones. This scenario is most useful when you’re working with dynamically created recommendations and want to pass some context to the Flow. Bear in mind that in the case of dynamic recommendations, there is no recommendationId to pass to the Flow.

For example, let’s suppose you create a strategy that generates a set of accounts that you should connect with because the last contact was more than 90 days ago. Check out our Integration Guide for instructions on how to build such a strategy. When the recommendation is accepted, you want to launch a flow that references the selected account. Thus, you want to pass the Account Id to the Flow.

First, make a small tweak to the Recommendation object and add a text field called AccountId__c. Second, in the Apex action responsible for generating recommendations, set the AccountId__c with the ID of the generated account: AccountId__c = account.Id. The modified class would look like the following.

global class Generate_GetAccountsToFollowUp { 
    @InvocableMethod(label='Accounts to Follow Up Today' 
                     description='Recommend accounts the current user should follow up on today')
    global static List<List<Recommendation>> getAccounts(List<String> inputData){
        List<List<Recommendation>> outputs = new List<List<Recommendation>>();
        Integer daysSinceLastContact;
         Account[] accounts = [SELECT Name, Description, LastContactDate__c, OwnerId FROM Account WHERE OwnerId = :inputData[0]];
        List<Recommendation> recs = new List<Recommendation>(); 
        for (Account account:accounts) {
            if (account.LastContactDate__c != null){
                daysSinceLastContact = account.LastContactDate__c.daysBetween(;
                if (daysSinceLastContact > 30){
                    Recommendation rec = new Recommendation(
                        Name = account.Name,
                        Description = 'Connect with the ' + account.Name + ' account, the last interaction was '+ daysSinceLastContact + ' days ago.',
                        ActionReference = 'accountOutreach',
                        AcceptanceLabel = 'View',
                        AccountId__c = account.Id
        return outputs; 

Third, in the accountOutreach flow, create a text variable, called “accountId,” and mark it as “Available for input.”

Next, add a Map element after the Generate element.

Finally, in the Map element, create a text variable called accountId and set it to be AccountId__c. The variable name MUST match the name of the flow input variable.

The dynamically generated account Id will now be passed as an input variable to the Flow (accountId) and can be referenced to do things like Get Account details.

For example, send an email to each account.