Skip to content

Instantly share code, notes, and snippets.

@ndthanh
Forked from tanaikech/submit.md
Created June 16, 2021 13:07
Show Gist options
  • Save ndthanh/f6f5a6f6700376b751a69360b9f9ee17 to your computer and use it in GitHub Desktop.
Save ndthanh/f6f5a6f6700376b751a69360b9f9ee17 to your computer and use it in GitHub Desktop.
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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment