API: Upload Files from Google Drive in GAS

CODE EXAMPLE for those who use Google Apps Script…
Hope this helps others! Enjoy!
*Credit goes to the countless posters I piggy-backed off of to figure it out.

I call this function in a loop where ‘key’ is my super secret API key and everything else is pretty much spelled out. :slight_smile:

function apiUpload(key, itemID, columnID, fileURL) {

  //GET THE GOOGLE DRIVE FILE ID FROM THE FILE URL TO GET THE FILE.
  var fileID = fileURL.match(/[-\w]{25,}/);
  var file = DriveApp.getFileById(fileID);

  //YOU'LL PROBABLY NEED TO '.toString()' YOUR 'itemID' BEFORE IT GETS HERE.
  let query = "mutation ($file: File!) { add_file_to_column (file: $file, item_id: " + itemID + ", column_id: \"" + columnID + "\") { id } }";

  //BUILD THE MULTIPART REQUEST...
  //***NOTE (BECAUSE I'VE SEEN A LOT OF CONFUSION ABOUT THIS IN OTHER POSTS): THE "xxxxxxxxxx" IS LITERALLY WHAT I USE FOR 'boundary'. IT'S NOT A SECRET CODE OR ANYTHING. IT CAN PRETTY MUCH BE WHATEVER YOU WANT AS LONG AS IT DOESN'T APPEAR ANYWHERE ELSE IN THE BODY OF THE REQUEST. IT JUST ACTS AS A BOUNDARY SO THAT MONDAY KNOWS WHERE EACH CHUNK OF THE MULTIPART REQUEST TEXT (A.K.A. 'data') BEGINS AND ENDS.
  var data = "";
  var boundary = "xxxxxxxxxx";
  //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";
  //FILE PART
  data += "--" + boundary + "\r\n";
  data += "Content-Disposition: form-data; name=\"variables[file]\"; filename=\"" + file.getName() + "\"\r\n";
  data += "Content-Type:application/octet-stream\r\n\r\n";

  //THIS IS HOW WE DO IT IN G.A.S.
  var payload = Utilities.newBlob(data).getBytes()
    .concat(file.getBlob().getBytes())
    .concat(Utilities.newBlob("\r\n--" + boundary + "--").getBytes());

  //FILE UPLOADS REQUIRE A DIFFERENT ENDPOINT THAN OTHER REQUESTS (ADD "/file").
  var url = "https://api.monday.com/v2/file";
  var options = {
    "method": "post",
    "headers": { "Content-Type": "multipart/form-data; boundary=" + boundary, "Authorization": key },
    "payload": payload
  };
  var response = UrlFetchApp.fetch(url, options);
  return response;
}
2 Likes

THANK YOU!!!

I have just avoided using file columns and put files in Google folder with links to the folder on the item because I gave up making it work.

This works like a charm!!! And I did not need to convert my itemID to a string.

1 Like

Yay!!! Thanks for letting me know this helped you, Chris! I had to bash a few bricks in with my head to get there and I’m so glad to know my work is benefiting more than just me.

2 Likes