【问题标题】:Correct way to implement Installable Triggers in Google Addon (Google App Script)在 Google Addon(Google App Script)中实现可安装触发器的正确​​方法
【发布时间】:2021-12-13 20:48:14
【问题描述】:

我有一个谷歌应用脚​​本,它作为谷歌表格插件发布。该插件的一个特点是它获取一个单元格的值,查询一个 Google Big Query 表,并使用下拉选项填充下一个单元格。一旦用户选择了一个选项,另一个查询就会发送到 Big Query,依此类推。

由于此活动发生在用户编辑单元格时,我认为我需要使用 onEdit() 类型功能。但是文档清楚地表明我不能使用onEdit() 来发出需要授权的请求(我使用服务帐户),所以我需要使用触发器,并且因为它是用于添加的,所以我需要使用可安装触发器.

我按照docs 以编程方式执行此操作

/**
 * Creates a trigger for when a spreadsheet opens.
 */
function createSpreadsheetOpenTrigger() {
  var ss = SpreadsheetApp.getActive();
  ScriptApp.newTrigger('stu')
      .forSpreadsheet(ss)
      .onEdit()  //the docs actually is onOpen()
      .create();
}

反过来,函数 stu 从单元格中获取值并调用另一个查询 Big Query 的函数:

function stu(e) {
  var activeCell = e.range;
  var cellValue = e.value;
....
....
if (wsName === "Targets" && c < 7 && r > 1) {
    var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Targets");
    var rowValues = ws.getRange(r, 1, 1, 6).getValues();
    runQuery(cellValue, r, nextCol, rowValues);  // runQuery executes the BigQuery query
  }
}

我遇到了几个问题:

  1. 当用户安装插件时,似乎无法安装可安装触发器。为了解决这个问题,我遵循了 https://stackoverflow.com/questions/61314827/install-trigger-for-google-app-script-in-custom-addon 的建议,并添加了一个菜单项以允许用户安装触发。

  2. 我开始收到诸如Exception: This add-on has created too many edit triggers in this document for this Google user account.  之类的错误

谁能告诉我在创建可安装触发器 onEdit 是否正确

ScriptApp.newTrigger('stu')
          .forSpreadsheet(ss)
          .onEdit()
          .create();

也许我应该使用

ScriptApp.newTrigger('stu')
          .forSpreadsheet(ss)
          .onOpen()
          .create();

然后在函数stu 中将功能包装在onEdit() 中:

function stu(e) {
  onEdit(e) {
    var activeCell = e.range;
    var cellValue = e.value;
   ....
   ....
   if (wsName === "Targets" && c < 7 && r > 1) {
     var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Targets");
     var rowValues = ws.getRange(r, 1, 1, 6).getValues();
     runQuery(cellValue, r, nextCol, rowValues);  // runQuery executes the BigQuery 
   query
  }
 }
}

如果我正确使用可安装触发器,我是否应该删除以前的实例以避免Exception: This add-on has created too many edit triggers in this document for this Google user account. 错误?我可以看到有一种方法可以检查是否存在触发器并酌情删除(也在 https://developers.google.com/apps-script/guides/triggers/installable#managing_triggers_manually 上)。

我怀疑实际上我已经从根本上理解了我应该如何使用可安装触发器。我已通读文档,但非常感谢任何建议。

【问题讨论】:

  • deleting previous instances 为什么会有以前的实例?应该只有 1 个触发器。您是否多次执行创建触发器功能?
  • @StuartBrown 附加组件仅限于一个且只有一个可安装触发器。
  • @TheMaster,我认为这是我的错误之一。我认为我的代码在每次用户编辑时都会创建一个可安装的触发器。我建议创建 IT onOpen 然后将 onEdit 放入我在触发器中调用的函数中的选项是否更好?
  • @TheAddonDepot 抱歉,我只能在回复中标记一个人。你认为我应该切换到创建触发器 onOpen 并在它调用的函数中使用 onEdit 吗?

标签: javascript google-apps-script google-sheets


【解决方案1】:

这只会做一个:

function creatonedittrigger(funcname) {
  if(ScriptApp.getProjectTriggers().filter(t => t.getHandlerFunction() == funcname).length == 0) {
    ScriptApp.newTrigger(funcname).forSpreadsheet(SpreadsheetApp.getActive()).onEdit().create();
  }
}

【讨论】:

  • 非常感谢@Cooper。你认为我想创建触发器 onEdit 还是 onOpen?如果我在 onEdit 上创建它,它会在每次用户进行编辑时尝试创建触发器(这可能会生成许多触发器)。如果我使用 onOpen 触发器会被创建一次(并且您的逻辑会在将来打开时处理删除其他实例),然后我将 onEdit 放在触发器调用的函数中
  • 该函数只允许为给定的处理函数名称创建一个触发器。但我不会将它附加到任何触发器上。我只会运行一次然后忘记它。您希望为每个用户编辑获得一次 onEdit 触发器,因此您可能希望一次将其操作限制在一张纸上。这个网站上有很多 onEdit 函数的例子。尝试在触发器Logger.log(JSON.stringify(e)) 中运行它,其中 e 是用于接受事件对象的参数。事件中发生的事情比记录的要多得多。
  • 非常感谢。今晚下班回家后我会试试这个!
猜你喜欢
  • 2023-03-03
  • 1970-01-01
  • 2021-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-26
  • 1970-01-01
相关资源
最近更新 更多