Proper format of a Google Drive API multipart/mixed batch request using Javascript

只愿长相守 提交于 2019-12-09 18:42:09

问题


I am using Javascript (in the Google Apps Script Editor) to make HTTP requests to the Google Drive API.

I've successfully made individual calls to the API, so I know my Oauth 2 works, but now I'm working on making a batch request.

I will loop through each file, and make 2 API calls per file.

My request:

var newOwnerEmail = 'archive@test.com';
var newEditorEmail = 'admin@test.com';
var fileIds = ['a', 'b', 'c'];

const boundary = 'testboundaryname';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";

var multipartRequestBody = '';

for (var i = 0; i < fileIds.length; i++) {

  var fileId = fileIds[i];

  var resource1 = { role: "owner", type: "user", value: newOwnerEmail };

  var requestBody = {};
  requestBody.path = '/drive/v2/files/' + fileId + '/permissions';
  requestBody.method = 'POST';
  requestBody.contentType = 'application/json';
  requestBody.payload = JSON.stringify(resource1);
  requestBody.muteHttpExceptions = true;

  multipartRequestBody += delimiter;
  multipartRequestBody += 'Content-Type: application/json\r\n';
  multipartRequestBody += JSON.stringify(requestBody);

  var resource2 = { role: "writer", type: "user", value: newEditorEmail };

  requestBody.payload = JSON.stringify(resource2);

  multipartRequestBody += delimiter;
  multipartRequestBody += 'Content-Type: application/json\r\n';
  multipartRequestBody += JSON.stringify(requestBody);

}

multipartRequestBody += close_delim;

var batchUrl = 'https://www.googleapis.com/batch';

var batchRequestBody = {};
batchRequestBody.headers = { Authorization: 'Bearer ' + service.getAccessToken() };
batchRequestBody.method = 'POST';
batchRequestBody.contentType = 'multipart/mixed; boundary="' + boundary + '"';
batchRequestBody.body = multipartRequestBody;
batchRequestBody.muteHttpExceptions = true;

try {

  var batchResponse = UrlFetchApp.fetch(batchUrl, batchRequestBody);

  Logger.log(batchResponse);

multipartRequestBody ends up being a string that looks like this:

 --testboundary
 Content-Type: application/json
 {"method":"POST","contentType":"application/json","payload":"{\"role\":\"owner\",\"type\":\"user\",\"value\":\"archive@test.com\"}","muteHttpExceptions":false}
 --testboundary
 Content-Type: application/json
 {"method":"POST","contentType":"application/json","payload":"{\"role\":\"writer\",\"type\":\"user\",\"value\":\"admin@test.com\"}","muteHttpExceptions":false}
 --testboundary
 Content-Type: application/json
 {"method":"POST","contentType":"application/json","payload":"{\"role\":\"owner\",\"type\":\"user\",\"value\":\"archive@test.com\"}","muteHttpExceptions":false}
 --testboundary
 Content-Type: application/json
 {"method":"POST","contentType":"application/json","payload":"{\"role\":\"writer\",\"type\":\"user\",\"value\":\"admin@test.com\"}","muteHttpExceptions":false}
 --testboundary
 Content-Type: application/json
 {"method":"POST","contentType":"application/json","payload":"{\"role\":\"owner\",\"type\":\"user\",\"value\":\"archive@test.com\"}","muteHttpExceptions":false}
 --testboundary
 Content-Type: application/json
 {"method":"POST","contentType":"application/json","payload":"{\"role\":\"writer\",\"type\":\"user\",\"value\":\"admin@test.com\"}","muteHttpExceptions":false}
 --testboundary--

I ran UrlFetchApp.getRequest() to see what was being sent to the server, and it's this:

{
  "headers": {
    "Authorization": "Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "X-Forwarded-For": “(our external IP address)“
  },
  "method": "post",
  "payload": "\r\n--testboundary\r\nContent-Type: application/json\r\n{\"method\":\"POST\",\"contentType\":\"application/json\",\"payload\":\"{\\\"role\\\":\\\"owner\\\",\\\"type\\\":\\\"user\\\",\\\"value\\\":\\\"archive@test.com\\\"}\",\"muteHttpExceptions\":false}\r\n--testboundary\r\nContent-Type: application/json\r\n{\"method\":\"POST\",\"contentType\":\"application/json\",\"payload\":\"{\\\"role\\\":\\\"writer\\\",\\\"type\\\":\\\"user\\\",\\\"value\\\":\\\"admin@test.com\\\"}\",\"muteHttpExceptions\":false}\r\n--testboundary\r\nContent-Type: application/json\r\n{\"method\":\"POST\",\"contentType\":\"application/json\",\"payload\":\"{\\\"role\\\":\\\"owner\\\",\\\"type\\\":\\\"user\\\",\\\"value\\\":\\\"archive@test.com\\\"}\",\"muteHttpExceptions\":false}\r\n--testboundary\r\nContent-Type: application/json\r\n{\"method\":\"POST\",\"contentType\":\"application/json\",\"payload\":\"{\\\"role\\\":\\\"writer\\\",\\\"type\\\":\\\"user\\\",\\\"value\\\":\\\"admin@test.com\\\"}\",\"muteHttpExceptions\":false}\r\n--testboundary\r\nContent-Type: application/json\r\n{\"method\":\"POST\",\"contentType\":\"application/json\",\"payload\":\"{\\\"role\\\":\\\"owner\\\",\\\"type\\\":\\\"user\\\",\\\"value\\\":\\\"archive@test.com\\\"}\",\"muteHttpExceptions\":false}\r\n--testboundary\r\nContent-Type: application/json\r\n{\"method\":\"POST\",\"contentType\":\"application/json\",\"payload\":\"{\\\"role\\\":\\\"writer\\\",\\\"type\\\":\\\"user\\\",\\\"value\\\":\\\"admin@test.com\\\"}\",\"muteHttpExceptions\":false}\r\n--testboundary\r\nContent-Type: application/json\r\n{\"method\":\"POST\",\"contentType\":\"application/json\",\"payload\":\"{\\\"role\\\":\\\"owner\\\",\\\"type\\\":\\\"user\\\",\\\"value\\\":\\\"archive@test.com\\\"}\",\"muteHttpExceptions\":false}\r\n--testboundary\r\nContent-Type: application/json\r\n{\"method\":\"POST\",\"contentType\":\"application/json\",\"payload\":\"{\\\"role\\\":\\\"writer\\\",\\\"type\\\":\\\"user\\\",\\\"value\\\":\\\"admin@test.com\\\"}\",\"muteHttpExceptions\":false}\r\n--testboundary\r\nContent-Type: application/json\r\n{\"method\":\"POST\",\"contentType\":\"application/json\",\"payload\":\"{\\\"role\\\":\\\"owner\\\",\\\"type\\\":\\\"user\\\",\\\"value\\\":\\\"archive@test.com\\\"}\",\"muteHttpExceptions\":false}\r\n--testboundary\r\nContent-Type: application/json\r\n{\"method\":\"POST\",\"contentType\":\"application/json\",\"payload\":\"{\\\"role\\\":\\\"writer\\\",\\\"type\\\":\\\"user\\\",\\\"value\\\":\\\"admin@test.com\\\"}\",\"muteHttpExceptions\":false}\r\n--testboundary--",
  "followRedirects": true,
  "validateHttpsCertificates": true,
  "useIntranet": false,
  "contentType": "multipart/mixed; boundary=\"testboundary\"",
  "url": "https://www.googleapis.com/batch"
}

I get this response:

Unsupported number format: --

There's definitely something wrong with the content of the request, but it's difficult to determine what it is, given that there's such little documentation for creating batch requests using Javascript.

The only documentation I could find is this, but the example is language-independent/hypothetical.

Then I found this example, which seems to use a Google API client library, which I can't use in Apps Script.

来源:https://stackoverflow.com/questions/32295912/proper-format-of-a-google-drive-api-multipart-mixed-batch-request-using-javascri

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!