![](/img/trans.png)
[英]Remove the web apps from the G Suite Admin Console by using Google Apps Script
[英]How to get a list of G Suite users which are using Google Apps Script?
我想知道,是否有机会获得使用 Google Apps 脚本的 G Suite 用户(一个域的)列表?
从用户的 Google Drives 检索脚本项目列表后,您必须首先从Apps Script API请求项目元数据。 目前,获得项目的唯一方法是 go 一个一个,提供带有scriptId
的请求。
诀窍是脚本项目文件的 Id 恰好与脚本 Id相同(如果您查看 CLASP 项目的list
命令的源代码,您会发现他们利用这一事实来显示项目 Id)。
要获取Project
资源,我们需要调用get
方法:
GET https://script.googleapis.com/v1/projects/{scriptId}
下面是一个简单的实用程序,用于从 API 中检索单个Project
资源。 请注意,您的清单文件必须至少包含https://www.googleapis.com/auth/script.projects.readonly
scope,否则403
将返回响应代码
/**
* @typedef {{
* domain : string,
* email : string,
* name : string
* }} GSuiteUser
*
* @typedef {{
* scriptId : string,
* title : string,
* createTime : string,
* updateTime : string,
* creator : GSuiteUser,
* lastModifyUser : GSuiteUser
* }} ScriptProject
*
* @summary gets script project metadata
* @param {{
* id : string,
* token : string
* }}
* @returns {ScriptProject}
*/
const getProject = ({
id = ScriptApp.getScriptId(),
token = ScriptApp.getOAuthToken()
}) => {
const uri = `https://script.googleapis.com/v1/projects/${id}`;
/** @type {GoogleAppsScript.URL_Fetch.URLFetchRequestOptions} */
const params = {
contentType : "application/json",
headers : {
Authorization: `Bearer ${token}`
},
muteHttpExceptions : true,
method : "get"
};
const response = UrlFetchApp.fetch(uri, params);
const successChecker = getSuccessChecker();
const success = successChecker(response);
if(!success) {
return {};
}
return JSON.parse(response.getContentText());
};
Map 在您使用 ziganotschka 方法获得的脚本文件列表上,您将获得有关项目的详细信息。 接下来,如果您的意思是运行项目,您可以调用processes.list
API 方法:
GET https://script.googleapis.com/v1/processes
必需的 OAuth scope 是https://www.googleapis.com/auth/script.processes
。
/**
* @typedef {{
* projectName : string,
* functionName : string,
* processType : string,
* processStatus : string,
* userAccessLevel : string,
* startTime : string,
* duration : string
* }} ScriptProcess
*
* @summary lists script processes for a user
* @param {{
* id : (string|"any"),
* pageSize : (number|50),
* token : string,
* start : (Date|undefined),
* end : (Date|undefined),
* statuses : string[],
* types : string[]
* }}
* @returns {ScriptProcess[]}
*/
const listScriptProcesses = ({
id = ScriptApp.getScriptId(),
token = ScriptApp.getOAuthToken(),
pageSize = 50,
start, end,
statuses = [],
types = []
} = {}) => {
const query = [
`pageSize=${pageSize}`,
`userProcessFilter.startTime=${toZuluTimestamp(start)}`,
`userProcessFilter.endTime=${toZuluTimestamp(end)}`
];
id !== "any" && query.push(`userProcessFilter.scriptId=${id}`);
types.length && query.push(`userProcessFilter.types=${types.join(",")}`);
statuses.length && query.push(`userProcessFilter.statuses=${statuses.join(",")}`);
const uri = `https://script.googleapis.com/v1/processes?${query.join("&")}`;
/** @type {GoogleAppsScript.URL_Fetch.URLFetchRequestOptions} */
const params = {
contentType: "application/json",
headers: {
Authorization: `Bearer ${token}`
},
muteHttpExceptions: true,
method: "get"
};
const response = UrlFetchApp.fetch(uri, params);
const content = response.getContentText();
const successChecker = getSuccessChecker();
const success = successChecker(response);
if (!success) {
console.warn(response.getResponseCode(), content);
return [];
}
const { processes = [] } = JSON.parse(content);
return processes;
};
作为响应,您将代表用户获取有关脚本执行的元数据,其凭据与不记名令牌一起传递(您将需要每个用户的服务帐户)。
rest 很简单:如果响应不为空,则用户在某个时间点运行脚本项目(请注意,上面的实用程序将start
和end
时间戳参数都默认为now
)。 如果您提供any
作为脚本 ID,则请求将返回代表用户执行的每次执行。
该方法的另一个好处是返回每种类型的脚本项目执行,包括 Web 应用程序、附加组件和绑定项目(有关详细信息,请参阅ProcessType
枚举)。
这种方法的唯一困难是 Web 部署为“像我一样执行”的应用程序,该应用程序将始终在脚本项目所有者的权限下运行,因此您必须单独跟踪 Web 应用程序的用户。
上面的片段使用以下实用程序脚本:
/**
* @summary checks HTTPResponse for being successful
* @param {GoogleAppsScript.URL_Fetch.HTTPResponse} resp
* @returns {boolean}
*/
const getSuccessChecker = ({ successOn = [200] } = {}) => (resp) => {
const code = resp.getResponseCode();
return successOn.some(c => c === code);
};
/**
* @summary converts input into RFC3339 UTC "Zulu" format
* @param {Date|number|string} [date]
* @returns {string}
*/
const toZuluTimestamp = (date = Date.now()) => new Date(date).toISOString().replace('Z','000000Z');
您需要启用V8 运行时才能使上面的代码片段正常工作(或将它们转换为 ES5 语法)。
Main menu menu> Security > API controls
并为新创建的服务帐户添加必要的范围 - 如此处所述"private_key"
字段https://www.googleapis.com/auth/drive.readonly
"Resources > Libraries... > Find a library"
并输入代码1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF
q: 'mimeType="application/vnd.google-apps.script"'
每个用户的文件,以找出用户在他的驱动器上是否有独立的应用程序脚本文件代码示例:
function myFunction() {
var users = AdminDirectory.Users.list({"domain":"PASTE HERE YOUR DOMAIN NAME"}).users;
users.forEach(function(user){
user = user.primaryEmail;
getService(user).reset();
var service = getService(user);
if (service.hasAccess()) {
Logger.log("service has access");
var url = "https://www.googleapis.com/drive/v3/files";
var query = '?q=mimeType%3D%22application%2Fvnd.google-apps.script%22';
var headers ={
"Authorization": 'Bearer ' + service.getAccessToken()
};
var options = {
'headers': headers,
'method' : 'get',
'muteHttpExceptions': true
};
var response=UrlFetchApp.fetch(url+query, options).getContentText();
if(JSON.parse(response).files.length==0){
Logger.log("User " + user + " does not have any Standalone Apps Script projects on his Drive");
}else{
Logger.log("User " + user + " has Standalone Apps Script projects on his Drive");
}
}
else {
Logger.log(service.getLastError());
}
}
)
}
var PRIVATE_KEY ="-----BEGIN PRIVATE KEY-----PASTE HERE YOUR PRIVATE KEY FROM THE JSON FILE-----END PRIVATE KEY-----\n";
var CLIENT_EMAIL = 'PASTE HERE THE EMAIL OF THE SERVICE ACCOUNT';
function getService(user) {
return OAuth2.createService('List users')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
.setPrivateKey(PRIVATE_KEY)
.setIssuer(CLIENT_EMAIL)
.setSubject(user)
.setPropertyStore(PropertiesService.getScriptProperties())
.setParam('access_type', 'offline')
.setScope("https://www.googleapis.com/auth/drive.readonly");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.