使用AppS脚本快速获取大量G Suite用户的用户信息
Getting user information for a large number of G Suite users quickly with AppScript
我正在使用此代码段的略微修改版本来获取 G Suite 域中大量用户的上次登录时间。由于用户数量众多,此代码无法在 30 分钟内完成 运行 并达到 30 分钟的执行时间限制而失败。我正在寻找一种加快执行速度的方法。
运行它的应用程序将此数据与截断的类似代码结合起来,从企业许可证管理器 API 读取值,我预计它会遇到同样的问题。
如果无法使代码更快,我至少需要确保它不会达到执行时间限制。我需要为所有用户至少调用一次此 API 才能使应用程序正常工作 - 它按用户上次登录时间对用户列表进行排序。该应用在应用制作工具中,在 G Suite Enterprise 域上使用应用脚本。
function getParameterValues(parameters) {
return parameters.reduce(function(result, parameter) {
var name = parameter.name;
var value;
if (parameter.intValue !== undefined) {
value = parameter.intValue;
} else if (parameter.stringValue !== undefined) {
value = parameter.stringValue;
} else if (parameter.datetimeValue !== undefined) {
value = new Date(parameter.datetimeValue);
} else if (parameter.boolValue !== undefined) {
value = parameter.boolValue;
}
result[name] = value;
return result;
}, {});
}
function generateLoginActivityReport() {
var today = new Date();
var oneWeekAgo = new Date(today.getTime() - (7 * 24 * 60 * 60 * 1000));
var timezone = Session.getScriptTimeZone();
var date = Utilities.formatDate(oneWeekAgo, timezone, 'yyyy-MM-dd');
var parameters = [
'accounts:last_login_time',
'drive:num_items_created'
];
var rows = [];
var pageToken;
var page;
do {
page = AdminReports.UserUsageReport.get('all', date, {
parameters: parameters.join(','),
maxResults: 500,
pageToken: pageToken,
});
var reports = page.usageReports;
if (reports) {
for (var i = 0; i < reports.length; i++) {
var report = reports[i];
try {
var parameterValues = getParameterValues(report.parameters);
var row = [
report.date,
report.entity.userEmail,
parameterValues['accounts:last_login_time'],
//parameterValues['drive:num_items_created']
];
rows.push(row);
//var ar = app.models.ActivityReport.newRecord();
//ar.LastLogin = parameterValues['accounts:last_login_time'];
console.log(report.entity.userEmail);
//ar.DocsAdded = 0; //getting this value is another issue but unrelated so it's set to 0 for now.
//ar.Email = report.entity.userEmail.toString();
//app.saveRecords([ar]);
}
catch(error) {
console.error("Error: \n"+error);
}
}
}
} while (pageToken);
}
这是一个示例执行:
[19-07-15 15:58:30:784 CDT] Starting execution
[19-07-15 15:58:30:796 CDT] Session.getScriptTimeZone() [0 seconds]
[19-07-15 15:58:30:797 CDT] Utilities.formatDate([Mon Jul 08 13:58:30 PDT 2019, America/Mexico_City, yyyy-MM-dd]) [0 seconds]
[19-07-15 15:58:32:202 CDT] console.log([user1@test.mavenwave.com, []]) [0.003 seconds]
[19-07-15 15:58:32:203 CDT] console.log([ad.test.admin@test.mavenwave.com, []]) [0 seconds]
[19-07-15 15:58:32:204 CDT] console.log([user3@test.mavenwave.com, []]) [0 seconds]
///more entries, roughly 195 total
[19-07-15 15:58:32:441 CDT] console.log([user4@test.mavenwave.com, []]) [0 seconds]
[19-07-15 15:58:32:441 CDT] console.log([user5@test.mavenwave.com, []]) [0 seconds]
[19-07-15 15:58:32:443 CDT] Execution succeeded [1.645 seconds total runtime]
与其使用报告 API 获取最后一次登录,不如直接从所有用户记录的列表中获取它会更快吗?使用 AdminDirectory.Users.list
并检索 user.lastLoginTime
属性?
如果您仍然需要云端硬盘项目的数量(您已在上面注释掉),您可能必须 运行 通过一个单独的函数,但您可以根据其他一些标准或开始最近登录的用户优先。
我通过使用 App Maker 的客户端脚本解决了这个问题。客户端脚本调用服务器脚本,服务器脚本获取 100 个用户的报告,然后将页面令牌传回客户端脚本,客户端脚本使用页面令牌再次调用它 - 这会达到 30 分钟的时间限制并按顺序继续调用。
function crunLoginActivityReport(page) {
// this loops over every page token and gets the data and writes it to the DB.
console.log("Running activity report for page: " + page);
google.script.run.withSuccessHandler(function(result) {
console.log("Got the following from the server, handing back to client runner" + result);
if (result === null) {
console.log("Result was null, stopping get");
return;
} else {
crunLoginActivityReport(result); }
}).runLoginActivityReport(page);
return;
}
function cinitLoginActivityReport() {
google.script.run.withSuccessHandler(function(result) {
crunLoginActivityReport(result);
return;
}).initLoginActivityReport();
return;
}
我正在使用此代码段的略微修改版本来获取 G Suite 域中大量用户的上次登录时间。由于用户数量众多,此代码无法在 30 分钟内完成 运行 并达到 30 分钟的执行时间限制而失败。我正在寻找一种加快执行速度的方法。
运行它的应用程序将此数据与截断的类似代码结合起来,从企业许可证管理器 API 读取值,我预计它会遇到同样的问题。
如果无法使代码更快,我至少需要确保它不会达到执行时间限制。我需要为所有用户至少调用一次此 API 才能使应用程序正常工作 - 它按用户上次登录时间对用户列表进行排序。该应用在应用制作工具中,在 G Suite Enterprise 域上使用应用脚本。
function getParameterValues(parameters) {
return parameters.reduce(function(result, parameter) {
var name = parameter.name;
var value;
if (parameter.intValue !== undefined) {
value = parameter.intValue;
} else if (parameter.stringValue !== undefined) {
value = parameter.stringValue;
} else if (parameter.datetimeValue !== undefined) {
value = new Date(parameter.datetimeValue);
} else if (parameter.boolValue !== undefined) {
value = parameter.boolValue;
}
result[name] = value;
return result;
}, {});
}
function generateLoginActivityReport() {
var today = new Date();
var oneWeekAgo = new Date(today.getTime() - (7 * 24 * 60 * 60 * 1000));
var timezone = Session.getScriptTimeZone();
var date = Utilities.formatDate(oneWeekAgo, timezone, 'yyyy-MM-dd');
var parameters = [
'accounts:last_login_time',
'drive:num_items_created'
];
var rows = [];
var pageToken;
var page;
do {
page = AdminReports.UserUsageReport.get('all', date, {
parameters: parameters.join(','),
maxResults: 500,
pageToken: pageToken,
});
var reports = page.usageReports;
if (reports) {
for (var i = 0; i < reports.length; i++) {
var report = reports[i];
try {
var parameterValues = getParameterValues(report.parameters);
var row = [
report.date,
report.entity.userEmail,
parameterValues['accounts:last_login_time'],
//parameterValues['drive:num_items_created']
];
rows.push(row);
//var ar = app.models.ActivityReport.newRecord();
//ar.LastLogin = parameterValues['accounts:last_login_time'];
console.log(report.entity.userEmail);
//ar.DocsAdded = 0; //getting this value is another issue but unrelated so it's set to 0 for now.
//ar.Email = report.entity.userEmail.toString();
//app.saveRecords([ar]);
}
catch(error) {
console.error("Error: \n"+error);
}
}
}
} while (pageToken);
}
这是一个示例执行:
[19-07-15 15:58:30:784 CDT] Starting execution
[19-07-15 15:58:30:796 CDT] Session.getScriptTimeZone() [0 seconds]
[19-07-15 15:58:30:797 CDT] Utilities.formatDate([Mon Jul 08 13:58:30 PDT 2019, America/Mexico_City, yyyy-MM-dd]) [0 seconds]
[19-07-15 15:58:32:202 CDT] console.log([user1@test.mavenwave.com, []]) [0.003 seconds]
[19-07-15 15:58:32:203 CDT] console.log([ad.test.admin@test.mavenwave.com, []]) [0 seconds]
[19-07-15 15:58:32:204 CDT] console.log([user3@test.mavenwave.com, []]) [0 seconds]
///more entries, roughly 195 total
[19-07-15 15:58:32:441 CDT] console.log([user4@test.mavenwave.com, []]) [0 seconds]
[19-07-15 15:58:32:441 CDT] console.log([user5@test.mavenwave.com, []]) [0 seconds]
[19-07-15 15:58:32:443 CDT] Execution succeeded [1.645 seconds total runtime]
与其使用报告 API 获取最后一次登录,不如直接从所有用户记录的列表中获取它会更快吗?使用 AdminDirectory.Users.list
并检索 user.lastLoginTime
属性?
如果您仍然需要云端硬盘项目的数量(您已在上面注释掉),您可能必须 运行 通过一个单独的函数,但您可以根据其他一些标准或开始最近登录的用户优先。
我通过使用 App Maker 的客户端脚本解决了这个问题。客户端脚本调用服务器脚本,服务器脚本获取 100 个用户的报告,然后将页面令牌传回客户端脚本,客户端脚本使用页面令牌再次调用它 - 这会达到 30 分钟的时间限制并按顺序继续调用。
function crunLoginActivityReport(page) {
// this loops over every page token and gets the data and writes it to the DB.
console.log("Running activity report for page: " + page);
google.script.run.withSuccessHandler(function(result) {
console.log("Got the following from the server, handing back to client runner" + result);
if (result === null) {
console.log("Result was null, stopping get");
return;
} else {
crunLoginActivityReport(result); }
}).runLoginActivityReport(page);
return;
}
function cinitLoginActivityReport() {
google.script.run.withSuccessHandler(function(result) {
crunLoginActivityReport(result);
return;
}).initLoginActivityReport();
return;
}