I am trying to connect Salesforce with GoToWebinar (GTW) to automate webinar activities within my Salesforce app. I am attempting to use Named Credentials (OAuth2) to authenticate with GTW.

I have followed their documentation on how to authorise users, and also found another posted on here in another question thats experienced issues.

Following both pages I created the following:

GTW OAuth Client

Auth Provider enter image description here (the callback URL is added in the GWT OAuth client settings)

Self Signed Cert

enter image description here

Named Credential

enter image description here

When I save the Named Credential it initiates the auth flow, but GTW returns an unexpected error, problem is because its all in the UI I can't really debug what the issue is.

I have also tried running the following anon apex to run a test endpoint request:

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

This returns a 403 error in the response.

Can anyone help me debug this issue?


I was able to set up a named credential to GoToWebinar(trial version) on my developer org and also get a successful HTTP response (status code 200) for the anonymous apex code given in your question. As mentioned in the other link in your question, enabling 'Send client credentials in header' in the Auth provider settings is essential.

The problem I see in your screenshots are the scope values (for both Auth Provider & Named credential). According to Salesforce documentation here,valid scopes vary depending on the third party; refer to your third-party documentation. But the values you have used are Salesforce scopes (which are invalid for GTW). Hence, when OAuth flow is initiated (upon Named credential save), GTW doesn't recognize the value as valid scope and refuses to authenticate & authorize. In your case, you should be referring to client app (OAuth client) created in GoToWebinar for valid scope values (see screenshot below for reference)

enter image description here

The valid scope value for the client app shown in this screen shot is 'identity:scim.me collab:' and you should be specifying this value either in the Auth providers settings or in the Named credential. It's not required to specify in both the places. The scope specified in Named credential will override the default scope specified in the Auth Provider. If scope is not specified in Named credential, then the Auth provider scope will be used.

Also, your apex code is missing the required query parameters (fromTime & toTime) for the REST endpoint. Refer to the official documentation here. GTW will respond with a HTTP 403 or 401 for incorrect endpoints. With the correct parameters, I was able to get a successful response.

UPDATE: [This section outlines a specific problem related to access token expiry and how it is handled between Salesforce & GoToWebinar.]

Enable 'Allow Merge Fields in HTTP Header' in the Named Credential settings. This seems to be essential for fetching a new access token after the existing access token expires. [The screenshots in your question shows this option enabled, but not sure if you had this disabled later]

enter image description here

The access and refresh token received from GTW during the initial auth handshake are valid for 60 min and 30 days respectively. After the access token expires, any web request sent to GTW should send an 401 HTTP status response and the caller (in our case SF thru Named Credential & Auth Provider) should be able to fetch a new access token using the refresh token. But, unfortunately that doesn't happen because GTW sends HTTP status codes 403 or 400 for any request that is missing parameter or has incorrect end point URLs. So, a new access token is not fetched and the web request fails.

Although, I couldn't find any official documentation from Salesforce, enabling 'Allow Merge Fields in HTTP Header' seems to send additional required parameters in the callout and GTW is able to respond with a new access token.

Hope this helps.

  • Thanks Arut for your detailed response, would you be able to detail how to refresh the token given the limitations with the response codes? I have created a mock callout to callout:GoToWebinar/webhooks which doesn't exist but this returns a 403 error instead of the 401 error expected so my tokens aren't refreshed. – Deployment Failure Jul 29 '20 at 14:09
  • I believe that the confusing response codes is probably due to a bug in the rest api implementation at GTW (or intentionally done as per their design), with final outcome being the response indicating successful auth but that something went wrong in the request. In your case 403 indicates forbidden request (I would have expected a 404 response) and doesn't say that the authentication was unsuccessful (or access token expired). – arut Jul 29 '20 at 14:33
  • Could you tell me if you are able to send an expired access token in this mock callout scenario and get an incorrect response? As per my knowledge, the initial authentication/ authorization should return a JSON (or whatever content-type is specified in the request) with access token as well as refresh token. So, your code should work fine when the access token actually expires. – arut Jul 29 '20 at 14:41
  • If you are able to actually replicate the scenario, then a custom impl of auth provider may be required (utilizing the GTW endpoints to get refresh token), but I don't think that is required. The TokenEndPoint URL in the Auth Provider settings is the URL to get the refresh token and hence, Salesforce should automatically handle that for you. – arut Jul 29 '20 at 14:42
  • So what I did was simply create that callout that I mentioned above which doesn't exist in anonymous apex to test to see if I could still access the REST endpoint an after a successsful callout (thats how long the tokens last for). My original plan although not best practise was to simply check if I get a 403 response and then make the fake callout and then try again but this doesn't appear to work as expected. – Deployment Failure Jul 29 '20 at 14:44

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.