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);
}
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(...) {
    ...
  }
}
| improve this answer | |
  • 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 '17 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 '17 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 '18 at 0:07
  • updated the update. I forgot a important line on initial update – Olivia Jan 12 '18 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 '18 at 15:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.