Salesforce jsforce download and base64 conversion of staticresource body

442 Views Asked by At

Javascript novice and am stuck trying to convert a staticresource record body to a parseable string, and hoping someone might know how to proceed?

I have retrieved the static resource successfully using jsforce library. The resource is a csv file, and the body attribute of the result returned presents as a url ie. Body : "/services/data/v56.0/sobjects/StaticResource/resourceId/Body"

I tried to prepend the domain and url together and do this, but nothing happened..no errors, no console output; maybe the wrong approach?

// res.records[0].Body definitely returns the url for the body
// I have put 'domain' in place of my actual salesforce domain :)
const url =  'https://domain.lightning.force.com' + res.records[0].Body;
fetch(url)
.then(res => {console.log(res); });

Beyond this point I'm stuck - I've not been able to figure out how to get any further. Any suggestions on how to get from this url to actually having a usable result would be really appreciated!

2

There are 2 best solutions below

3
On BEST ANSWER

You'll need to set a HTTP header Authorisation with value Bearer {session id sometimes referred to as access token}. You'll get back the raw payload.

It looks like you got a REST API result (SOAP API would return the base64-encoded thing as is, not a link to actual content) so hopefully you're already aware of that setting the header and have a valid session id?

See also my other answer, https://stackoverflow.com/a/60284736/313628

Edit:

I don't think you should be using "lightning" url. Use what came back from login request / what you see on login page. Exact url will vary depending on production/sandbox and whether your admin started testing "enhanced domains" SF update. You'll get raw binary, not base64

Do this HTTP request in programming language of your choice

  1. login (obtain instance url and access_token a.k.a. session id)
  2. and then

"raw HTTP"

GET /services/data/v56.0/sobjects/StaticResource/0815r000000GmvmAAC/Body HTTP/1.1
Host: (redacted).my.salesforce.com
Content-Type: application/json
Authorization: Bearer 00D(redacted)

cURL

curl --location --request GET 'https://(redacted).my.salesforce.com/services/data/v56.0/sobjects/StaticResource/0815r000000GmvmAAC/Body' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer 00D(redacted)'

Here's my Postman, request was sent to a sandbox:

enter image description here

0
On

Code sample for future reference - (no vote requested...)

async function getFile(fileId) {
  let url = '/services/data/v56.0/sobjects/StaticResource/'.concat(fileId,'/Body');
  let res = '';

  const response = await fetch(url, {
    headers: {
      'Content-Type': 'application/json',
      'Authorization' : 'Bearer '+accessToken
    }
  })
  .then((response) => {
    const reader = response.body.getReader();
    return new ReadableStream({
      start(controller) {
        return pump();
        function pump() {
          return reader.read().then(({ done, value }) => {
            // When no more data needs to be consumed, close the stream
            if (done) {
              controller.close();
              return;
            }
            // Enqueue the next data chunk into our target stream
            controller.enqueue(value);
            return pump();
          });
        }
      }
    })
  })
  // Create a new response out of the stream
  .then((stream) => new Response(stream))
  // Create an object URL for the response
  .then((response) => response.blob())
  .then((blob) => blob.text())
  // Update result
  .then((chunk) => console.log(res = chunk))
  .catch((err) => console.error(err));
}