Uploading a file to a column with the Api

I’m trying to upload a file to a column using the monday api through node app. I took an example from github and modified the query to upload to a column. I get this error when I run the program.

{ error_message: ‘Unsupported query’, status_code: 400 }

I can’t tell what the issue is with the query to monday or if there’s another issue in the code. The code I used is posted below.

/// those are the main dependecies you’ll need to have installed in this example;
const fs = require(‘fs’);
const fetch = require(‘node-fetch’);

/// Replace with your actual API Key
const API_KEY= “XXXXXXXXXXXX”;

/// Notice the /file/ endpoint - only this endpoint will support variables in this type of call
const url = ‘https://api.monday.com/v2/file’;

/// This is your mutation query - can also be adapted to send files to file columns instead
const query = ‘mutation add_file($file: File!, $itemId: Int!) {add_file_to_column(item_id: $itemId, column_id: 'file', file: $file) {id}}’

/// These are the variables you are sending. Can be adapted to a call that would add the file to a file oclumn instead;
var vars = {“updateId”:1234};

///This is the mapping for the API call, where you specify that a variable should be considered as the variables[file] of the request.
///This can be called “image”, or simply file - as long as it matches the name of the multipart request later down the line.
var map = {“file”:“variables.file”};

/// this is the path to the file you’d like to upload to monday.com
var upfile = ./test.xlsx;

var data = “”;
const boundary = “xxxxxxxxxxxxxxx”;

fs.readFile(upfile, function(err, content){

// simple catch error
if(err){
    console.error(err);
}

//below, we will construct a multipart request. Take a look at the "name" within each part, as those will refer to different parts of the API call.

// construct query part
data += "--" + boundary + "\r\n";
data += "Content-Disposition: form-data; name=\"query\"; \r\n";
data += "Content-Type:application/json\r\n\r\n";
data += "\r\n" + query + "\r\n";

// construct variables part
data += "--" + boundary + "\r\n";
data += "Content-Disposition: form-data; name=\"variables\"; \r\n";
data += "Content-Type:application/json \r\n\r\n";
data += "\r\n" + JSON.stringify(vars)  + "\r\n";

// construct map part
data += "--" + boundary + "\r\n";
data += "Content-Disposition: form-data; name=\"map\"; \r\n";
data += "Content-Type:application/json\r\n\r\n";
data += "\r\n" + JSON.stringify(map)+ "\r\n";

// construct file part - the name needs to be the same as passed in the map part of the request. So if your map is {"image":"variables.file"}, the name should be image.
data += "--" + boundary + "\r\n";
data += "Content-Disposition: form-data; name=\"file\"; filename=\"" + upfile + "\"\r\n";
data += "Content-Type:application/octet-stream\r\n\r\n";
var payload = Buffer.concat([
        Buffer.from(data, "utf8"), // data has update id and mutation query
        new Buffer.from(content, 'binary'),
        Buffer.from("\r\n--" + boundary + "--\r\n", "utf8"),
]);

// construct request options
var options = {
    method: 'post',
    headers: {
      "Content-Type": "multipart/form-data; boundary=" + boundary,
      "Authorization" : API_KEY
    },
    body: payload,
};

// make request
fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json));

});

hi @pwolter
Welcome to the community. Although I did not do file upload in any of my Node projects (yet) I struggled some time ago with a PHP project.

$eol = “\r\n”;

$header = array(
‘User-Agent’ => MONDAY_TEAM . ’ GraphQL Client’,
‘Authorization’ => get_field(‘mondaykey’, ‘user_’ . get_current_user_id()),
‘Content-Type’ => ‘multipart/form-data; boundary=’ . $boundary
);

//We need to build the body from scratch because it is multipart with boundaries
//Take care of the extra empty lines (twice $eol) before the actual query and file, otherwise an error 500 is returned

$body = ‘–’ . $boundary . $eol;
$body .= ‘Content-Disposition: form-data; name=“query”’ . $eol . $eol;
$body .= 'mutation ($file: File!) {add_file_to_column (item_id: ’ . $item_id . ‘, column_id: file, file: $file) {id}}’ . $eol;
$body .= ‘–’ . $boundary . $eol;
$body .= ‘Content-Disposition: form-data; name=“variables[file]”; filename="’ . $upload[‘name’] . ‘"’ . $eol;
$body .= 'Content-Type: ’ . $upload[‘type’] . $eol . $eol;
$body .= file_get_contents($upload[‘value’]);
$body .= $eol . ‘–’ . $boundary . ‘–’;

$response = wp_remote_post( MONDAY_URL . ‘file/’, [‘headers’ => $header, ‘body’ => $body] );

Maybe this snippet help you.

Are you trying to upload a JSON in the file column? (Content-Type)

I’m hoping we can get more clarity from the Monday development team on this one.

Most SDKs and APIs that allow for file transmission are specific in the documentation for how the file itself is transmitted.

Especially knowing that Monday uses AWS for it’s file downloads, I’m assuming all files are posted to AWS.

The format for pushing a file to AWS is fairly straight forwards using a buffer of the file, mime type, and title. I’m quite amazed this is such a difficult integration to create on Monday, and that we are stuck having to format parts of the body on our own. Updated documentation on uploading a file using a synchronous upload or a stream would go a long ways towards making this function useful.

Hi @pwolter!

To troubleshoot your request, I would recommend starting from the basics and verifying that you have the correct file path, file, authorization token, etc.

One thing I did see is that you’re using a “itemId” variable, but you’re not defining it anywhere (that I can see). Do you mind letting me know where you’re setting it? Could this be the error you’re running into?

Please let us know if the issue persists and we can continue troubleshooting this together.

@morhriveion, thanks for your feedback here! Perhaps this is a conversation for a separate thread, but I would love to learn more about the specific gaps in our documentation on file uploads. In any case, documentation on file uploads with our API is indeed something our team is looking on improving and making more robust.

I was able to do some initial digging into the documentation for file uploads for Slack, AWS, and Spotify and there’s a lot of variance. In terms of what you would find the most helpful, would it be more specificity as to what happens in the backend when a file is uploaded?

Or would you like more documentation as to what devs need to construct when making a file upload? We do have an example of constructing a file upload request from scratch as created by my colleague, I’m not sure if you’ve had a chance to check it out yet: Uploading a file to the monday.com API, from basics · GitHub.

Let me know! I look forward to continuing the conversation.

1 Like

Best way to try file uploads on Monday.com in any code is to use Postman

Once it works, Postman has code in most languages. Doing file uploads with Php and Python has been easy with this approach.

For Node, i got the below code snippet.
var request = require(‘request’);
var fs = require(‘fs’);
var options = {
‘method’: ‘POST’,
‘url’: ‘https://api.monday.com/v2/file’,
‘headers’: {
‘Authorization’: ‘Bearer XXX’
},
formData: {
‘variables[file]’: {
‘value’: fs.createReadStream(‘/C:/Users/rrr/Desktop/hall.jpg’),
‘options’: {
‘filename’: ‘/C:/Users/rrr/Desktop/hall.jpg’,
‘contentType’: null
}
},
‘query’: ‘mutation ($file: File!) { \n add_file_to_column (file: $file, item_id: XXXX, column_id: “files”) { \n id \n } \n}’
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});

1 Like

I made a typo in the code I posted here. “updatedId” should be "itemId. I was able to get the code to work by changing the single quotes on column_id:‘file’ to double quotation marks column_id:“file”. Thanks for your help!

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.