我有一个脚本,它是通过一个文件夹列表并使用Drive权限api转移所有权。我使用那个而不是bean(DriveApp.commands),因为我需要抑制电子邮件通知。
虽然每分钟传输至少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("[email protected]");
} 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)。
今天,我可以确认,文件的所有者可以通过Drive API的批量请求来改变。因此,我想提出一个示例脚本来实现你的目标,如下。
当使用批量请求时,一个API调用可以运行100个API请求。而且,每个任务都可以用异步进程来运行。这样一来,进程成本和配额成本都可以降低。
当你使用这个脚本时 请在高级谷歌服务中启用Drive 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/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
不使用。