April 16, 2020

How to do a callout from Flow in Salesforce?

If Salesforce creates, updates, or deletes data in your org and then accesses external data in the same transaction, an error occurs. In your flow, we recommend using a separate transaction to access data in an external system. To do so, end the prior transaction by adding a screen or local action to a screen flow or a Pause element to an auto-launched flow. If you use a Pause element, don't use a record-based resume time. For example, a screen flow creates a contact and then displays a confirmation screen. Next, the flow updates the contact in the external system. The flow doesn’t fail because it uses a separate transaction to access the external data.
 
https://help.salesforce.com/articleView?id=flow_prep_bestpractices.htm&type=5

Remote Site Settings:



Flow:




Apex Class:

public class FlowController {
   
    @InvocableMethod( label='Create Contact' description='Create Contact using Title' category='Callout' )
    public static void getTitle( List < String > inputs ) {
       
        system.debug( 'Inputs is ' + inputs );
        createContact( inputs.get( 0 ) );
       
    }
   
    @future( callout=true )
    public static void createContact( String strInput ) {
       
        List < String > listInputs = strInput.split( ',' );
        HTTP h = new HTTP();
        HTTPRequest req = new HTTPRequest();
        req.setEndPoint( 'https://jsonplaceholder.typicode.com/todos/' + listInputs.get( 0 ) );
        req.setMethod('GET');
        HTTPResponse res = h.send(req); 
        JSONWrapper wrapper = ( JSONWrapper ) JSON.deSerialize( res.getBody(), JSONWrapper.class );
        /*
           If the response contains multiple values, then you can use the below code
           List < JSONWrapper > listWrapper = (List < JSONWrapper >) JSON.deSerialize(res.getBody(), List < JSONWrapper >.class);
        */
        Contact objContact = new Contact();
        objContact.LastName = wrapper.title;
        objContact.AccountId = listInputs.get( 1 );
        system.debug( 'Contact is ' + objContact );
        insert objContact;
       
    }
   
    public class JSONWrapper {
       
        public Integer userId;
        public Integer id;
        public String title;
        public Boolean completed;
       
    }
   
}


Output:


3 comments:

  1. I'm trying to do similar with a Scheduled Flow. I am creating a record then making an external call to an Apex Class with that record Id passed in. In that Apex class, I would like to make an update to that record. The flow runs and the Apex Class appears to be called but the record update in that apex is not working. I am able to get this to work on a screen flow but not in a scheduled flow. Any input?
    Thank you.

    ReplyDelete
    Replies
    1. That is standard limitation.
      Check this post for workaround - https://unofficialsf.com/mix-callouts-with-scheduled-flows-with-the-updated-launch-flow-dynamically/

      Delete
    2. Thank you. I will look at that workaround.

      Delete