How to Call Invocable Actions from Apex in Salesforce?
In Salesforce Winter 23' release we can now use Invocable Actions in Apex Class.
In this blog we will see how we can make use of new Invocable.Action Apex Class in order to use custom or standard Invocable Actions via apex.What are Invocable Actions ?
The invocable actions mechanism allows to create custom code and package it into components/actions available in declarative tools, such as flow. It is a simple idea to provide input values that the apex manipulations and transactions and then finally gives the desired output values.
The invocable actions mechanism allows to create custom code and package it into components/actions available in declarative tools, such as flow. It is a simple idea to provide input values that the apex manipulations and transactions and then finally gives the desired output values.
New Invocable.Action class has following methods -
We will take two examples to use the above methods, 1 for each custom Invocable Action and standard Invocable actions.
We will take two examples to use the above methods, 1 for each custom Invocable Action and standard Invocable actions.
Call Standard Invocable Actions from Apex
Let us take chatterPost as an example for Standard Invocable Actions.
Step 1: Check the type and other input parameters that are needed for chatterPost.
Login into Workbench => Utilities => REST Explorer => GET Request/services/data/v54.0/actions/standard/chatterPost
If we expand the input folder we can see the input parameters that are needed. Similarly for expected output we can see that in Output folder.
Here ,
Input Parameters are :-
- text -String
- subjectNameOrId - String
- type
- communityId
- visibility
- feedItemId
for example -
ClassName - TestInvocableActionViaApexW23
MethodName - postToChatter
For chatterPost only text and subjectNameOrId are required parameters and rest are optional.
So lets give following values;-
text - 'This is an example Chatter post.'
subjectNameOrId - recordId (Any recordId where you want to post a Chatter feed)
TestInvocableActionW23.cls
Step 3 : From anonymous window run
TestInvocableActionViaApexW23.postToChatter('0016F00002V58eaQAB')
We will get the following result from which we can extract the newly created feedItemId which is the output parameter.
public class TestInvocableActionW23 {
public static void postToChatter(String recordId) {
//set standard action as 'chatterPost'
Invocable.Action action = Invocable.Action.createStandardAction('chatterPost');
// set text value as string type
action.setInvocationParameter('text', 'This is an example Chatter post.');
// set the record Id value
action.setInvocationParameter('subjectNameOrId', recordId);
//invoke the Invocation.Action
List<Invocable.Action.Result> results = action.invoke();
System.debug('result : ' + results); //print result
if (results.size() > 0 && results[0].isSuccess()) {
System.debug('Created feed item with ID: ' +
results[0].getOutputParameters().get('feedItemId'));// Debug newly created FeedIemId
}
}
}
TestInvocableActionViaApexW23.postToChatter('0016F00002V58eaQAB')
We will get the following result from which we can extract the newly created feedItemId which is the output parameter.
(Result:[action=Action:[invocations=({subjectNameOrId=0016F00002V58eaQAB, text=This is an example Chatter post.}), name=null, namespace=null, type=chatterPost], errors=(), invocationParameters=(already output), outputParameters={feedItemId=0D56F0000EL2yHfSQJ}, success=true])
Call Custom Invocable Actions from Apex
Step 1: Check the existing actions in your org
Login into Workbench => Utilities => REST Explorer => GET Request
/services/data/v54.0/actions/custom
Here we will use existing Apex class ChangeOwnerFromflow with Invocable methods .
In this class ChangeOwnerFromflow we have
Input Parameters are :-
- recIds - List<String>
- user_name - String
- N/A (here it is N/A, but we can create one as per requirement.)
Step 3: ChangeOwnerFromflow.cls
public class ChangeOwnerFromFlow {
public class FlowInputs {
@InvocableVariable public List<String> recIds;
@InvocableVariable public String user_Name;
}
@InvocableMethod
public static void updateOpp (List<FlowInputs> requests) {
// get all Ids
List<Id> newIds = new List<Id>();
String username;
for (FlowInputs request : requests) {
newIds.addAll(request.recIds);
username = request.user_Name;
}
String str = '%'+username+'%';
User usernameId = [Select id from User where Name Like :str limit 1];
// Get the sObject token from the first ID (the List contains IDs of sObjects of the same type).
Schema.SObjectType token = newIds[0].getSObjectType();
// Using the token, do a describe and construct a query dynamically.
Schema.DescribeSObjectResult dr = token.getDescribe();
String queryString = 'SELECT id,ownerId FROM ' + dr.getName() + ' WHERE ';
for(ID objId : newIds) {
queryString += 'Id=\'' + objId + '\' OR ';
}
// Remove the last ' OR'
queryString = queryString.subString(0, queryString.length() - 4);
sObject[] objDBList = Database.query(queryString);
System.assert(objDBList.size() > 0);
// Update the owner ID on the sObjects
for(Integer i=0;i<objDBList.size();i++) {
objDBList[i].put('ownerId', usernameId.id);
}
Database.SaveResult[] srList = Database.update(objDBList, false);
for(Database.SaveResult sr : srList) {
if (sr.isSuccess()) {
System.debug('Updated owner ID successfully for ' + dr.getName() + ' ID ' + sr.getId());
}
else {
System.debug('Updating ' + dr.getName() + ' returned the following errors.');
for(Database.Error e : sr.getErrors()) {
System.debug(e.getMessage());
}
}
}
}
}
for example -
ClassName - TestInvocableActionViaApexW23
MethodName - changeOwnerName
For ChangeOwnerFromFlow both recIds and user_name are required parameters.
TestInvocableActionW23.cls
public class TestInvocableActionW23 {
public static void changeOwnerName() {
List<Opportunity> oppList = new List<Opportunity>();
oppList = [Select Id from Opportunity Limit 10];
List<String> recIDs = new List<String>();
for(Opportunity opp : oppList){
recIDs.add(opp.Id);
}
//set standard action type as 'apex' and name as 'ChangeOwnerFromFlow'
Invocable.Action action = Invocable.Action.createCustomAction('apex', 'ChangeOwnerFromFlow');
// set List<String> recdIds
action.setInvocationParameter('recIds', recIDs);
//set user_name
action.setInvocationParameter('user_Name','Amit Agarwal');
List<Invocable.Action.Result> results = action.invoke(); //invoke the Invocation.Action
System.debug('result : ' + results); // print result
}
}
TestInvocableActionViaApexW23.changeOwnerName();
We will get the following result.
Result:-
(Result:[action=Action:[invocations=({recIds=(0066F000016jkrhQAA, 0066F000016jkveQAA, 0066F000016jkvyQAA, 0066F000016jkwNQAQ, 0066F000016jl21QAA, 0066F000016jl2BQAQ, 0066F00000vVBE6QAO, 0066F00000vVBEDQA4, 0066F00000vVBEEQA4, 0066F00000vVBESQA4), user_Name=Amit Agarwal}), name=ChangeOwnerFromFlow, namespace=null, type=apex], errors=(), invocationParameters=(already output), outputParameters=null, success=true])
References:-
Salesforce Winter 23' release notesInvocable Actions
Thank you all !
#Keep learning #Keep Sharing :)
Recent blogs:
Enhanced Lightning DataTable
Custom Toast Message in LWC
Generic Modal Box in LWC
Comments
Post a Comment