What Controls the URL Format for Chatter Content?

All we need is an easy explanation of the problem, so here it is.

When I query the chatter connect API through Javascript from a Visualforce page in a desktop browser, the post attachment URLs I receive use the visualforce domain that the page is being served up from, e.g.

https://c.eu5.content.force.com/sfc/servlet.shepherd/version/renditionDownload?rendition=THUMB240BY180&versionId=06824000000WLNl&operationContext=CHATTER&contentId=05T24000001IInS`

If I use this as the background image via CSS, then the browser sends a cookie along with the request with the relevant authentication information. So far, so good.

Without a Cookie

If I don’t have a cookie, say I just paste the URL into a different browser, then I can simply add a session id parameter to the URL (&sid=blahdeblahblah) and it also works. So far, still good.

From a Connected App

I have an iOS app that authenticates users through OAuth using the Salesforce Mobile SDK, and then it uses a method in the SDK to get an authenticated URL to the Visualforce page that I was previously accessing in the desktop browser.

Now, when the same javascript queries the Chatter connect API, the URLs returned are relative, and look like this:

/services/data/v33.0/chatter/files/06924000000NdruAAC/rendition?type=THUMB240BY180

and so if I try to use this as a CSS background image, the webview (WKWebView) attempts to load this URL:

https://c.eu5.visual.force.com/services/data/v33.0/chatter/files/06924000000NdruAAC/rendition?type=THUMB240BY180

And now things are not so good. The WKWebView does not send an authentication cookie along with this request and so it fails to load with an invalid session ID error, and I’ve been unable to find a URL parameter that I can add to this to make it work (I’ve tried sid, oauth_token and _bearer which all seem
to have some use in various places).


Send Help!

I’m assuming the API is returning different URLs due to the session ID being used, because I can’t seem to use a session ID from the iOS app in the first URL format. This rules out any cludgey solutions such as using a hard-coded URL.

So… Is there a way to either

1. set specific OAuth scopes to get URLs in the first format that will work? or,

2. use a session id parameter of some kind with the second URL format that won’t give me a session ID error?

Failing either of these options I’m going to have to find some way to download the images via Javascript and the API and that just plain sucks.

Extra notes:

I’m using these OAuth scopes at present:

  • Access your basic information (id, profile, email, address, phone)
  • Access and manage your data (api)
  • Provide access to your data via the Web (web)
  • Provide access to custom applications (visualforce)
  • Perform requests on your behalf at any time (refresh_token, offline_access)

I previously had everything selected and hoped that by removing the Chatter option it might change the response URLs but no luck 🙁

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Well I couldn’t find a way to get the first style URL when using an OAuth initiated session, but I did find a way to make the CSS background-image work with the /services/data URLs.

First:

Make an authorised (i.e. a request with the correct headers) JavaScript request to the Chatter API using the relative URL provided, e.g. /services/data/v33.0/chatter/files/06924000000NdruAAC/rendition?type=THUMB240BY180 before the div with the background image is rendered.

Second:

Job done. The prior request results in the image being cached for the URL, and so subsequent requests from CSS/<img> tags without the headers still get the cached result.


Disclaimer

Yes, this is hacky. Ideally the binary data returned should be base64 encoded and used in an image Data URI, but then I’d need to deal with other issues such as working out the image format. This works for my approach works for my purposes and I’m in control of the environment, so I’m happy to use it. Be wary if you use this technique and you don’t know what Browser/OS combo your users will be using.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply