无法使用 NodeJS 控制 Google 表格 API 的指标



我的项目使用NodeJS,它列出了与域外人员共享的所有文件,并将它们列在Google Sheets中。

我的问题是,当我列出所有驱动器时,我有很多文件和页面,我的功能不想等待在谷歌表单中写入数据,然后列出所有数据,检测域外的文件并进行写入。最后,谷歌表单的度量阻止了我:

代码:429,错误:[{消息:";超过了服务的配额指标"写入请求"和限制"每个用户每分钟写入请求"的配额消费者'project_number:XXXXXXXX'的'sheets.googleapis.com'&";,域:"全局",原因:"rateLimited Exceeded"}]

或者写所有数据的速度太快,在一些文件之后,停止在我的谷歌表单中写。

我试着设定一个暂停时间,但我不明白他为什么不接受。这是我的代码,有人能帮我写所有的文件吗?或者如果我的代码有问题,可以向我解释吗?

这是我的主要函数,它检查所有文件,如果一个文件在域外共享,请调用我的函数在之前在Google Sheets中生成

function exportDataFileOOD(nextPageToken, auth) {
const service = google.drive({version: 'v3', auth});
service.files.list({
corpora: 'user',
includeItemsFromAllDrives: true,
pageSize: 30,
pageToken: nextPageToken,
supportsAllDrives: true,
q: ''me' in owners and not trashed',
fields: 'nextPageToken,files(name,id,webViewLink,permissions, shared)'
}, (err, res) => {
if (err) {
return console.error('The API returned an error:', err.message);
}
let files = res.data.files
nextPageToken = res.data.nextPageToken
files.forEach((file) => {
if(file.shared === true){
let fileOOD = new Boolean(false);
let permissionList = file.permissions
permissionList.forEach((permission) => {
if (permission.emailAddress){
let mailSplit = permission.emailAddress.split('@')
if (mailSplit[1] !== 'DOMAIN') {
fileOOD = Boolean(true);
}
}
})
if (fileOOD === true) {
writeData(file)
sleep(10000)
}
}
})
if(nextPageToken){
exportDataFileOOD(nextPageToken)
}
})
}

这是我的写作功能:

function writeData(file){
columns[0].value.push(file.name)
columns[1].value.push(file.webViewLink)
file.permissions.forEach((permission) => {
if (permission.role === "owner") {
columns[2].value.push(permission.emailAddress);
} else if (permission.role === "writer") {
columns[3].value.push(permission.emailAddress);
} else if (permission.role === "reader") {
columns[4].value.push(permission.emailAddress)
} else if (permission.role === "commenter") {
columns[5].value.push(permission.emailAddress)
} else {
console.log("Error about this user permission: " + permission.email + " is " + permission.role)
}
})
let auth = callAPI("USER@DOMAIN")
columns.forEach((column) => {
const sheets = google.sheets({version: 'v4', auth})
if (column.value !== "") {
sheets.spreadsheets.values.batchUpdate({
spreadsheetId: idSheets,
requestBody: {
valueInputOption: "RAW",
data: [{
range: column.letter + line,
values: [[
String(column.value)
]]
}]
}
}, (err) => {
if (err) {
console.log(err)
}
})
}
})
columns.forEach((column) => {
column.value = [];
})
line++
}

谢谢你的帮助!

编辑:

我的脚本有一些更新,我知道用sleep((函数在表单中写东西不会出错,但现在我想检查用户列表的文件,脚本仍然很快,我不能对所有用户使用sleep(

我不能在30分钟内申请睡眠((,因为这需要一周的时间才能完成。那么,如果有人知道如何等待forEach循环的结束才能继续?

我的forEach循环:

let users = promise.users
users.forEach((user) => {
exportDataFileOOD(null, callAPI(user.primaryEmail))
})

第2版:

我的列变量

let columns = [
{
letter: "A",
title: "Name",
value: []
}, {
letter: "B",
title: "Link",
value: []
}, {
letter: "C",
title: "Owner(s)",
value: []
}
];

修改点:

  • 在脚本中,每一行都通过循环中的Sheets API放入电子表格中。我认为这就是你目前发行rateLimitExceeded的原因。在";方法:电子表格.values.batchUpdate"对于Sheets API,一个API调用可以将多行放入电子表格

当这些点反映在脚本中时,下面的修改如何?

在该修改中,使用了以下流程。

  1. 检索文件列表
  2. 创建一个数组,用于从检索到的文件列表中放入电子表格
  3. 使用";方法:电子表格.values.batchUpdate">

修改的脚本:

在此修改中,请运行main(auth)。并且,请在main中设置变量。

// This function is used for retrieving the file list.
function getFileList(drive, pageToken) {
return new Promise((resolve, reject) => {
drive.files.list(
{
corpora: "user",
includeItemsFromAllDrives: true,
pageSize: 1000,
pageToken,
supportsAllDrives: true,
q: "'me' in owners and trashed=false",
fields: "nextPageToken,files(name,id,webViewLink,permissions,shared)",
},
(err, res) => {
if (err) {
reject(err.errors);
return;
}
resolve(res.data);
}
);
});
}
// Please run this function.
async function main(auth) {
const service = google.drive({ version: "v3", auth }); // Please set your client.
const sheets = google.sheets({ version: "v4", auth }); // Please set your client.
const idSheets = "###"; // Please set your Spreadsheet ID.
const row = 2; // Please set the row number you want to put the values to Spreadsheet.

console.log("--- Retrieve file list.");
let files = [];
let pageToken = "";
do {
const res = await getFileList(service, pageToken);
if (res.files.length > 0) {
files = [...files, ...res.files];
console.log(files.length); // Showing process.
}
pageToken = res.nextPageToken;
} while (pageToken);
console.log(files.length);
console.log("--- Retrieved file list.");
console.log("--- Create values.");
const values = files.reduce((ar, file) => {
if (file.shared === true) {
file.permissions.forEach((permission) => {
if (permission.emailAddress) {
let mailSplit = permission.emailAddress.split("@");
if (mailSplit[1] !== "DOMAIN") {
file.permissions.forEach((permission) => {
const columns = [ file.name, file.webViewLink, ...Array(4).fill("") ];
if (permission.role === "owner") {
columns[2] = permission.emailAddress || "";
} else if (permission.role === "writer") {
columns[3] = permission.emailAddress || "";
} else if (permission.role === "reader") {
columns[4] = permission.emailAddress || "";
} else if (permission.role === "commenter") {
columns[5] = permission.emailAddress || "";
} else {
console.log("Error about this user permission: " + permission.email + " is " + permission.role);
}
ar.push(columns);
});
}
}
});
}
return ar;
}, []);
console.log(values.length);
console.log("--- Created values, and put values to Spreadsheet.");
if (values.length == 0) return;
const res = await sheets.spreadsheets.values.batchUpdate({ spreadsheetId: idSheets, requestBody: { valueInputOption: "USER_ENTERED", data: [{ range: `A${row}`, values }]} }).catch(({ errors }) => console.error(errors));
if (!res) return;
console.log("--- Done.");
}
  • 运行main(auth)时,将检索文件列表,并创建一个用于放入电子表格的数组。并且,通过一个API调用将数组放入电子表格中。由此,我认为您当前发行的rateLimitExceeded可能会被删除

注意:

  • 在你的脚本中,我使用了"方法:电子表格.values.batchUpdate"。如果你想把这些值附加到电子表格中,我认为";方法:电子表格.values.append"可能会被使用。

  • 很遗憾,我不知道你的实际电子表格。所以,当上面的脚本不是你预期的结果时,你能以图像的形式提供你对电子表格的预期情况吗?通过此操作,我想修改脚本。

  • 从您的显示脚本中,值将被放入电子表格的第一个选项卡中。请小心。

参考:

  • 方法:spreadsheets.values.batchUpdate

最新更新