Upload CSV with HTTP Request

Hey there,

I want to upload a CSV file to an HTTP Endpoint.
Right now, I am trying to figure out if this is actually possible.

Documentation can be found here:

It would be cool if somebody could tell me if this should be possible with n8n before I put in hours of work in desperation.

Thank you!

Hi @nkos,

This should be possible but is a bit tricky in n8n at the moment. From looking at the documentation you have linked it seems the API requires binary and JSON data in a single request. This is a bit tricky with n8n and requires using the Function node. @RicardoE105 has built an example workflow implementing this which you can check out here:

So with this in mind you might find it easier to read the CSV file in n8n and then use an endpoint not requiring binary and JSON data combined (possibly this one). This would allow to use the HTTP Request node instead of the more complex Function node.

1 Like

Hey @MutedJam ,

thank you for your reply.
Glad to hear that it is possible at least.

I tried out the Function that @RicardoE105 posted in the other topic.
Unfortunately, I don’t know exactly how to adapt the code so that it works for me, since I’m not that deep in JavaScript or coding in general.

Right now my workflow looks like this:

When I run the workflow I get the following error:

I would be very grateful if someone could help me with this.
Many thanks in advance.

Got it done. It works for me now. Thanks a lot anyway.

1 Like

Hi @nkos, I am sorry I couldn’t get back to you sooner but I am really glad to hear you managed to sort it out. Maybe you can share your solution to other users stumbling across this thread can benefit from it?

Sure, I can do it with pleasure.
I changed the function a bit, so that the upload of the CSV file worked. I post my workflow here to show the changes I made.

1 Like

I hope it’s OK to sort of hijack this here but I have been using @RicardoE105 example mentioned above on an older version of n8n and it seems to have broken for me on 0.171.0

The execution fails with

ERROR: Cannot read properties of undefined (reading 'split')

Can you share the stack trace?

Sure thing :slight_smile:

TypeError: Cannot read properties of undefined (reading 'split')
    at Object.execute (/home/waffle/.nvm/versions/node/v17.8.0/lib/node_modules/n8n/node_modules/n8n-nodes-base/nodes/Function/Function.node.ts:156:84)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at /home/waffle/.nvm/versions/node/v17.8.0/lib/node_modules/n8n/node_modules/n8n-core/src/WorkflowExecute.ts:814:26

and here’s the function node’s code

const request = require('request-promise-native');

const binaryData = items[0].binary.data;

const metadata = {
  name: binaryData.fileName,
  parent: { id: 123 }
}

const options = {
  uri: 'https://api.lexoffice.io/v1/files',
  headers: {
    'content-type': 'multipart/form-data',
    'Authorization': 'Bearer xxxxxxxxxxxxxxxxxxxxxxxxx',
  },
  formData: {
    file: {
      value: Buffer.from(binaryData.data, 'base64'),
      options: {
	    filename: binaryData.fileName,
	    contentType: binaryData.mimeType,
	  },
 	},
    type: "voucher",
    attributes: JSON.stringify(metadata),
  },
  method: 'POST',
}

await request(options);

return [{ json: {} }]

EDIT: forgot to mention, this code works fine in 0.123.1

n8n uses currently node V16. I wonder if there an issue because you are using node V17.

Are you sure there is a binary object for the first input item? It might be worth checking to see if it exists first and exit if needed.

This might very well be it. I followed this guide here because I have a requirement where I need to pass requests via python :frowning:

I would be very grateful if anyone could point me into a direction where to begin reading on how to bring my n8n environment to v16. I don’t really know my way around node and wouldn’t even know what terms to search for.

@jon
there’s definitely a binary object which is a PDF file that I’m pulling from my Zammad instance

Did you update node at the same time as updating n8n? I would still put a check in to make sure you have binary data just to rule out any potential issues in the future.

To change your node version you can look into Node Version Manager (nvm) which makes it a lot easier to manage different versions.

Does the workflow always fail as well or just some of the time?

1 Like

Did you update node at the same time as updating n8n?

It’s a fresh install from a couple days ago I tried bringing the workflow over from an old instance that I want to decommission soon

I would still put a check in to make sure you have binary data just to rule out any potential issues in the future.

I did check and probably should’ve mentioned that my first attempt at troubleshooting was to log something in the console since I wasn’t using the split function and I didn’t really know where the error came from.

The error occurs at this line:

await request(options);

To change your node version you can look into Node Version Manager (nvm) which makes it a lot easier to manage different versions.

Thanks! I’ll look into it, I have already installed node via nvm as per the guide linked above so I should be able to work things out

Does the workflow always fail as well or just some of the time?

Always fails

Hey all, sorry for jumping in here. However, seeing that this code was working in 0.123.1 I figured it might be worth a shot. The approach to accessing binary data has changed in v0.135.0.

Instead of accessing your binary data directly, could you try using await this.helpers.getBinaryDataBuffer(itemIndex, binaryPropertyName)?

Do you mean like this?

value: Buffer.from(await this.helpers.getBinaryDataBuffer(0, "data"), 'base64')

Not sure if I’m using this correctly but it produces the same error

I was more thinking something like this in your Function node:

const request = require('request-promise-native');
const binaryData = items[0].binary.data;
const data = await this.helpers.getBinaryDataBuffer(0, 'data');

const metadata = {
  name: binaryData.fileName,
  parent: { id: 123 }
};

const options = {
  uri: 'https://webhook.site/b34c5fc9-f079-4460-a069-c5224b8130a4',
  headers: {
    'content-type': 'multipart/form-data',
    'Authorization': 'Bearer xxxxxxxxxxxxxxxxxxxxxxxxx',
  },
  formData: {
    file: {
      value: Buffer.from(data, 'base64'),
      options: {
        filename: binaryData.fileName,
        contentType: binaryData.mimeType,
	  },
 	},
    type: "voucher",
    attributes: JSON.stringify(metadata),
  },
  method: 'POST',
}

await request(options);

return [{ json: {} }]

Testing this using webhook.site worked fine, both the text data and the binary file arrived as expected:

Sweet, In that case try the node version and we can go from there, Do you know what version of node the old instance is using or is it all on the same machine?

Doesn’t work for me, this leads me to believe it is indeed an Issue with me being on node v17. I should get some time to tinker with nvm tonight or tomorrow to verify.

Thanks for your help, y’all are awesome!

So I figured out how to change the node version and…

…it didn’t work.

However, I noticed there was some funky stuff going on with how Zammad returned the ticket attachments. In particular the binary file names were not the actual filenames but the ticket id (without file extension). Zammad does return the actual filename in the json payload though and things work when I use that. I figure there’s something going on with split() not working during the request because of the missing file extension.

Hats off to you @jon for being suspicious about my binary object :smiley:

1 Like