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.

5
  • whenever you call that class using scheduler, pass the current user session id in that class constructor and use that session id for callout Commented Jan 27, 2016 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 Commented Jan 27, 2016 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. Commented Jan 27, 2016 at 19:19
  • Hi @RichardDurrant. Were you able to figure this out? I am stuck with the same thing. Commented Jul 25, 2016 at 13:14
  • Were you able to figure this out? I am stuck with the same thing. Commented Mar 2, 2017 at 20:13

1 Answer 1

6

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.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.