5

I have a system that is posting data to a streaming channel which works upon data changing and a trigger firing.

The a code snippet is shown below.

        string sessionId = UserInfo.getSessionId();    
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();

        req.setEndpoint(uri);
        req.setMethod('POST');
        req.setHeader('Authorization', 'Bearer '+sessionId);


        string body = '{"pushEvents":[{"payload":"'+payload.escapeJava()+'", "userIds":[]}]}';


        req.setHeader('Content-Type', 'application/json');
        req.setBody(body);

        req.setCompressed(true); // otherwise we hit a limit of 32000

        try {
            res = http.send(req);                
        } catch(System.CalloutException e) {
            System.debug('Callout error: '+ e);
            System.debug(res.toString());

        } catch(System.Exception ex){
          System.debug(res.getStatusCode());
          System.debug(res.toString());
        }

I now need to call this code via scheduled apex and so now the sessionid is coming in null as its asynchronous.

What I can do is use OAuth to get an access token and use this for authentication. There is quite a lot of setup to this and storing usernames/passwords/securitytokens (and managing them) is something that doesn't appeal!

I have come across the Named Credentials functionality and wonder if this is something I can leverage? Anybody tried this?

I have tried

HttpRequest req = new HttpRequest();
req.setEndpoint('callout:Salesforce');
req.setMethod('POST');

Http http = new Http();
HTTPResponse res = http.send(req);


System.debug(res.getBody());

where Salesforce is the Named Credential with the following details:-

The result from Developer Console is

12:05:11.560 (560650534)|CALLOUT_RESPONSE|[6]|System.HttpResponse[Status=Bad Request, StatusCode=400]
12:05:11.560 (560668002)|HEAP_ALLOCATE|[6]|Bytes:96
12:05:11.560 (560819528)|VARIABLE_ASSIGNMENT|[6]|res|"System.HttpResponse[Status=Bad Request, StatusCode=400]"|0x319e2ef7
12:05:11.561 (561088589)|USER_DEBUG|[9]|DEBUG|{"error":"unsupported_grant_type","error_description":"grant type not supported"}

Any help appreciated.

  • whenever you call that class using scheduler, pass the current user session id in that class constructor and use that session id for callout – Ratan Paul Jan 27 '16 at 12:10
  • @Ratan I am calling this from batch apex and so the session isn't guaranteed to be available. Sessions time out and expire due to user logout so I'm looking for a 'proper solution' here – Richard Durrant Jan 27 '16 at 12:12
  • Try checking this question. Its in C#, not apex, but when I was having a similar error in apex, the question was helpful to determining the cause. – battery.cord Jan 27 '16 at 19:19
  • Hi @RichardDurrant. Were you able to figure this out? I am stuck with the same thing. – AslamK Jul 25 '16 at 13:14
  • Were you able to figure this out? I am stuck with the same thing. – user40703 Mar 2 '17 at 20:13
5

You can do this, but you'll need to do a bit more work to use it.

  • First, Create a connected app with oAuth, select refresh_token (at a min) for the oAuth scope
  • Second, Create an auth provider of the salesforce type. Give it the oauth consumer key and consumer secret that you got when you created the connected app.
  • Finally, create a Named Credential using oauth, and your auth provider. When you save the named credential, it will prompt you to log in to a SF org.

Once you've logged in there, the refresh token is saved and used by the named credential. From there, you can make callouts to access data. Note whatever user you login as there is the user your api calls will run as.

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.