检查触发器执行当前是否正在 Google Apps 脚本中运行

IMT*_*Man 6 google-apps-script

是否可以查看特定项目的触发器是否有任何活动/正在运行的执行?

我有一个一次性迁移脚本/项目,用于将数千个 Google 表格文件更新为新的模板格式。根据我的计算,该脚本将需要几个小时才能运行。我们的 G-Suite Enterprise 环境的执行时间限制为 30 分钟。

我的代码是这样编写的,如果脚本由于某种原因失败,我可以重新运行它,它将从停止的地方继续。

有时,脚本会因其他原因而失败,例如内存错误或网络连接问题。

所以我想设置一个 15 分钟的触发器来运行脚本。我希望它检查另一个执行是否仍在运行。如果是的话,就会停止。如果不是,那么它将继续。

我知道如何使用ScriptApp.getProjectTriggers()查看链接到项目的触发器,但从中我不知道如何找到正在运行的执行。

Tan*_*ike 5

  • 您想知道脚本现在是否由时间驱动的触发器运行。
  • 您希望使用 Google Apps 脚本来实现此目的。

如果我的理解是正确的,这个答案怎么样?请将此视为多个答案之一。

解决方案:

我认为您的目标可以使用Google Apps Script API中的processes.list方法来实现。当时间驱动触发器运行脚本期间请求 Google Apps 脚本 API 中的processes.list 方法时,可以检索以下值。

{
 "processes": [
  {
   "projectName": "sampleProject",
   "functionName": "myFunction",
   "processType": "TIME_DRIVEN",
   "processStatus": "RUNNING",  // <--- here
   "userAccessLevel": "OWNER",
   "startTime": "2019-10-07T00:00:00.000Z",
   "duration": "36.145s"
  }
 ]
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,processStatusRUNNING脚本完成后,processStatus将更改为COMPLETED.

processStatus检索时间信息的示例脚本RUNNING如下。

用法:

1. 将 Cloud Platform 项目链接到 Google Apps 脚本项目

在这种情况下,需要将 Cloud Platform 项目链接到 Google Apps 脚本项目。关于如何链接,你可以看这里

2. 启用 Google Apps 脚本 API

第二步,请在 API 控制台启用 Google Apps Script API。关于如何启用它,你可以在这个帖子中看到它。

3. 运行示例脚本:

function sample() {
  var scriptId = "###"; // Please set the script ID here.
  var functionName = "###"; // Please set the function name here.

  var url = "https://script.googleapis.com/v1/processes?userProcessFilter.functionName=" + functionName + "&userProcessFilter.scriptId=" + scriptId;
  var res = UrlFetchApp.fetch(url, {headers: {Authorization: 'Bearer ' + ScriptApp.getOAuthToken()}});
  var obj = JSON.parse(res);
  var runningScript = obj.processes.filter(function(p) {return p.processType == "TIME_DRIVEN" && p.processStatus == "RUNNING"});
  Logger.log(runningScript)
}
Run Code Online (Sandbox Code Playgroud)
  • https://www.googleapis.com/auth/script.external_request当您使用此脚本时,请添加和的范围https://www.googleapis.com/auth/script.processes。因此请将它们添加到清单文件 ( appsscript.json) 中。
  • 当您使用此脚本时,请设置 和 的变量scriptIdfunctionName这些变量在时间驱动触发器触发时运行。
  • 在此脚本中,当没有正在运行的脚本时,[]返回。
  • 如果您想了解其他流程类型,请修改p.processType == "TIME_DRIVEN"

笔记:

  • 我认为在你的情况下,你也可以使用方法:processes.listScriptProcesses
  • 根据我的经验,当脚本完成后,processStatus有时会出现这样的情况UNKNOWN。但在这种情况下,它表明脚本已经完成。

参考:

如果我误解了你的问题并且这不是你想要的方向,我很抱歉。

添加:

我认为使用Apps Script API的方法是一种解决方案。为了在不将云平台项目与GAS项目链接的情况下实现您的目标,在这里,我想提出一个解决方法。

在此解决方法中,我使用了 Drive API 的属性。当使用Drive API的属性时,可以检索其他项目的属性。所以在这里,我使用了Drive API的属性。请将此视为几种解决方法之一。

用法:

1. 在高级 Google 服务中启用 Drive API

首先,请在高级 Google 服务中启用 Drive API。

2. 示例脚本:

示例脚本1:

请复制并粘贴以下脚本。假设 的函数runByTrigger是由时间驱动的触发器运行的。

function runByTrigger(e) {
  var fileId = "###"; // Please set the file ID.

  if (e && "triggerUid" in e && e.triggerUid != "") {
    Drive.Files.update({properties: [
      {key: "processStatus", value: "RUNNING", visibility: "PUBLIC"},
      {key: "processStartTime", value: new Date().toISOString(), visibility: "PUBLIC"},
    ]}, fileId);
  }

  // do something
  // Here, please put your script.

  if (e && "triggerUid" in e && e.triggerUid != "") {
    Drive.Files.update({properties: [
      {key: "processStatus", value: "COMPLETED", visibility: "PUBLIC"},
      {key: "processStartTime", value: "", visibility: "PUBLIC"},
    ]}, fileId);
  }
}
Run Code Online (Sandbox Code Playgroud)

示例脚本2:

该脚本用于检查脚本是否由时间驱动触发器运行。请运行此脚本进行检查。您还可以使用与不同项目(包括runByTrigger.

function myFunction() {
  var fileId = "###"; // Please set the file ID.

  var runningScript = Drive.Properties.get(fileId, "processStatus", {visibility: "PUBLIC"}).value;
  if (runningScript == "RUNNING") {
    var startTime = Drive.Properties.get(fileId, "processStartTime", {visibility: "PUBLIC"}).value;
    Logger.log("Script is currently running. Start time is %s", startTime)
  } else {
    Logger.log("Script was finished.")
  }
}
Run Code Online (Sandbox Code Playgroud)
  • fileId脚本1和2都是相同的ID 。作为测试用例,如果脚本是独立脚本,请设置独立脚本的脚本ID。如果脚本是容器绑定脚本,请设置Google Docs的文件ID。
  • WhenrunByTrigger由时间驱动触发器运行,processStatus并被processStartTime放入文件的属性中。
    • 如果脚本当前正在运行,则当函数myFunction运行时,Script is currently running. Start time is {startTime}会在日志中显示。
    • 如果脚本已完成但未运行,Script was finished.则会在日志中显示。

笔记:

  • 在此解决方法中,使用 file 的属性。但我认为,例如,流程状态也可以保存到电子表格等。

参考: