Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Multipart-POST Request Using Google Apps Script

Multipart-POST Request Using Google Apps Script

April 20, 2019: GAS library for this situation was published. Please check it at https://github.com/tanaikech/FetchApp.

These sample scripts are for requesting multipart post using Google Apps Script.

In most cases, the multipart request is used for uploading files. So I prepared 2 sample situations as follows. For each situation, the request parameters are different.

  1. Upload a file from Google Drive to Slack.
  2. Convert an excel file to Spreadsheet on Google Drive using Drive API v3.

Multipart post is required for these situations.

1. Uploading Files From Google Drive To Slack

Curl Code

In order to use this sample, please retrieve access token for uploading file to Slack.

If curl is used for this situation, the curl code becomes as follows. But this code uploads a file on local PC to Slack. The detail information is here.

curl -X POST -sSL \
     -F token=### access token ### \
     -F channels=### channel ID ### \
     -F filename=### filename on Slack ### \
     -F title=### title on Slack ### \
     -F file=@### filename ### \
     "https://slack.com/api/files.upload"

Google Apps Script

When above curl code is changed to GAS, the script becomes as follows.

function request_slack1() {
  var fileId = "### file ID on Google Drive ###";
  var metadata = {
    token: "### access token ###",
    channels: "### channel ID ###",
    filename: "### filename on Slack ###",
    title: "### title on Slack ###",
  };
  var url = "https://slack.com/api/files.upload";
  var file = DriveApp.getFileById(fileId);
  var boundary = "xxxxxxxxxx";
  var data = "";
  for (var i in metadata) {
    data += "--" + boundary + "\r\n";
    data += "Content-Disposition: form-data; name=\"" + i + "\"; \r\n\r\n" + metadata[i] + "\r\n";
  }
  data += "--" + boundary + "\r\n";
  data += "Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"\r\n";
  data += "Content-Type:" + file.getMimeType() + "\r\n\r\n";
  var payload = Utilities.newBlob(data).getBytes()
    .concat(file.getBlob().getBytes())
    .concat(Utilities.newBlob("\r\n--" + boundary + "--").getBytes());
   var options = {
    method : "post",
    contentType : "multipart/form-data; boundary=" + boundary,
    payload : payload,
    muteHttpExceptions: true,
  };
  var res = UrlFetchApp.fetch(url, options).getContentText();

  Logger.log(res);
}

Another Method

For uploading files to slack, following script can be also used.

function request_slack2(){
  var fileId = "### file ID on Google Drive ###";
  var url = "https://slack.com/api/files.upload";
  var payload = {
    token: "### access token ###",
    channels: "### channel ID ###",
    filename: "### filename on Slack ###",
    title: "### title on Slack ###",
    file: DriveApp.getFileById(fileId).getBlob(),
  };
  var options = {
    method: "POST",
    payload: payload,
    muteHttpExceptions : true,
  };
  var res = UrlFetchApp.fetch(url, options).getContentText();

  Logger.log(res)
}

2. Convert Excel files To Spreadsheets On Google Drive Using Drive API v3.

Curl Code

If curl is used for this situation, the curl code becomes as follows. But this code uploads a file on local PC to Google Drive.

curl -X POST -sSL \
     -H "Authorization: Bearer ### access token ###" \
     -F "metadata={ \
                  name : '### uploaded filename on Google Drive ###', \
                  mimeType : 'application/vnd.google-apps.spreadsheet' \
                  };type=application/json;charset=UTF-8" \
     -F "file=@### Excel file ###;type=application/vnd.ms-excel" \
     "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"

Google Apps Script

When above curl code is changed to GAS, the script becomes as follows.

In this sample, please be careful that contentType is multipart/related not multipart/form-data. The detail information is here.

function request_driveapi() {
  var fileId = "### file ID (excel file) on Google Drive ###";
  var metadata = {
    name: "### uploaded filename on Google Drive ###",
    mimeType: "application/vnd.google-apps.spreadsheet"
  };
  var fields = "id,mimeType,name";
  var url = "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields="
    + encodeURIComponent(fields);
  var file = DriveApp.getFileById(fileId);
  var boundary = "xxxxxxxxxx";
  var data = "--" + boundary + "\r\n";
      data += "Content-Disposition: form-data; name=\"metadata\"\r\n";
      data += "Content-Type: application/json; charset=UTF-8\r\n\r\n";
      data += JSON.stringify(metadata) + "\r\n";
      data += "--" + boundary + "\r\n";
      data += "Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"\r\n";
      data += "Content-Type: " + file.getMimeType() + "\r\n\r\n";
  var payload = Utilities.newBlob(data).getBytes()
    .concat(file.getBlob().getBytes())
    .concat(Utilities.newBlob("\r\n--" + boundary + "--").getBytes());
  var options = {
    method : "post",
    contentType : "multipart/related; boundary=" + boundary,
    payload : payload,
    headers: {'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()},
    muteHttpExceptions: true,
  };
  var res = UrlFetchApp.fetch(url, options).getContentText();

  Logger.log(res);
}

References

And then, I analyzed logs from curl codes which were shown above.

@enderahmetyurt

This comment has been minimized.

Copy link

commented Mar 28, 2018

Thanks for codes. What about 2 and more photo posting in a request?

@VladiCastillo

This comment has been minimized.

Copy link

commented Apr 2, 2018

How would you handle a multipart/form-data for uploading gmail attachments to a third party api? I'm trying to upload a gmail email attachment from a gmail add on that i'm creating.

@slalka

This comment has been minimized.

Copy link

commented Dec 11, 2018

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.