Summer ’19 Flow Sneak Preview

Here’s a sneak peak at some of the things you’ll be able to start playing with in a couple of weeks (either via a new pre-release org or an early sandbox upgrade).

Keep in mind our forward-looking statement. Please make your purchase decisions based only on generally available product functionality.


The Flow Builder gets Undo, Redo, and Duplicate. As well it should.


You can find elements quickly. (We’d be very proud of this one if Cloud Flow Designer didn’t already have it.)


Rich Text is back. in black. and red. and bold. (Boy, we’re funny)

We added an image button that uploads and inserts images too.

There are a couple of limitations to be aware of:

  • The added images get created into the org as ContentVersion metadata, but can’t really be packaged with the flow because ContentVersion use id’s that are specific to an org. It will take more work to figure out a solution for that.
  • At the last minute we had to disable rich text in Text Templates because we need to do some more work to make sure the rich text you create doesn’t spew html into downstream plain text fields like the email body in the Send Email flow action. We’ll have that working next release.

The “New Flow” button now generates a New Flow dialog box that provides access to flow templates.

Watch for special flow template announcements at TrailheaDX in May.


The new Automation Home page

We have big plans for the metrics and tools we intend to make available from this new page.


Flow Support for Rich Web Objects (JSON)

Our most complex and powerful feature in Summer ’19 allows incoming JSON to be converted to rich objects that can be used declaratively in Flow.

Read the deep-dive post on rich web object support.


Actions have categories to make them easier to manage in large numbers.

We haven’t enabled custom actions to be tagged with categories yet, but that’s in the works.


Additional Enhancements

  • With the new $Flow.InterviewStartTime system variable, you can use the start time of the flow interview in Decision elements, formula resources, and elsewhere in the flow.
  • Dependent Picklist component can be set to Required.
  • Custom Metadata Type Records can be used in Process Builder
  • New Build Flows with Flow Builder trail at Trailhead.
  • Flow names and properties are now available via REST (This is useful for doing things like putting a picklist of flow names on a flow screen to let a user pick which flow to go to next). previously you had to use the metadata retrieve process)

Advanced Flow Navigation Button from GravityLab

Dan Howell and GravityLab have made available an advanced Flow Navigation Button with no fewer than 12 built-in features, including:

  1. Add bespoke navigation options in a flow. For example, replace the “Next” button with a “Save and View” button.
  2. Launch new record or edit page. For example, launch the create new account page with a specific record type.
  3. Auto launch a quick action. For example, automatically launch the new opportunity quick action when an account with the type “prospect” is created.
  4. Navigate to another page. For example, auto navigate to another record page when a certain status is reached.

Documentation and Installation

Part 1: Manipulate Complex Internet Data in Flow Without Code

Watch Intro Video

In Summer ’19, Flow gains the ability to manipulate the kinds of complex data objects that are typically returned from calls to web services. Using Apex Actions and External Service Registrations, Flow was already able to work with web data, but it had to be in the form of simple ‘primitives’ like strings and numbers. The problem with that is that data from the web and enterprise data retrieved via integration solutions like Mulesoft rarely is composed of nothing but primitives. Consider these snapshots of web data:

This Product data structure includes three different URLs and three different SKU numbers corresponding to the different sizes of the Product. Traditionally, you’d have to manipulate these data structures in code (or carry out transforms in Mulesoft’s developer-oriented Application environment). Flow’s new functionality provides a new option that requires no code, expanding the range of people that can work with these rich objects.

To demonstrate this, we’re going to build a Flow that takes that complex Mulesoft product data and breaks it up into three separate Salesforce product records.

Setting Up: Creating Mulesoft Actions in Flow

For our particular example, we’ll start with a Mulesoft endpoint that produces this JSON:

 
{
  "identifier": "1295527d-d3c7-11e7-9c84-06bf056d193e",
  "identifiers": [
    {
      "SKU": "LN-2230"
    },
    {
      "SKU": "LN-2232"
    },
    {
      "SKU": "LN-2231"
    }
  ],
  "price": {
    "amount": {
      "currencyValue": "24.00",
      "name": "Amount",
      "currency": "USD"
    },
    "salesUnit": {
      "code": "EA",
      "name": "Each"
    }
  },
  "description": "Lion Mane costume hat for cats and dogs SMALL: Best fits slim cats and kittens. Neck circumference 22-26cm LARGE: Best fits most cats or small dogs. Neck circumference up to 35cm",
  "model": "Lion Mane Costume",
  "brand": "SmartPets",
  "pictures": [
    "https://s3-us-west-1.amazonaws.com/mulesoft/catmane-S.jpg",
    "https://s3-us-west-1.amazonaws.com/mulesoft/catmane-L.jpg",
    "https://s3-us-west-1.amazonaws.com/mulesoft/catmane-M.jpg"
  ]
}

This data is returned by a Mulesoft application that you create by following the Mulesoft Quick Start. However, you can use one that I set up already. To test your connectivity out, open a terminal program and run:

curl -X GET
http://congosample.us-e2.cloudhub.io/api/products/1295527d-d3c7-11e7-9c84-06bf056d193e

If things are running correctly, you should get back the JSON shown above.

However, we want to access this data inside of Salesforce and inside Flow in particular. The first thing we’re going to do shows how this is done before now. I’m going to create an Apex Class that calls this same URL.

This class defines an Invocable Action by making use of the @InvocableMethod annotation. It also uses the Requests & Results pattern that’s described here. You can get an introduction to Invocable Actions here.

If we go to Flow, we can now easily find that action by dragging the Action element onto the screen and searching for it by name (Note the new Summer ’19 simplified palette).

Getting The Data To Salesforce From The Web

The basic way to get data from the web into Salesforce is via an Apex class. Notice that this class parses the response JSON into an Apex object called a WebProduct:

global with sharing  class GetWebProductViaMulesoft {
 
    @InvocableMethod
    public static List<Results> GetWebProductViaMulesoft(List<Requests> requests)
       {
            Http http = new Http();
            HttpRequest request = new HttpRequest();
            String endpoint = requests[0].endpoint;
            String submittedId = requests[0].submittedId;
            System.debug('url is: ' + endpoint + submittedId);
            request.setEndpoint(endpoint + submittedId );
            request.setMethod('GET');
            HttpResponse response = http.send(request);
           
            Results curResult = new Results();
            String responseJSON = response.getBody();
           
            //this particular Mulesoft endpoint returns json that includes as a keyword 'currency',
            //which is a disallowed reserved word in apex. So we need to transform it to something else before we can parse it
            responseJSON = responseJSON.replace('currency"', 'currencyType"');
           
            WebProduct curProduct = WebProduct.parse(responseJSON);        
            curResult.WebProduct = curProduct;
           
            List<Results> resultsList = new List<Results>();
            resultsList.add(curResult);
            return resultsList;
       }
    
    global class Requests {
        @InvocableVariable
        global String submittedId;
        
        @InvocableVariable
        global String endpoint;       
    }
    
    global class Results {
        @InvocableVariable
        global WebProduct product;
    }

}

Where did WebProduct come from? We created it by converting the JSON into Apex. To use rich web data in flow, you take the initial json and create an Apex representation of it:

Taking the JSON response from above and pasting it into the excellent tool at JSON2Apex, we get the following Apex:

Our GetWebProductViaMulesoft Apex class can get a rich web object from Mulesoft, turn it into Apex objects and work with it in code. Since we want to go farther and work with it Flow, we need to do 2 pieces of post-processing:

  1. Add the @AuraEnabled annotation to each property that we want to be present in Flow.
  2. Move each of the inner classes, such as Identifiers and Amount, into their own files.

Once this is done, we end up with five individual small class files like this:

By doing this work once, you subsequently can create many different Flows that work with this incoming data.

We’re setup to work with this endpoint via Flow. We’ll do that in Part 2.

Part 2: Manipulate Complex Internet Data in Flow Without Code

Working with Rich Web Data in Flow

Review Part 1

Let’s recall the problem we’re trying to solve. The web data that’s returned by our Mulesoft product API packs three different SKU’s into a single ‘WebProduct’. Every time we get a result from this API, we need to unpack it and create multiple Product records in Salesforce:

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

Here’s the flow we’ll use:

The two Extract assignment elements are extremely important: they take the two Lists that are part of the product and store them in variables. But we handle them slightly differently. Recall that this is what the object looks like:

Because the picture URLS are simple strings:


we can create a standard collection variable of type Text to store them as a group:

But the identifiers are more complicated:

so we store them in a resource that uses the new Apex-Defined type:

Here’s how we configure one of the resources we’ll use:

Note how you select the specific Apex Class that indicates the structure of the data you’ll be storing.

Extracting Subobjects

An important part of the process is extracting copies of the subobjects (in our case it’s the SKU identifiers and the URL Product Images) into record collection variables that use the new Apex-Defined type. Once the data is in record collection variables, we can Loop over it in Flow.

Note the use of dot notation in the Value field. I was able to select this value without typing:

However if you need to go more than one level deep, you’ll have to type in the dot notation yourself, as in the case of the Pricein this example:

Recall that our goal is to end up with three products. We generate the product data by looping over the identifiers and assembling a collection of products. A second loop enables us to add the appropriate picture URL to each of the products. Finally, we save the collection of records to Salesforce.

Good luck with your flows!

New Version of Load Web Page Flow Screen Component

The old version of Load Web Page used an event-based architecture that doesn’t work in all Salesforce environment.

Here’s a new version that should work everywhere: Install

Provide it with a url that has the “http://” in front of it.

Seamless Flow Handoffs from Users to Agents

Users can start flows and then pause them, and those same flows can be made to appear on the user’s Contact record where an agent can resume and complete the flow.

This requires and relies on the Guided Action List’s ability to find and display all paused flows associated with a record.

The Community user must be a signed in Salesforce user. They can’t be a Guest User.

Flows can be linked to a Record

Flow provides a mechanism that allows individual flows to be linked to records. This means that a flow about a Contact can be linked to a particular Contact via that Contact’s Id. Or a flow could be linked to an Asset or a custom object record. The main benefit of doing this is that when the record page is displayed for that record, if the record page has a Guided Action List component, it will display all the linked flows that are 1) In Progress or 2) Paused. And in the case of flows that are Paused, the user looking at the record page can resume the flow.

Enable Flow Handoffs By Linking The Flow To the User

In order for a Flow started in Community Cloud to be resumable by an agent in Service Cloud, have the Flow populate the Flow Global Variable $Flow.CurrentRecord must be assigned the value of the current UserId.

Tip: The Contact Id of the currently logged-in Community user is the same as their UserId.

Flow provides access to the Global Variable $User and $User.Id will return the currently logged-in user’s Id. Assign this value to the recordId resource that you created:

When the Guided Action List is on a record page, it queries to see if there are any Flows in progress or paused that are linked to the current recordId, and it does this by checking for the presence of a value in a resource called recordId. So, you will need to be on the Contact page corresponding to the user in order to see their paused flows.

A final note: The Guided Action List component is only available in the Lightning Experience so you’ll need to be in Lightning to use this process.

Learn how to Insert Images in Flow Screens

There’s a new blog post on Salesforce’s official blog channel covering the use of the official, bundled-with-Flow Display Image screen component. Check it out.

There’s also the more powerful, less polished Image screen component that continues to be available on this community site. The original post on that.

Here’s a post we did on overriding the Footer buttons with a custom image.

New Flow Action: Get Distance between Cities

There are scenarios where you need to know the distance between two specific cities and use it in your flows. Now you can easily do it using this new flow action. Grab an unmanaged package here, install it to you Salesforce organization and add it to your flow. Alternatively, you can grab the source code from GitHub and push to your org.

Internally this action utilizes Google Maps API so you will need to get developer key. You can request one here. After you got the key and installed the package, go to Setup -> Custom Metadata Types -> Google API Key (click ‘Manage Records‘ next to it). There will be just one record of this type: open it and paste your developer key into Key field.

Google API Key

Configuring Google developer key

The configuration is pretty straightforward: give it two cities (optionally with country names for disambiguity) and use the output distance measured in miles or kilometers.

GetDistance Input Values

Input values configuration

GetDistance Output Values

Output values configuration

If everything is fine parameter Is Success will contain True value. Otherwise, it becomes False, and Error Message will contain detailed description of the error (e.g. source or destination were not found or there are no routes between them). The distance (both in miles and in kilometers) are rounded up to 3 digits.

GetDistance Example

Example of the message constructed from the output parameters

Source Location and Destination Location output parameters are the source and destination input parameters converted to a universal form City, State, Country (e.g. Los Angeles, CA, USA)