Best answer

"File Object" output, need a how-to

  • 31 May 2023
  • 4 replies
  • 662 views

Userlevel 2
Badge +1

I am researching for a way to export a file from our application into another app like Google Drive. However I’m running into some difficulty hydrating the file or making it a file object as described in https://help.zapier.com/hc/en-us/articles/8496259603341#file-fields-0-4

In my action step using the code below I’m taking a encoded file from our database and doing a base64 decode to get the file name, file type, the buffer stream, and buffer stream length.

const encodedFile = bundle.inputData.file;
const decodedFile = Buffer.from(encodedFile, 'base64').toString('utf-8');

var fileByte = Buffer.from(decodedFile.substring(decodedFile.indexOf('<File>')+6,decodedFile.indexOf('</File>')), 'base64').toString('utf-8');
var filetype =Buffer.from(decodedFile.substring(decodedFile.indexOf('<FileType>')+10,decodedFile.indexOf('</FileType>')), 'base64').toString('utf-8');
var filename = Buffer.from(decodedFile.substring(decodedFile.indexOf('<UploadedFileName>')+18,decodedFile.indexOf('</UploadedFileName>')), 'base64').toString('utf-8');
//Buffer.from(decodedFile.substring(decodedFile.indexOf('<File>')+6,decodedFile.indexOf('</File>')), 'base64').toString('utf-8')
//output = { type: filetype, name: filename, file: fileByte };

return {'myFile':z.stashFile(fileByte,fileByte.length,filename,'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')};

Unfortunately the result is an empty value. 

I’m looking for some guidance on this as there doesn’t appear to be a lot of documentation or examples showing how to display the files in hydrated format and since files are in the database there isn’t a public url available to pull the file from.

 

 

icon

Best answer by Arment 17 June 2023, 22:40

View original

This post has been closed for comments. Please create a new post if you need help or have a question about this topic.

4 replies

Userlevel 4
Badge +9

Hey @Arment 👋

A little confused if you’re trying to implement a trigger that provides a file object to a Zap (for use in later actions, such as Upload to Google Drive) or an action that takes the file object from a trigger (such as File Upload in Google Drive) and uploads it to your app - you’ve mentioned both in your post so just making sure 😀

We have an example app with implementing both a trigger and an action here: https://github.com/zapier/zapier-platform/tree/main/example-apps/files 

Looking at your code, I see you’re using z.stashFile as documented here: https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md#stashing-files but you’ve noted your file is not publicly available.  Does the software you’re trying to build an app for on Zapier have an API that you can authenticate to and where a link to that file could be retrieved? 

Userlevel 2
Badge +1

Hi @MarinaH,

I’m looking to implement both a trigger and an action so we can move file objects to and from our database using the API from our software. 

The files are stored inside the database in a base64 encoded format. We can retrieve the file from the API and decode it but not sure how to transform it into a file object. Our software has the files irretrievable by URL for security reasons. Looking at the example app I assume this would require the files to be accessible via URL. Is there any option we have besides a public URL that can create a file object for our trigger step?

Userlevel 4
Badge +9

Hey @Arment,

Thanks for confirming! Let’s focus on the trigger to start with. Yes, this should be possible, even if the file is not accessible via URL. 

z.stashFile should accept any String, Buffer or Stream. If your API returns a base64 encoded string as response data, you could create a Buffer and pass that into z.stashFile directly, something like:

const file = z.stashFile(Buffer.from(response.data, 'base64'))

If the code you’ve provided above is not returning as expected, go ahead and add z.console at every step to confirm what data is being received

Once you’ve got that added (you can see those logs for yourself in the Monitoring tab), open a ticket with us from https://developer.zapier.com/contact so we can review those logs with you if they’re still unclear.     

Userlevel 2
Badge +1

I did add z.console and can confirm the buffered file looks right in the Monitoring tab but the z.stashFile output still doesn’t look right. Also for some reason the z.console output displays as an error message in the Monitoring tab. 

 

I’ll open a ticket and see if I can make further progress.

EDIT:

Just had a eureka moment and added “await” before z.stashFile, I should have picked up on it earlier as an async function. Below is my code if that helps someone with converting a buffered file into a file object. Thank you @MarinaH!

 

const encodedFile = bundle.inputData.file;
const decodedFile = Buffer.from(encodedFile, 'base64').toString('utf-8');

var fileByte = Buffer.from(decodedFile.substring(decodedFile.indexOf('<File>')+6,decodedFile.indexOf('</File>')), 'base64');
var filetype =Buffer.from(decodedFile.substring(decodedFile.indexOf('<FileType>')+10,decodedFile.indexOf('</FileType>')), 'base64').toString('utf-8');
var filename = Buffer.from(decodedFile.substring(decodedFile.indexOf('<UploadedFileName>')+18,decodedFile.indexOf('</UploadedFileName>')), 'base64').toString('utf-8');
//Buffer.from(decodedFile.substring(decodedFile.indexOf('<File>')+6,decodedFile.indexOf('</File>')), 'base64').toString('utf-8')
//output = { type: filetype, name: filename, file: fileByte };
z.console.log(fileByte);
z.console.log(Buffer.from(decodedFile.substring(decodedFile.indexOf('<File>')+6,decodedFile.indexOf('</File>')), 'base64').toString('utf-8'));
const stashedfile = await z.stashFile(fileByte, fileByte.length, filename, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
return {'myFile':stashedfile, 'filetype': filetype, 'filename': filename};