Dynamically Execute Apex Script in Salesforce Flow

Munawirrahman
6 min readDec 24, 2023

--

Hi Folks!

As a flow developer you may get annoyed by the fact that you have to write Apex, write Apex Test, and deploy your Apex everytime you want to have functionality that flow does not have but apex has, especially if you only need a small functionality from the Apex itself. But what if, you can write your apex script and execute that apex script on the fly with only a single variable in Flow?

Image00 Thumbnail

Invocable Execute Apex Script

Invocable Execute Apex Script is an invocable method (an Apex function that you can access in flow) that can help you to execute your Apex script dynamically on the fly within Flow. Magic behind this flow action is you do a callout to Salesforce Execute Anonymous Apex API with the Apex Script that you pass to the input.

Image01 Invocable Execute Apex Script Inputs

Input Attributes

  1. Apex Script (Required)
    This is an Apex Script you would like to execute. You can use Text Template to formulate the Apex Script and pass some variables to the text template(just make sure it’s in plain text mode)
    API Name : apexScript
    Type : Text / String
    Example : System.debug(‘Hello World’);
  2. API Version (Optional)
    This is the API Version of the Apex Script you’d like to execute. If none, will be defaulted to v59.0
    API Name : apiVersion
    Type : Text / String
    Example : v59.0
  3. Named Credential API Name (Optional)
    This is the Named Credential you’d like to use for the callout. If you don’t set the Named Credential, it will use the running user’s context auth token by using UserInfo.getSessionId(). Here’s the how-to create Named Credential for Tooling API. Here are the extended functionality you can have if you use Named Credential
    - You can do the callout synchronously, which means you can know immediately whether you script is sucessfully executed or not. Check when to run asynchronously or synchronously on image05.
    - If the user that will run this Flow Action does not have Execute Anonymous Apex Permission and you set the Named Credential Auth Provider to Named Principle (authenticated as a System Admin user), your user will still be able to run this Flow Action. But the user context will be as the System Admin user.
    API Name : namedCredentialApiName
    Type : Text / String
    Example : Tooling_API
  4. Run Asynchronously ? (Optional)
    If set to true, the callout will run asynchronously using Queueable Apex and you won’t be able to know the result of the script execution immediately. If Named Credential is empty, this will be automatically defaulted to True. If Named Credential is not empty, automatically defaulted to False. The output of Run Asynchronously will only be the Job Id of the Queueable.
    API Name : runAsynchronously
    Type : Boolean
    Example : True
Image02 Sample of Named Credential for Tooling API

Output Attributes

  1. (Async) Job ID
    Only output in Asynchronous mode. This is a Job ID that you will retrieve if you run this action asynchronously. You can check the result of your apex script execution in Apex Jobs list view.
    API Name : jobId
    Type : Text / String
    Example : 7075g00008hIm63
  2. (Sync) Line
    Only output in Synchronous mode. Represents the line number in the code where a particular event or issue occurred during the execution. This can be useful for pinpointing the location of errors or other events.
    API Name : column
    Type : Number / Integer
    Example : -1
  3. (Sync) Column
    Only output in Synchronous mode. Represents the column number in the code where a particular event or issue occurred during the execution. Similar to line, it helps narrow down the location of errors or events.
    API Name : column
    Type : Number / Integer
    Example : -1
  4. (Sync) Compiled
    Only output in Synchronous mode. A Boolean flag indicating whether the Apex code was successfully compiled (true) or if there were compilation errors (false). If compiled is false, you might check the compileProblem for details on the compilation issue.
    API Name : compiled
    Type : Boolean
    Example : True
  5. (Sync) Success
    Only output in Synchronous mode. A Boolean flag indicating the overall success of the execution. If success is true, the execution was successful; if false, there might be issues that need attention.
    API Name : success
    Type : Boolean
    Example : True
  6. (Sync) Compile Problem
    Only output in Synchronous mode. If the code compilation fails, this variable provides details about the specific problem encountered during compilation. It typically includes an error message indicating what went wrong in the code.
    API Name : compileProblem
    Type : Text / String
    Example : Unexpected token ‘=’
  7. (Sync) Exception Stack Trace
    Only output in Synchronous mode. In case of runtime exceptions or errors during execution, this variable contains the stack trace associated with the exception. The stack trace gives a detailed report of the sequence of calls and the point at which the exception occurred.
    API Name : exceptionStackTrace
    Type : Text / String
    Example : AnonymousBlock: line 1, column 1
  8. (Sync) Exception Message
    Only output in Synchronous mode. Provides a human-readable message associated with any runtime exception that occurred during execution. It summarizes the nature of the exception or error.
    API Name : exceptionMessage
    Type : Text / String
    Example : System.MathException: Divide by 0
Image03 Sample Output Asynchronous
Image04 Sample Output Synchronous

Deciding when to run asynchronously or synchronously

Image05 When to run asynchronously or synchronously

How to check status of the Asynchronous Job

  1. Go to Setup -> Search for Apex Jobs -> click Apex Jobs
  2. Click Create a New View
  3. Name it InvocableExecuteApexScript
  4. Set Apex Class Name Equal to InvocableExecuteApexScript as a filter
  5. Click Save
  6. Search the job based on Job ID that being outputted in the Flow
  7. Check column Status Detail
Image06 List View Filter
Image07 Check Async Apex Script Job

Sample Use Case : Force Pause / Wait in Record Triggered Flow

Let’s try to find a workaround for this idea. Disclaimer : The solution I give you probably won’t be a best practice, but just to give you a clear idea on how you can actually achieve this.

Image08 When you try to launch Autolaunched Flow that has Pause / Wait Element

Step 1 — Prepare an Autolaunched Flow with Wait element

Image09 Autolaunched Flow with Pause or Wait Element

Step 2 — Prepare an Apex Script to Launch that Autolaunched Flow (You can try it first in Anonymous Apex Window)

String inputVariableName = 'recordId'; //input variable name in the subflow
String recordId = '{!$Record.Id}'; //value of the variable in the subflow
String flowName = 'Force_Pause'; //api name of the subflow
Map<String,Object> inputVariablesMap = new Map<String,Object>();
inputVariablesMap.put(inputVariableName,recordId);
Flow.Interview myFlow = Flow.Interview.createInterview(flowName,inputVariablesMap);
myFlow.start();

Step 3— Prepare a record triggered flow that will trigger the Autolaunched Flow

Image10 Text Template to launch Autolaunched Flow in Apex
Image11 Final Record Triggered Flow (Run asynchronously)
Image12 Input for use case

Step 4 — Test and Validate

Image13 Apex Job
Image14 Paused Interview created

Consideration and Limitation :

  1. With great power comes great responsibility, whoever user context that will do the callout should have Apex Author permission enabled, you can consider to use Named Principle Named Credential.
  2. This will consume more of your API Call limit (and Apex Async Limit if you do it asynchronously) since this solution require a callout.
  3. You should ensure that the script does not inject any variable that you dont intend, else it may become a security issue.

Installation

Install Production
Install Sandbox
Source Code

Please clap if you think this is useful. Let me know if you have any question. Thank you

--

--