3

Is it possible to set either the @InvocableMethod or Process.Plugin with a @future(callout=true)?

My problem (bear with me):

  1. I have a trigger that calls a class
  2. the class creates an object and calls another class
  3. this class creates more objects and calls a flow
  4. the flow (is quite lengthy) eventually fires off a Process.Plugin apex class, that has input and output data and calls a webservice.

When I call the flow normally from the Trigger I get error:

System.CalloutException: Callout from triggers are currently not supported.

So I attempt to make the call out a future and I get error:

Future methods do not support parameter type of Process.PluginRequest

Which then leads me to question if I should try to re-write my Process.Plugin class to an Invocable class. When I create a mock Invocable class with the @future annotation I get error:

The only annotation that can be used with InvocableMethod is Deprecated

The greater question is- is there another way to call a callout from a trigger without using the @future annotation?

I found this question but it is from 2012.

UPDATE: follow up question:

//The main method to be implemented. The Flow calls this at runtime.
global class FlowToWebservice_Class implements Process.Plugin {
    public static Map<String,Object> result = new Map<String, Object>();

global Process.PluginResult invoke(Process.PluginRequest request){
    varProcessName = (String)request.inputParameters.get('varProcessName');
    varCreditReviewId = (String)request.inputParameters.get('varCreditReviewId');
    callWebService(varProcessName , varCreditReviewId);
    return new Process.PluginResult(result);
}

@future(callout=true)
global static void callWebService(String processName, String crId) {
    req = new HttpRequest();
    req.setEndpoint(endpointURL);
    req.setMethod('POST');
    req.setBody(k);
    req.setHeader('Content-Type', 'application/json');
    req.setTimeout(120000);
    string d = getAuth();
    req.setheader('Authorization', d);
    try {
        Http h = new Http();
        res = h.send(req);
        JSONParser parser = JSON.createParser(res.getBody());
        while (parser.nextToken() != null) {
            if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) && (parser.getText() == 'Status')) {
               ...
           }
        }
    }
    catch (System.CalloutException z) {
        system.debug('z: ' + z);
    }

    //output params
    result = new Map<String,Object>();
    result.put('varResult',finalDecision);
    result.put('varROSID', relatedOppSearchId);
    result.put('varDeclineReason', declineReason);
}

1 Answer 1

4

No, you can't use a web service call in a trigger context. Instead, you have call the @future method from the InvocableMethod method:

public class XYZ {
  @InvocableMethod(Description=...) public static void process(...) {
    callWebService(...);
  }
  @future(callout=true) public static void callWebService(...) {
    ...
  }
}
5
  • I see, I assume I can do this same thing with Process.Plugin? I could do the same thing long the lines of: global static Process.PluginResult invoke(Process.PluginRequest request) {callWebService(...);}, I am trying it out now...
    – Olivia
    Dec 19, 2017 at 18:30
  • @Olivia Yes, you can call a future method from either, you just can't declare either as a future method.
    – sfdcfox
    Dec 19, 2017 at 18:32
  • I have a follow up to this question - when I call the method callWebService(), I can't have a return statement because it is a future method, and when I update a static variable with the returned parameters within the future method, the values do not get carried over to the return statement on the invoke() method. How would I go about passing back the output parameters? See updates for better explanation.
    – Olivia
    Jan 12, 2018 at 0:07
  • updated the update. I forgot a important line on initial update
    – Olivia
    Jan 12, 2018 at 14:15
  • @Olivia It probably would have been better as a new question, but it doesn't really matter, since the answer is the same; you can't synchronously call out during a trigger. They've never allowed this, and probably never will. You can perform a DML update on the record after making the callout. Make sure you check to see if you're already in @future context so that you don't get recursion errors (you can't call a future method from a future method).
    – sfdcfox
    Jan 12, 2018 at 15:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .