0

I doing a Apex Callout to the third party API which uses the OAuth. I am beginner in the integration from Salesforce to external systems. I am successfully able to call the third party API and perform GET/POST methods.

@future (callout=true)
    public static void createSegmentD365() {
        try{
                String clientId = 'xxxxxxx';
                String clientSecret = 'xxxxxxxx';
                String tenant_id = 'xxxxxxxxxxx';
                String resource = 'xxxxxxxxxxxx';

                String reqbody = 'grant_type=client_credentials&client_id='+clientId+'&client_secret='+clientSecret+'&tenant_id='+tenant_id+'&resource='+resource;

                Http h = new Http();
                HttpRequest req = new HttpRequest();
                req.setBody(reqbody);
                req.setMethod('POST');
                req.setEndpoint('https://login.microsoftonline.com/xxxx/oauth2/token');
                HttpResponse res = h.send(req);

                deserializeResponse resp1 = (deserializeResponse)JSON.deserialize(res.getbody(),deserializeResponse.class);
                String bearerToken = resp1.access_token;

                Http http1 = new Http();
                HttpRequest req1 = new HttpRequest();
                req1.setEndpoint('https://xyz/data/parentAccounts');       
                req1.setMethod('GET');
                req1.setHeader('Authorization','Bearer '+bearerToken);
                HttpResponse res1 = http1.send(req1);

The access token I retrieved from the Authorization provider is valid for 1 hour. I am trying to understand is there a way where I can cache the access token, so I can use the cached token instead of calling the authprovider again within the 1 hour for Access Token. we wont be able to use the named credentials and looks like custom settings is deprecated. I started creating a custom metadatatype with the following fields

enter image description here

I am not able follow in any of the article how I store the credentials or how I cache the access token / refresh if the token is expired from the custom metadata. Any help greatly appreciated.

enter image description here

  • Why are Named Credentials not an option? – sfdcfox May 29 '20 at 5:27
  • @sfdcfox I tried playing with named credentials but looks like the grant type client_credentials is not supported – user81642 May 29 '20 at 10:28
1

I'd suggest you, creating a Custom Setting for it. Create three fields, Access Token, Refresh Token & expiry time. Before making a callout to the external service, check whether the token you already have in your custom setting is expired or not. If the token has expired, make Callout to the external web service & request a refresh token else use the one, you've stored.

The idea would be similar to this.

@AuraEnabled public static String validateAuthToken_Apex(){
        GDrive__c gdAuth = new GDrive__c(); //custom setting
        gdAuth = GDrive__c.getorgDefaults();
        if(gdAuth != null){
            DateTime curTime = System.now();
            if(gdAuth.Access_Token__c == null){
                //inserts access token & set expiry time of token
                return 'required';
            }
            else{
                if(curTime < gdAuth.Expires_at__c){
                    //Token isnt expired
                return 'notrequired';
                }
                else{
                    ///Request refresh token
                    Boolean response = getRefreshToken_Apex(gdAuth);
                        if(response){
                            return 'refreshed';
                    }
                    else{
                        return 'some error';
                    }
                }
            }
        }
        else{
            return 'false';
        }
    }

And while populating the access token or the refresh token in custom settings, populate Expiry time current time + 3600 seconds (as you mentioned the expiry duration)

gdAuth.Expires_at__c = System.now().addSeconds(Integer.ValueOf(gdAuthResp.get('expires_in')));

So, you might have got a case and the access token length exceeds 255 characters, Since Custom Setting hasn't got an option to create fields of TEXTAREA(long) which can hold values in that case. So you'd need to create Custom Metadata instead of Custom Setting. Yes, the procedure is pretty same except you'd need a class that implements Metadata.DeployCallback interface. So,

public class CreateUpdateMetadataUtils implements Metadata.DeployCallback {

}

And unlike custom settings, metadata are used with __mdt though the fields would have __c. Once you done creating the Custom Metadata, write your class to populate the fields. Refer here.

  • Looks like Custom Setting is deprecated. Can I know what you do in the getRefreshToken_Apex() – user81642 May 29 '20 at 4:34
  • What do you mean Custom Setting is deprecated? Like its not an option for you? In this method, you can refresh your access token if the web service supports refresh tokens. – Sachin Hooda May 29 '20 at 4:36
  • Added the screenshot of the recommendation I see when creating the Custom Setting – user81642 May 29 '20 at 4:37
  • You wouldn't need a list of records, the default one will work for it. The only limitation I know using Custom Setting you'd face is, you won't be able to retrieve the records in your custom setting using ANT tools like Workbench. However, a post-install script will get your work done, in this case. – Sachin Hooda May 29 '20 at 4:41
  • 1
    @SachinHooda P.S. A text field retrieved from the database will never be the empty string (''). TMYK. – sfdcfox May 29 '20 at 5:29

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.