The Flow Troubleshooter Pattern is useful for creating and managing large numbers of custom nodes without having to manually add a flow element for each one.
https://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.png00Alex Edelsteinhttps://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.pngAlex Edelstein2020-02-13 13:27:112020-02-13 13:28:37Sebastiaan de Man: Create Customized Knowledge Articles with Flow
https://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.png00Alex Edelsteinhttps://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.pngAlex Edelstein2020-02-11 14:09:222020-02-11 14:09:23New Guidance: How to Check For Null in an Automatic Output World
SalesForce Orgs and Communities often require multiple language support, including the ability to generate emails in the selected language of the Community anonymous user, member or Org User.
LightningFlowComponents/flow_action_components/SendHTMLEmail/ has been extended to send the appropriate language email based on the preferred language as part of a flow action to send email. This Action uses Lightning EmailTemplates, and has not been tested on Classic Templates (yet).
For this functionality, each language localization has its own template, that shares a common EmailTemplate.Name. To differentiate the localizations, add a tag to the EmailTemplate.Description field in the format: ‘Language=”en_US”‘ (or whatever corresponding to your organization localizations).
When the sendHTML templateName and templateLanguage parameters are used, the action selects the template with the matching templateName and the ‘Language=”xxx_YY”‘ tag in the Description. (Note, no spaces, exact match only)
Template Selection criteria order is prioritized using matching EmailTemplate:Name and:
If templateLanguage is empty, set to Organization LanguageLocaleKey
If templateLanguage tag is found in EmailTemplate.Description (e.g., ‘Language={{{templateLanguage}}}’)
First matching template with matching templateName but no corresponding ‘Language=”‘ tag in EmailTemplate.Description
Example:
Step 1: Identify the Common EmailTemplate:Name for the Template Set you would like to use for localization and copy the name. (App Launcher–>Email Template[lightning]). (Note, in this case it would be “OAG OCP Complaint Received Email” – and there are two tagged locales identified in the Description Field, “en_US” and “es_MX”)
Step 2: Add the Apex action to your Flow and set the Parameters:
Associated RecordId(WhatId/recordId for template and activity) (In Example, a Case Record ID {!param_Case.Id}, but only needed if you are using merge fields for this record)
Template Language (In Example, the language chosen in the flow logic for the Contact {!param_Language})
Template Name (In Example, “OAG OCP Complaint Received Email” )
Template Target Record Id (In Example, {!param_ContactID} which is to whom the email will be sent, and any recipient merge fields used in the template)
Caveats
Limitation: Enhanced Letterheads are not supported in Lightning Communities at this time. A support request has been submitted and it is being worked on by SF. If you attempt to use the Enhanced Letterhead in a Community application, you will get the following error: sObject type ‘EnhancedLetterhead’ is not supported. If you are attempting to use a custom object, be sure to append the ‘__c’ after the entity name. Please reference your WSDL or the describe call for the appropriate names.: []
Kludge Acknowledgement: The elegant solution would have a localization field in EmailTemplate (e.g., EmailTemplate.LanguageLocaleKey ). At this time, no such field exists and you cannot add custom fields to EmailTemplate Object – ergo, a tag parsed from the standard “Description” is the kludged approach.
https://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.png00Jack Pondhttps://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.pngJack Pond2020-02-11 08:33:572020-03-15 08:15:10Send HTML Email with Multi-Language Support for Lightning Email Templates
Some input parameters requires strings in one of two forms. Send Rich Email, for example, can take a list of string email addresses but can’t (currently) take a comma-separated-list.
This package provides a set of simple actions to convert data from one form to the other.
Convert from Collection to CSV String
This takes a string collection and returns a csv string.
Convert To String Collection
ConvertToStringCollection, can use a provided character as a delimiter. For example, if you pass in the output of a multiselect picklist and set the delimiter to a semicolon, you’ll convert multiselect picklist output to a collection of strings that can be worked on later in the flow.
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 typesYou need to check this box to store the output valueThe new task Id is fed into this actionAnd this is the completed flowHere is the end user experience
https://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.png00Tamar Erlichhttps://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.pngTamar Erlich2020-02-10 12:18:322020-02-13 07:56:44Flow Use Case – New Task Button with picklist for selecting the record type
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
https://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.png00Tamar Erlichhttps://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.pngTamar Erlich2020-02-10 12:13:032020-02-10 17:19:28Preventing duplicate junction object records by GORAV SETH
Courtesy of Chris Van Der Merwe, here’s a Calculate Business Hours action that allows easy declarative, automated manipulation of Business Hours information.
Effective key performance indicators are a valuable part of any business. However, Salesforce does not have an easy declarative way to do calculations around business hours. You can do this with a variety of formula fields, but it is not very flexible.
For example, how do you quickly update it for a snow day, or your leadership team approved an extra holiday over the winter break? At my organization, we wanted to track performance indicators such as how long does it take to make our first attempt and how long does it take to make the first contact.
This new flow action will allow you to quickly and easily calculate the business hours between two dates. This utilizes the Salesforce built-in Business Hours object. The component has three inputs:
Business Hours Id
Start Date
End Date
You will have the option to output the difference in milliseconds, seconds, or minutes.
https://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.png00Alex Edelsteinhttps://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.pngAlex Edelstein2020-02-09 08:34:392022-07-16 06:40:26Work with Business Hours via New Flow Actions
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.
Example
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.
https://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.png00Alex Edelsteinhttps://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.pngAlex Edelstein2020-02-07 08:33:062020-02-07 08:36:42Using Serialization with Flow to Store Session Data and Enable Custom Resume
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.
https://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.png00Alex Edelsteinhttps://unofficialsf.com/wp-content/uploads/2022/09/largeUCSF-300x133.pngAlex Edelstein2020-02-04 21:44:552020-02-04 21:47:57David Entremont: Increase Your Limits with the “Save Records Later” Action (Queueable Apex)