Google Drive权限api仅在20次调用后引发速率限制错误 [英] Google drive permissions api throws rate limit error after only 20 calls

查看:71
本文介绍了Google Drive权限api仅在20次调用后引发速率限制错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个脚本,该脚本正在浏览文件夹列表并使用驱动器"权限api转移所有权.我使用它而不是bean(DriveApp.commands)?因为我需要禁止发送电子邮件通知.

I have a script that is going through a list of folders and transferring ownership using the Drive permissions api. I use that rather than the bean (DriveApp.commands)? because I need to suppress the email notifications.

尽管每分钟至少传输100个文件确实应该可以,但每3到15个文件我都会出错,即使单个呼叫要花3秒的时间才能传输,但传输速度仅为每分钟20、40每分钟,因为这可能算作每个文件两个单独的调用.

Although it really should be okay to transfer at least 100 files per minute, I'm getting errors every 3 to 15 files, even though the individual calls take 3 seconds to transfer which is a rate of only 20 per minute, 40 per minute since this probably counts as two separate calls per file.

//SNIPPET
  for (var i = 0; i < records.length; i++) {

    var folder = records[i]; // SPECIFIC FOLDER
    if (folder.Transferred === true) {
      //console.log(total+" That folder already transferred -"+folder.gdrive); 
      continue;
    }
    var target = folder.owner;    
    try {
        var result = passOwner(folder.gdrive, target);
      } catch (e) {
        console.log(e);
        Utilities.sleep(2000);
      }     
  } //for loop

//END OF PROBLEM CODE

function passOwner(fileId, user) {
  if (user == null) return -2;
  try {
    Drive.Permissions.insert({
      'role': 'owner',
      'type': 'user',
      'value': user
    }, fileId, {
      'sendNotificationEmails': 'false'
    });
  } catch (e) {    
    if (e.indexOf("File not found:") > -1) return -1;
    console.log("Taking a nap" + e);
    Utilities.sleep(2000);
    return -1;
  }
  try {
    DriveApp.getFileById(fileId).revokePermissions("ME@ME.com");
  } catch (e) {
    console.log(e);
    return -1;
  } 
  return 0;
}

带时间戳的调试日志

Jan 31, 2020, 10:34:17 AM Debug TypeError: Cannot find function indexOf in object GoogleJsonResponseException: API call to drive.permissions.insert failed with error: Rate limit exceeded. User message: "These item(s) could not be shared because a rate limit was exceeded: XXXX".
Jan 31, 2020, 10:34:18 AM Debug 88Folder transferred - 1XGOOGLEDRIVEID
Jan 31, 2020, 10:34:21 AM Debug 89Folder transferred - 1XGOOGLEDRIVEID
Jan 31, 2020, 10:34:24 AM Debug 90Folder transferred - 1XGOOGLEDRIVEID
Jan 31, 2020, 10:34:27 AM Debug 91Folder transferred - 1XGOOGLEDRIVEID
Jan 31, 2020, 10:34:30 AM Debug 92Folder transferred - 1XGOOGLEDRIVEID
Jan 31, 2020, 10:34:33 AM Debug 93Folder transferred - 1XGOOGLEDRIVEID
Jan 31, 2020, 10:34:34 AM Debug TypeError: Cannot find function indexOf in object GoogleJsonResponseException: API call to drive.permissions.insert failed with error: Rate limit exceeded. User message: "These item(s) could not be shared because a rate limit was exceeded: XXXX".

您知道我应该怎么做才能进一步解决问题吗?每次发生速率限制错误时,我都会小睡2秒钟,同时没有其他明显的api用途.最有说服力的是,它几乎立即启动了速率限制崩溃(在出现第一个问题之前,它的速率小于5).

Any idea what I should do to troubleshoot further? I have it nap for 2 seconds each time it has a rate limit error, there are no other obvious uses of the api occurring at the same time. Most tellingly, it starts the rate limit crashes almost immediately (it gets fewer than 5 before the first problem).

推荐答案

今天,我可以确认文件所有者必须能够通过使用Drive API的批处理请求进行更改.因此,我想提出一个示例脚本来实现您的目标,如下所示.

Today, I could confirm that the owner of files got to be able to be changed by the batch requests with Drive API. So I would like to propose a sample script for achieving your goal as follows.

使用批处理请求时,一个API调用可以运行100个API请求.而且,每个任务都可以与异步过程一起运行.这样,既可以降低流程成本,又可以降低配额成本.

When the batch requests is used, 100 API requests can be run by one API call. And also, each task can run with the asynchronous process. By this, both the process cost and quota cost can be reduced.

使用此脚本时,请在高级Google上启用Drive API服务.使用脚本的records时,脚本如下所示.

When you use this script, please enable Drive API at Advanced Google services. When records of your script is used, the script becomes as follows.

function myFunction() {
  // Please set the values of "records".
  const records = [
    {Transferred: false, owner: "###@gmail.com", gdrive: "### fileId 1###"},
    {Transferred: true, owner: "###@gmail.com", gdrive: "### fileId 2###"},
    {Transferred: false, owner: "###@gmail.com", gdrive: "### fileId 3###"},
    ,
    ,
    ,
  ];
  
  // Create requests for the batch request.
  const requests = records.reduce((ar, {Transferred, owner, gdrive}) => {
    if (Transferred === false) {
      ar.push({
        method: "POST",
        endpoint: `https://www.googleapis.com/drive/v3/files/${gdrive}/permissions?transferOwnership=true`,
        requestBody: {
          role: "owner",
          type: "user",
          emailAddress: owner
        }
      });
    };
    return ar;
  }, []);

  // Run batch requests.
  const limit = 100;
  const split = Math.ceil(requests.length / limit);
  const boundary = "xxxxxxxxxx";
  for (let i = 0; i < split; i++) {
    const object = {batchPath: "batch/drive/v3", requests: requests.splice(0, limit)};
    const payload = object.requests.reduce((s, e, i) => s += "Content-Type: application/http\r\nContent-ID: " + i + "\r\n\r\n" + e.method + " " + e.endpoint + "\r\nContent-Type: application/json; charset=utf-8\r\n\r\n" + JSON.stringify(e.requestBody) + "\r\n--" + boundary + "\r\n", "--" + boundary + "\r\n");
    const params = {method: "post", contentType: "multipart/mixed; boundary=" + boundary, payload: payload, headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}, muteHttpExceptions: true};
    var res = UrlFetchApp.fetch("https://www.googleapis.com/" + object.batchPath, params);
    console.log(res.getContentText())
  }
  
  // DriveApp.createFile()  // This is used for automatically detected the scope of https://www.googleapis.com/auth/drive. This scope is required to use the method of Permissions: create in Drive API.
}

注意:

  • 在上面的脚本中,即使records的长度大于100,该脚本也可以工作.
  • 使用sendNotificationEmail=false时,发生The sendNotificationEmail parameter is only applicable for permissions of type 'user' or 'group', and must not be disabled for ownership transfers.错误.因此,在此脚本中,未使用sendNotificationEmail=false.
  • Note:

    • In above script, even when the length of records is more than 100, the script works.
    • When sendNotificationEmail=false is used, an error of The sendNotificationEmail parameter is only applicable for permissions of type 'user' or 'group', and must not be disabled for ownership transfers. occurs. So in this script, sendNotificationEmail=false is not used.
      • Advanced Google services
      • Permissions: create

      我确认到2020年7月7日,该方法无法使用.但是,在2020年7月10日,我确认更改了权限:在Drive API中创建"方法的规范,并且该示例脚本得以再次使用.正是enforceSingleParentmoveToNewOwnersRoot必须能够正确使用.通过修改enforceSingleParentmoveToNewOwnersRoot,特定文件夹的所有权(包括文件和子文件夹)也可以在保持文件夹结构的情况下进行转移. 参考但是在当前阶段,我不确定这是否是永久性规范.

      I confirmed that at July 7, 2020, this method got not to be able to be used. But, at July 10, 2020, I confirmed that the specification of the method of Permissions: create in Drive API was changed, and this sample script got to be able to be used again. It's that enforceSingleParent and moveToNewOwnersRoot got to be able to be correctly used. By modified enforceSingleParent and moveToNewOwnersRoot, the ownership of the specific folder including the files and sub-folders got to be able to be also transferred with kept the folder structure. Ref But in the current stage, I'm not sure whether this is the permanent specification.

      这篇关于Google Drive权限api仅在20次调用后引发速率限制错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆