Skip to content

Instantly share code, notes, and snippets.

@tanaikech
Created January 19, 2018 01:13
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save tanaikech/f167b9280a8e710804e4061571b53fb9 to your computer and use it in GitHub Desktop.
Save tanaikech/f167b9280a8e710804e4061571b53fb9 to your computer and use it in GitHub Desktop.
Batching Requests for Google Apps Script

Batching Requests for Google Apps Script

There is the bathing requests in the Google APIs. The bathing requests can use the several API calls as a single HTTP request. By using this, for example, users can modify filenames of a lot of files on Google Drive. But there are limitations for the number of API calls which can process in one batch request. For example, Drive API can be used the maximum of 100 calls in one batch request.

The following sample script modifies the filenames of 2 files on own Google Drive using Google Apps Script. Drive API for modifying filenames is used as "PATCH". The batch request including 2 API calls of Drive API is called using "multipart/mixed". If you want more APIs, please add the elements to the array of "body".

function main() {
  var body = [
    {
      method: "PATCH",
      endpoint: "https://www.googleapis.com/drive/v3/files/### fileId ###?fields=name",
      requestBody: {"name": "samplename1"}
    },
    {
      method: "PATCH",
      endpoint: "https://www.googleapis.com/drive/v3/files/### fileId ###?fields=name",
      requestBody: {"name": "samplename2"}
    }
  ];

  var url = "https://www.googleapis.com/batch";
  var boundary = "xxxxxxxxxx";
  var contentId = 0;
  var data = "--" + boundary + "\r\n";
  for (var i in body) {
    data += "Content-Type: application/http\r\n";
    data += "Content-ID: " + ++contentId + "\r\n\r\n";
    data += body[i].method + " " + body[i].endpoint + "\r\n";
    data += body[i].requestBody ? "Content-Type: application/json; charset=utf-8\r\n\r\n" : "\r\n";
    data += body[i].requestBody ? JSON.stringify(body[i].requestBody) + "\r\n" : "";
    data += "--" + boundary + "\r\n";
  }
  var payload = Utilities.newBlob(data).getBytes();
  var options = {
    method: "post",
    contentType: "multipart/mixed; boundary=" + boundary,
    payload: payload,
    headers: {'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()},
    muteHttpExceptions: true,
  };
  var res = UrlFetchApp.fetch(url, options).getContentText();
  Logger.log(res);
}

Note :

  • For the batch request, each API call is no guaranteed ordering.

Reference :

  • Batching Requests
    • This document shows how to batch API calls together to reduce the number of HTTP connections your client has to make.
    • There are "Example batch request" and "Example batch response".
@oshliaer
Copy link

oshliaer commented Feb 17, 2019

 var data = body.reduce(function(p, c) {
    p += 'Content-Type: application/http\r\n';
    p += 'Content-ID: ' + ++contentId + '\r\n\r\n';
    p += c.method + ' ' + c.endpoint + '\r\n';
    p += c.requestBody
      ? 'Content-Type: application/json; charset=utf-8\r\n\r\n'
      : '\r\n';
    p += c.requestBody ? JSON.stringify(c.requestBody) + '\r\n' : '';
    p += '--' + boundary + '\r\n';
    return p;
  }, '--' + boundary + '\r\n');

@tanaikech
Copy link
Author

Yes. After I measured the benchmark for the loop process, I use this way.
https://gist.github.com/tanaikech/848aeafaac1ec676900bb78e3ce220b6

But, by recent Google's update, I thought that the request body might have been more strictly evaluated. So recently, I updated several applications.

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