Salesforce Get Attachment Body

I'm trying to get the body of an Attachment object in Salesforce so I can provide it to the user via utils.downloadFile(). After a lot of research and trial and error it seems it is possible to access this through a Salesforce CRUD Action with:

CRUD Action = Retrieve
Resource Type = Attachment
Resource ID = /Body

Per this Salesforce documentation, this request will return the binary content of the attachment. However this seems to be getting converted to ASCII data before I can access it. The query.data field is:

result:

It's not base64 encoded, and I can't figure out any way to serve it to the user as a file that's not corrupted.

Is there another way to access binary data from Salesforce? I'm considering connecting the Salesforce REST API directly as described here, but I'd rather not do that if I don't have to.

Hey @cgw - the short answer is that there isn't a very convenient way to do this, as Retool isn't really equipped to handle raw binary responses. I'm not even able to replicate the setup that you've outlined above, probably because I'm testing on a Lightning instance. Any attachments I upload are created as ContentDocument objects.

If you expect your users to be authenticated in Salesforce, though, one option is to just construct and give them a URL to the relevant attachment.

Have you had a chance to revisit this, @cgw?

Thanks for following up.

I came up with an ugly workaround, by making the service generating the document also put a copy in S3, which is easier to access and serve to the user. The specific purpose of this was to pull an attachment out of Salesforce for a user without an account, so pointing them at the URL in Salesforce wouldn't have worked.

1 Like

I'm glad you found a decent workaround! File management in something like S3 is generally way easier to integrate, but I understand the desire to keep everything in one place.

I've gone ahead and marked your post as the "Solution", but will keep the topic open so that I can share any future updates and so other community members can chime in. :+1:

@Darren I wanted to ask what you meant by this? It’s possible to download an s3 file in binary format, so why wouldn’t that apply to any old rest api resource?

Only that the S3 example is more an exception than the rule. It's the same with GCS, I believe. We've built those two resource connectors to support direct upload/download via signed URL, but everything else goes through the Retool backend and is typically coerced into json or text.

I see your new topic on the subject and will respond over there, but the primary workaround for exposing binary data in the frontend is to fetch the base64 encoding and convert it back. Unfortunately, I'm not sure if that will be possible with the Salesforce API.

the primary workaround for exposing binary data in the frontend is to fetch the base64 encoding and convert it back. Unfortunately, I'm not sure if that will be possible with the Salesforce API.

Thanks for the response. When you say “fetch”, do you mean using the javascript fetch api? If so, do you have a mechanism for me to get the bearer token to provide in the header, so I don’t have to manage the access/refresh tokens myself? Also, I suspect the fetch api would be called from front-end in a retool app, which obviously wouldn’t work. However, in this specific scenario I could do what I need to do in a workflow, which has js called from “backend”.

Not necessarily - any base64 response can be turned into via some JS scripting. That said, using any XHR-based API directly instead of via the Retool backend would allow you to directly capture the binary file object. You could do this in a workflow or backend function.