Hi, I am working on a custom app and I have a problem with download a file operation. It is a GET request that outputs a document, in this form (we get this if we print responseData):
I am trying to output the response document in the binary object of newItem that is pushed inside returnData array, similar to the way HttpRequest node handles binary response.
Unfortunately this approach shows a blank document if I click on ‘Download’ and open the document. It seems that it’s not converted to Buffer properly for the prepareBinaryData method.
If I use the HttpRequest node, the file is received correctly, I can download it and view the PDF file.
How can I implement the binary file logic within my operation, so it has same file output behaviour as HttpRequest node? Thank you!
Please share your workflow
if (operation === 'downloadDocument') {
const documentID = this.getNodeParameter('documentID', i) as string;
const newItem: INodeExecutionData = {
json: {},
binary: {},
pairedItem: {
item: i,
},
};
const options: OptionsWithUri = {
headers: {
Accept: 'application/pdf',
},
method: 'GET',
body: {},
uri: `https://${tenant}.${server}/v1/document/id/${documentID}/download`,
json: false,
};
// Fetch the binary response data
const responseData = await this.helpers.requestWithAuthentication.call(
this,
'weclappApi',
options,
);
// Prepare the binary data and add it to the newItem
newItem.binary!['data'] = await this.helpers.prepareBinaryData(
Buffer.from(responseData),
'test.pdf',
);
// Push the newItem to the returnData array
returnData.push(newItem);
}
I appreciate your response. The solution you provided seems to be more of a workaround rather than a comprehensive solution for my scenario involving custom node development.
I’m particularly interested in understanding the proper way to handle binary files within the context of custom node development. My goal is to effectively map the binary file to a Binary property, ensuring that users can seamlessly view and download the file from my custom node. I’ve noticed that the HttpNode handles this format well, and I’m hoping to adopt a similar approach for my node.
If you have any insights or information regarding this matter, I would greatly appreciate it. Please feel free to reach out if you need any additional information from my end. Thank you!
That looks pretty similar to what I normally do and it looks like the output has the mimetype and a filesize. If you download the file is it still 80.5kb or is it 0 bytes?
Then I receive this error: ‘ERROR: body.pipe is not a function’
TypeError: body.pipe is not a function
at /usr/local/lib/node_modules/n8n/node_modules/n8n-core/src/BinaryDataManager/utils.ts:7:13
at new Promise (<anonymous>)
at binaryToBuffer (/usr/local/lib/node_modules/n8n/node_modules/n8n-core/src/BinaryDataManager/utils.ts:5:2)
at BinaryDataManager.storeBinaryData (/usr/local/lib/node_modules/n8n/node_modules/n8n-core/src/BinaryDataManager/index.ts:107:39)
at setBinaryDataBuffer (/usr/local/lib/node_modules/n8n/node_modules/n8n-core/src/NodeExecuteFunctions.ts:928:41)
at prepareBinaryData (/usr/local/lib/node_modules/n8n/node_modules/n8n-core/src/NodeExecuteFunctions.ts:1058:9)
at Object.prepareBinaryData (/usr/local/lib/node_modules/n8n/node_modules/n8n-core/src/NodeExecuteFunctions.ts:2268:3)
at Object.execute (/Users/alexnemes/Documents/Projects/N8N/Weclapp/n8n-nodes-weclapp/nodes/Weclapp/Weclapp.node.ts:577:46)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at Workflow.runNode (/usr/local/lib/node_modules/n8n/node_modules/n8n-workflow/src/Workflow.ts:1249:19)
at /usr/local/lib/node_modules/n8n/node_modules/n8n-core/src/WorkflowExecute.ts:1024:29
Code looks like this:
const responseData = await this.helpers.requestWithAuthentication.call(
this,
'weclappApi',
options,
);
// Prepare the binary data and add it to the newItem
newItem.binary!['data'] = await this.helpers.prepareBinaryData(
responseData,
'test',
);
// Push the newItem to the returnData array
returnData.push(newItem);
Interesting, You might need to do some magic then when creating the buffer. I would need to spend a bit more time on this one and maybe even play with the API but it looks like you have the data to start with and when changing it to the buffer it gets a bit confused.
What other options have you tried when working with the buffer?
Thank for the help on this one. Mainly tried the Buffer.from() method but there might also be some libraries that could help. I noticed responseData is of type string. Will also look for other approaches