Google Drive权限api仅在20次调用后引发速率限制错误 [英] Google drive permissions api throws rate limit error after only 20 calls
问题描述
我有一个脚本,该脚本正在浏览文件夹列表并使用驱动器"权限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
. - In above script, even when the length of
records
is more than 100, the script works. - When
sendNotificationEmail=false
is used, an error ofThe 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
Note:
我确认到2020年7月7日,该方法无法使用.但是,在2020年7月10日,我确认更改了权限:在Drive API中创建"方法的规范,并且该示例脚本得以再次使用.正是enforceSingleParent
和moveToNewOwnersRoot
必须能够正确使用.通过修改enforceSingleParent
和moveToNewOwnersRoot
,特定文件夹的所有权(包括文件和子文件夹)也可以在保持文件夹结构的情况下进行转移. 参考但是在当前阶段,我不确定这是否是永久性规范.
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屋!