谷歌云端硬盘权限 api 仅在 20 次调用后抛出速率限制错误



>我有一个脚本,该脚本正在浏览文件夹列表并使用云端硬盘权限 API 转移所有权。我使用它而不是bean(DriveApp.command(?因为我需要禁止电子邮件通知。

虽然每分钟至少传输 100 个文件确实没问题,但我每 3 到 15 个文件就会出错,即使单个调用需要 3 秒才能传输,传输速度仅为每分钟 20 个,每分钟 40 个,因为这可能算作每个文件两个单独的调用。

//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(。

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

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

示例脚本:

使用此脚本时,请在高级 Google 服务中启用云端硬盘 API。使用脚本records时,脚本将如下所示。

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/httprnContent-ID: " + i + "rnrn" + e.method + " " + e.endpoint + "rnContent-Type: application/json; charset=utf-8rnrn" + JSON.stringify(e.requestBody) + "rn--" + boundary + "rn", "--" + boundary + "rn");
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

引用:

  • 高级谷歌服务
  • 权限:创建

更新时间: 2020 年 7 月 13 日

我确认在 2020 年 7 月 7 日,这种方法无法使用。但是,在 2020 年 7 月 10 日,我确认了"权限:在云端硬盘 API 中创建"方法的规范已更改,并且此示例脚本必须能够再次使用。就是enforceSingleParentmoveToNewOwnersRoot必须能够正确使用。通过修改enforceSingleParentmoveToNewOwnersRoot,包括文件和子文件夹在内的特定文件夹的所有权也能够与保留文件夹结构一起转移。参考 但在现阶段,我不确定这是否是永久规范。

最新更新