Site icon Sunshine and Other Unhandled Exceptions

Invocable Methods: How to Send Data Between Flow and Apex

UPDATE!!! This is information is outdated. GO HERE.

Invocable methods used with Flow allow you to launch something in an admin friendly format that uses the massive power of Apex. For example, you have an intake screen that collects answers to a few questions, then you use Apex to loop through many related records dispersing those answers in places hard to reach from Flow.

Creating an invocable method in a nutshell: First you write an apex class with @invocable method (label and description) and whatever code you want the apex to do (easy, right?) Then make your Flow including your input and output variables. Then add an Apex action in Flow to send/receive those variables.

Here are some things I learned about sending data between Flow and Apex.

Invocable methods in Apex always receive a List and they return a List unless the return type is null. Read more under “Inputs and Outputs” here.

SentSent FromReceived by Received
Record Variable.idFlowApexList<Id> listOfIds
Record Collection VariableFlowApexList<List<Opportunity>> nameOfThis
List containing 1 sObject recordApexFlowRecord (single) variable
List of Lists of sObjectApexFlowRecord Collection Variable

This is NOT an exhaustive list at all. I didn’t try sending a record variable (not just the ID from Flow), but I assume that will work. There are also generic sObjects that are pretty special, but I didn’t try.

Here are two examples of invocable methods used with Flows. Note that what you send to apex does not impact what you can receive, as far as I know.

Example One: Send One Id, Get Back a Record Collection

In this Flow, I tried using an Apex Action to avoid having a DML statement inside a loop. You may notice that there is also a loop inside another loop. So this Flow is not an example I want you to go out and copy (I ended up moving the whole thing to Apex), but I got the Apex Action to work and I learned a ton!
This image is from the Apex Action inside the Flow.
public class contactsListAction {
    //this invocable method takes a single contact id from Flow from a record variable
    //and returns a list of lists of opportunities associated with that contact.
    //the list of lists is stored as a collection variable in the Flow.
    @InvocableMethod (label = 'SendContactsGet Opps' description = 'returns opps for this contact.')
    
    //this method returns a List of Lists of Opps to the flow and receives a List of Ids
    public static List<List<Opportunity>> getContactIds (List<ID> ids) {
        
        //Store in a list the id, closedate and Amounts of opps whose Primary Contact came in the variable "ids"
        //and who have a stage of Clsoed Won and a Close Date of this year
        List<Opportunity> opps = [SELECT id,CloseDate,Amount
                                  FROM Opportunity                                   
                                  WHERE npsp__Primary_Contact__c in :ids 
                                  AND StageName = 'Closed Won' 
                                  AND CloseDate = THIS_YEAR]; 
        //declare a new list of lists of opps
        List<List<Opportunity>> itemListList = new List<List<Opportunity>>();
        //add the list opps to the list of lists
        itemListList.add(opps);
        // send list of lists to the Flow	
        return itemListList;        
    }  
}

Example Two: Send a Collection, Receive Back One Record

public class sendManyGetOne {
    @InvocableMethod (label = 'Send Many Get One' description = 'send a collection of records to Apex, get one record back.')
    
    //this method returns a List containing one opportunity 
    //the parameters are a List of Lists of Opportunities. The flow sends this as a collection variable of opps.
    public static List<Opportunity> getOppId ( List<List<Opportunity>> listOppLists) {
        
        //get the first List from the List of Lists
        List<Opportunity> oppsList = listOppLists.get(0);
        
		//get the id and Amount from the Opp in that first List. 
        List<Opportunity> opps = [SELECT id,Amount
                                  FROM Opportunity                                   
                                  WHERE id in :oppsList]; 
        //convert that to an opportunity
        Opportunity newOpp = opps.get(0);
        //change a value on it
        newOpp.Amount = 800;
        //instantiate a new list 
        List <Opportunity> returnOpps = new List <Opportunity> ();
        //add that modified opp to the new list
        returnOpps.add(newOpp);
        //send the new list of just one opp back to the Flow
        return returnOpps;
	}
}

Learn More

Official Documentation on Invocable Methods.

Exit mobile version