Multipart-POST Request Using Google Apps Script

Gist

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.

 Share!