Home » Flow

Category Archives: Flow

Scheduling a Salesforce autolaunched Flow

In the Winter ’20 release, Salesforce introduced scheduling autolaunched flows, which made it possible to schedule actioons decalatively within Salesforce. Prior to that, the only way to schedule anything in Salesforce was through Asynchgronous Apex, specificaly by implemeting the Schedulable interface. 

To schedule autolaunched flows, you need to specify the date and time the flow will run as well as its run frequency: once, daily, or weekly. Optionally, you can specify a specific Object with a filter that returns specific records of that Object, where the flow would run against. 

Here’s the session explaining scheduling Salesforce autolaunched flows, with 2 demos ar the end:

  1. Scheduling sending an email using the “Send Email” action
  2. Scheduling mass-updating Account records on a daily basis

These considerations apply to scheduled flows.

  • A scheduled flow starts at the specified time and frequency. You can’t launch a scheduled flow by any other means.
  • The Start Time field value is based on the org’s default time zone.
  • The View All Data permission is required to activate an autolaunched flow that has a trigger.
  • The maximum number of scheduled flow interviews per 24 hours is 250,000 or the number of user licenses in your org multiplied by 200, whichever is greater.

    If you specify an object so the flow runs for a batch of records, set the time, frequency, and record conditions to avoid reaching this limit. You can use debug logs to check how many records a scheduled flow runs on. Track the number of records with the FLOW_START_SCHEDULED_RECORDS event. If your org reaches the limit, Salesforce sends a flow error email.

  • If you delete a scheduled flow from the Scheduled Jobs page in Setup, all future recurrences of that flow are canceled. To enable future runs, deactivate and reactivate the flow.
  • A scheduled flow doesn’t run if it’s scheduled to run once with a date and time that has already passed.
  • The Automated Process user runs scheduled flows.
  • If you need a scheduled flow to invoke Apex code, don’t activate the Require User Access to Apex Classes Invoked by Flow critical update. When that critical update is activated, the scheduled flow fails when it invokes Apex.
  • If you configure an Update Records element to use the ID and all field values from the $Record global variable, enable Filter inaccessible fields from flow requests in your org’s process automation settings. Otherwise, the flow fails because the Update Records element tries to set the values for system fields and other read-only fields.
  • When you define multiple filters, the filter logic usually defaults to AND. However, if multiple filters have the same field selected and use the equals operator, the filters are combined with OR.

    For example, your filters check whether a case’s Type equals Problem (1), Type equals Feature Request (2), and Escalated equals true (3). At run time, the filters are combined to (1 OR 2) AND 3.

Round Robin Assignment using Flow

Use Case:

Marie Sloan, a Salesforce Admin, is asked to build a Round Robin assignment tool to assign Survey records to Agent records following a Round Robin way, which means that  the total number of Survey records to assign should be divided by the number of Agents, and each Agent should be assigned an equal number of Survey records. For example, if we have 3 Agents and 36 Surveys, each Agent will be asigned exactly 12 Surveys. 


Object Model:

To tackle this requirement, let’s first explain the data model required to illustrate this example:

  1. Custom object called Round_Robin_Assigner__c  This is the object that will be used to initiate the Round Robin assignment. The fiels are:
    1. Name: auto number field with display format: RR-{000}
    2. Number_of_Agents__c: Rollup-Summary field that counts the number of Agent__c records associated with this Round_Robin_Assigner__c record
    3. Number_of_Surveys__c: Rollup-Summary field that counts the number of Survey__c records associated with this Round_Robin_Assigner__c record
  2. Custom object called Agent__c with the following fields:
    1. Name: auto number field with display format: A-{000}
    2. User__c: lookup field to the User object
    3. Round_Robin_Assigner__c: Master-Details field to the Round_Robin_Assigner__c object.
  3. Custom object called Survey__c with the following fields:
    1. Name: auto number field with display format: S-{000}
    2. Tag__c: auto number field without any display format. This field simply represents the tag, or Id of eacj Survet record, it is automatically added to each survey, and no 2 surveys will have the same Tag number. This field will be used to calculate the Assignment_ID__c field below.
    3. Assignment_ID__c: formula field used to give the assignment ID to each Survey record, based on t he total number of Agents and the Tag on each Survey. More details to follow below.
    4. Round_Robin_Assigner__c: lookup field to the Round_Robin_Assigner__c object. This is the field that will be filled to assign an Agent to the Survey.

Here is the ERD:

To futher explain what’s going on,

  1. the main object (1) Round_Robin_Assigner__c is the parent of both:
  2. the object to assign, in this case (2) Survey__c
  3. the object to assign to, in this case (3) Agent__c.

In other words, if we want to assign Agent__c records to Survey__c records, first, we create a Round_Robin_Assigner__c record, second, we add to it all the Survey__c records that we want to assign, and third, we  add all the Agent__c records that should be assigned to Survey__c records. The Round_Robin_Assigner__c record will hav a button that will launch a flow to assign the Surveys to the Agents in a Round Robin fashion! Simple!

Now, let’s explain the fields on each object…

First, the Round_Robin_Assigner__c object has 2 Rollup-Summary fields that count the number of Agent__c and the number of Survey__c associated with it. The field names are Number_of_Agents__c and Number_of_Surveys__c


On the Survey__c object:

  • The Tag__c field is simply an auto-number field that gives a unique number to the record. The first Survey__c record has Tag__c = 1, and so on.
  • The Assignment_ID__c field is the field used to assign the Survey__c to the Agent__c. It is a Fomrula field with this Formula:
1 + MOD(Value(Tag__c), Round_Robin_Assigner__r.Number_of_Agents__c)

This MOD function will take the MOD of (1) the Tag number value of the Survey__c record – we uses the Value() function to take the number value of this auto-number field, and (2) the total number of Agent__c records associated with this Round_Robin_Assigner__c record. So, if we have 5 Agent__c records, and 100 Survey__c records,

  • For example, the record wih tag 50 would have 1 + MOD(50,5) = 1 + 50 MOD 5 = 1 + 0 = 1,
  • the next record would have 1 + MOD(51,5) = 1 + 51 MOD 5 = 1 + 1 = 2
  • the next 1 + MOD(52,5) = 1 + 52 MOD 5 = 1 + 2 = 3
  • the next 1 + MOD(53,5) = 1 + 53 MOD 5 = 1 + 3 = 4
  • the next 1 + MOD(54,5) = 1 + 54 MOD 5 = 1 + 4 = 5
  • the next 1 + MOD(55,5) = 1 + 55 MOD 5 = 1 + 0 = 1
  • Etc…

This way, the Assignment_ID__c field will dictate which Survey record goes to which Agent, based on the above math.

Next, we will add a Flow to assign the Agent__c field to the Survey__c records. 

Create the Flow:

Create a new Screen Flow, and in it first, create the variable that will hold the Id of the Round_Robin_Assigner__c record that will have the button to launch the flow. Remember, the variable name should exactly be ‘recordId‘ with the letter ‘I’ in a capital case.

To start, let’s create 3 “Get Records” elements: 

  • Get Assigner: to get the details of the 1 Round_Robin_Assigner__c record that has the Id recordId. Store the variable in the Record Variable sov_Assigner
  • Get Agents: to get all Agent__c records that are children of the above Round_Robin_Assigner__c record. Store the variable in the Record Variable socv_Agents
  • Get Sutveys: to get all Survey__c records that are children of the above Round_Robin_Assigner__c record. Store the variable in the Record Variable socv_Surveys
  • I will only show the screenshots of the first and second “Get Records” elements above. 

Now, create 2 Number variables and an Assignment element to assign them values:

  • v_Agent_Total_count = {!sov_Assigner.Number_of_Agents__c}. This is the rollup summary field that countsthe number of Agents related to this Round_Robin_Assigner__c record.  
  • v_Agent_Counter = 1. This will set the counter to 1. 

Create the first loop:

  • Purpose: loop through all the Agent__c records that are related to the Assigner__c record. For each agent, get all the Survey__c records with an Assignment Id equivalent to the Agent. 
  • Name: Loop through Agents 
  • Collection Variable: socv_Agents 
  • Iteration Direction: First item to last item
  • Loop Variable: socv_agents_single


Inside this loop, get the Survey__c records with an Assignment Id equivalent to the Agent. For that, we will use use variable v_Agent_Counter. All these syrveys will be stored in a Record Variable called socv_Specific Surveys

Create a second loop inside the first loop:

  • Purpose: loop through all the Survey__c records with an Assignment Id equivalent to the Agent, and add these to a “Record Variable” to assign them at the end to the Agent. 
  • Name: Loop through specific Surveys 
  • Collection Variable: socv_Specific_Surveys 
  • Iteration Direction: First item to last item
  • Loop Variable: socv_Specific_Surveys_single

Inside this second loop, assign the Agent Id to the Agent__c field of the Survey. Then add this Survey to a new Record Variable called socv_Surveys_to_Update. To do so, create the Record Variable, then create an Assignment element to add the single Survey__c record to the socv_Surveys_to_Update. 

After exiting the second loop, increase the Agent Counter variable by 1

Finally, update all the Survey__c records at once, using a Record Update element on the socv_Surveys_to_Update record variable. 

You can then add a Screen element with any information you want:

And this is the final Flow:

Now, activate the Flow, then add a New Action  that calls this Flow from within the Round_Robin_Assigner__c object. 

Let’s run thre Assigner! Here is a screen before clicking on the button, and then the result aft.er. Notice that each Survey ois now assigned to a specific Agent!

You can modify the objects based on your requirements, but the idea is the same! 



Lightning Flow to copy File Links from Opportunity to Account


Use Case: 

As a Salesforce Admin, you are requested to copy all the Files attached to an Opportunity to its parent Account whenever the Opportunity is Closed-Won. This way, the Account record will have each file added to any of the Opportunities of the Account. 


A little bit of background:

To tackle this requirement, we should first understand the data model behind Files and how they are attached to records in Salesforce. 

The Data model for Content Document is:


The key objects to understand

  • ContentDocument: Represents a document that has been uploaded to a library in Salesforce CRM Content or Salesforce Files
  • ContentDocumentLink: Represents the link between a Salesforce CRM Content document or Salesforce file and where it’s shared. A file can be shared with other users, groups, records, and Salesforce CRM Content libraries. Fields of this object:
    • ContentDocumentId: is the Id of the ContentDocument
    • LinkedEntityId: ID of the linked object. Can include Chatter users, groups, records (any that support Chatter feed tracking including custom objects), and Salesforce CRM Content libraries.
    • Visibility: picklist with 3 values. ‘V’ for Viewer permission – the user can explicitly view but not edit the shared file. ‘C’ for Collaborator permission – the user can explicitly view and edit the shared file. ‘I’ for Inferred permission. The user’s permission is determined by the related record.
    • ShareType: picklist with 3 values. AllUsers – the file is available to all users who have permission to see the file. InternalUsers – the file is available only to internal users who have permission to see the file. SharedUsers – the file is available to all users who can see the feed to which the file is posted.

So, to simplify, anytime you upload a File via the Files related list, you create a ContentDocument and a ContentDocumentLink that links the ContentDocument to the record! Simple. 



To tackle this requirement, we’re going to use Lightning Flow (Process + Flow). The process will be simply used to call the Flow when the Opportunity is Closed-Won, and to pass the Id of the Opportunity to the Flow. The process will be created AFTER the flow.

The Flow will be used to:

  1. Get the Opportunity details (mainly the AccoundIt field)
  2. Get all ContentDocumentLinks that are associated to the Opportunity and put them all in a single sObject Collection Variable
  3. Loop through these ContentDocumentLink records
  4. On each pass, add a new ContentDocumentLink record to a Collection Variable – but specify that the LinkedEntityId is the AccountId
  5. Finally, create the collection of ContentDocumentLink. This way, the links will be available on the Account

Here’s the final flow:


To begin, let’s create the Autolaunched Flow:


The first thing to do is to create the recordId variable. This variable will be used by the process to pass the Id of the Opportunity. Make sure you make it “Available for Input” as the process will pass the Opportunity Id to this variable. 


Now, we’ll use recordId to the the Opportunity record and store it in sov_Opportunity. Field to include is AccountId. 


Next, let’s get the ContentDocumentLink records that reference the Opportunity via the LinkedEntityId field. We store all these records in the variable socv_CDL_Opty.


We’ll now loop hrough this list of ContentDocumentLink records, and on each pass, we’ll assign a new record of ContentDocumentLink, then add it to the collection. The variable socv_CDL_Opty_Single is a single ContentDocumentLink record that will be used on each pass. Make sure to define it.


On each pass, 2 assignments will happen. The first is to assign a new ContentDocumentLink record, while specifyign the LinkedEntityId field to be the AccountId field retrieved from the first step.

The second assignment is to assign this single record to a collection of records.


And finally, we should create the ContentDocumentLink collection variable using the Record Create element:


The flow is done, we’ll now create the process that will simply call the Flow when an Opportunity is in the Closed-Won stage:


Here’s the Unmanaged Package that contains both the Flowand the Process. You can use it and modify it as needed, you can also use the same logic to apply for other objects and requirements.

For Production/Dev Edition:


For Sandbox: