【问题标题】:onEdit(e) not working in Add-ononEdit(e) 在附加组件中不起作用
【发布时间】:2016-01-15 22:31:04
【问题描述】:

我编写了一个脚本,在本机电子表格中使用时效果很好。我现在正在尝试将其作为附加组件发布,并且发现 onEdit(e) 无法正常工作,而 onOpen(e)onInstall(e) 工作正常。

我查看了有关授权模式和安装/启用插件的文档,但我认为我可能遗漏了一些东西(希望是直截了当的),因为我是初学者。我应该以不同的方式调用函数吗?还是onEdit 的位置?任何帮助表示赞赏。谢谢!!

function setup() {
  var ui = SpreadsheetApp.getUi();
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('Send Auto Emails');

  try {ss.setActiveSheet(ss.getSheetByName('Send Auto Emails'));}
  catch (e) {ss.insertSheet('Send Auto Emails', 0);}

  sheet.getRange(1, 1).setValue('Recipient Email Address');   

  //etc...
}

function onEdit(e) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = e.source.getActiveSheet();
  var range = e.source.getActiveRange();

  if (range.getA1Notation() == "C1" | range.getA1Notation() == "D1" |     range.getA1Notation() == "E1" && sheet.getName() == "Send Auto Emails") {
    Browser.msgBox(
      'Alert',
      'Feel free to change the title here to something more relevant to you.  But be aware, if you would like to use an optional item, please make sure you are referencing it in your email message exactly as it appears here, wrapped in < and >. Example: <Optional Item 1>.',
      Browser.Buttons.OK
    );
  }
  if (range.getA1Notation() == "J4" && sheet.getName() == "Send Auto     Emails") {
    Browser.msgBox(
      'Alert',
      'Only add the email message body.  "Hello, Recipient Name" and "Best, Your Name" will be automatically added.  If you would like to use Optional Items in this message, see the example text to make sure you are using them the right way.',
      Browser.Buttons.OK
    );
  }

  if (range.getA1Notation() == "A2") {
    ss.toast("Your data in column A must not be separated by any blank rows. Any data after a blank row will be ignored.", "Be aware", 90);
  }
}

function onOpen(e) {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('BulkEmail beta')
      .addItem('1. Sheet Setup', 'setup')
      .addItem('2. Send Emails', 'sendEmails')
      .addToUi();
  onEdit(e);
}

function onInstall(e) {
  onOpen(e);
}

编辑 1

我尝试创建一个可安装的触发器而不是使用简单的onEdit,但仍然无济于事。

function createonEdit() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  ScriptApp.newTrigger('installableonEdit')
      .forSpreadsheet(ss)
      .onEdit()
      .create();
}

function installableonEdit(e) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = e.source.getActiveSheet();
  var range = e.source.getActiveRange();

  try {
    if (range.getA1Notation() == "C1" | range.getA1Notation() == "D1" | range.getA1Notation() == "E1" && sheet.getName() == "Send Auto Emails") {
      Browser.msgBox(
        'Alert',
        'Feel free to change the title here to something more relevant to you.  But be aware, if you would like to use an optional item, please make sure you are referencing it in your email message exactly as it appears here, wrapped in < and >. Example: <Optional Item 1>.',
        Browser.Buttons.OK
      );
    }
    if (range.getA1Notation() == "J4" && sheet.getName() == "Send Auto Emails") {
      Browser.msgBox(
        'Alert',
        'Only add the email message body.  "Hello, Recipient Name" and "Best, Your Name" will be automatically added.  If you would like to use Optional Items in this message, see the example text to make sure you are using them the right way.',
        Browser.Buttons.OK
      );
    }

    if (range.getA1Notation() == "A2") {
      ss.toast("Your data in column A must not be separated by any blank rows. Any data after a blank row will be ignored.", "Be aware", 90);
    }
  } catch(err) {
    var errMsg = 'There was an error: ' + err +
        + " \n \n" +
        'from the: onEdit function ' +
        + " \n \n" +
        'The call stack is: ' + err.stack;

    GmailApp.sendEmail('elisabeth@groupon.com', "error", errMsg);
  }
}

【问题讨论】:

  • 它可能被调用但因某些错误而失败。使用 Logger 服务记录函数中各个点的错误。另外检查它是否由于此处提到的限制而失败:developers.google.com/apps-script/guides/triggers
  • @SujayPhadke Logger 无法记录错误。 Stackdriver 的console 将是一个对开发人员更加友好的工具(默认情况下,未捕获的错误会记录到 Stackdriver)。大多数(全部?)触发的函数都会因错误而静默失败(并将其记录到 Stackdriver)——只有用户显式执行的函数才会向用户显示错误消息。
  • 我无法在测试时让简单的 onEdit() 触发器在 Sheets 插件中运行,即使只使用一行代码:Logger.log("onEdit");我尝试了所有的 AuthModes,将项目分配给标准的 Cloud Platform 项目 ID,配置了 OAuth 屏幕,但均无济于事。如果我运行函数“onEdit()”它记录正常。我还尝试添加一个已安装的触发器,但在“事件源”下只有一个“日历”选项,它需要所有者的电子邮件地址,即使工作表和日历都在高级服务下和 appscript.json 下的“启用高级服务”下配置。有什么想法吗?
  • 根据developers.google.com/gsuite/add-ons/how-tos/…,“测试时不支持可安装触发器。依赖于可安装触发器的功能不可测试”。不过,只要我不使用任何需要授权的代码,似乎简单的触发器在测试时应该可以工作……但是 Logger 不会记录,developers.google.com/apps-script/guides/triggers/#onedite 也不起作用。

标签: google-apps-script google-sheets triggers google-apps-script-addon


【解决方案1】:

您的onOpen() 触发器正在运行onEdit() 触发器。 opOpen() 在安装并启用插件时在 AuthMode.LIMITED 中运行。

this documentation 中,它声明:

一种允许访问有限服务子集的模式 (LIMITED)。当绑定到文档的插件或脚本执行 onOpen(e) 或 onEdit(e) 简单触发器时,会出现此(LIMITED)模式,NONE 描述的情况除外。

您正在运行一个 onOpen() 简单触发器,并且它在 LIMITED 模式下运行,因为它在一个附加组件中。

所以,那部分,我很确定。

我相信您能做的就是创建一个可安装的编辑触发器,并在 FULL 模式下运行。所以,这就是我要尝试的方法,摆脱简单的触发器,并使用ScriptApp 安装触发器。

在文档中,它指出:

他们(一个简单的触发器)无法访问需要授权的服务。例如,简单触发器无法发送电子邮件,因为 Gmail 服务需要授权,但简单触发器可以使用匿名语言服务翻译短语。

Google Documentation

所以,try/catch 包括发送电子邮件,这会阻止 onEdit() 简单触发器工作。

在您的代码中添加 try/catch,如果出现错误,请给自己发送电子邮件。

function onEdit(e) {try{
  //Code Here

} catch(err) {
  var errMsg = 'There was an error: ' + err +
      + " \n \n" +
      'from the: onEdit function ' +
      + " \n \n" +
      'The call stack is: ' + err.stack;

  GmailApp.sendEmail('yourEmail@gmail.com', "Subject", errMsg);
};

【讨论】:

  • 刚试过这个。在作为附加组件进行测试时,我根本没有收到电子邮件,并且在作为本机脚本进行测试时,该功能再次按预期工作。所以该功能根本没有作为附加组件运行?
  • 我还试图通过添加代码来故意让它捕获它会失败,但仍然没有。
  • 我尝试从onOpen 中删除onEdit 以及创建一个可安装的触发器,如下所示。既不能发送错误电子邮件,也不能在工作表或附加组件中正确运行。我开始怀疑是否有某种错误?感觉肯定是权限问题。
  • @Alan Wells 感谢分享。我在测试模式下遇到与加载项相同的错误。您在 catch 中的代码向电子邮件发送以下消息:“出现错误:异常:插件尝试了在作为插件测试模式下不允许的操作。要使用此操作,您必须部署插件.0从:onEdit函数0调用栈是:在setTriggers:49(createClockTriggerForSpreadsheet)在setTriggers:14(createTriggers)”。如您所见,\n 并没有换行,这里还需要其他东西。
  • 我使用绑定的项目文件进行测试和开发。我很久以前就停止使用“测试作为附加组件”了。我有一个我开发的自定义 Web 应用程序,它将我的开发文件复制到一个不同的独立应用程序脚本文件中,而那个独立文件就是我用于生产的文件。实际上,我正在努力尝试将该应用发布到 Workspace Marketplace。
【解决方案2】:

一个可能的原因是您“作为插件测试”

https://developers.google.com/gsuite/add-ons/how-tos/testing-editor-addons#testing_details

测试时不支持可安装触发器。功能性 依赖于可安装的触发器是不可测试的。

但有趣的是,它适用于绑定脚本。

这让我困惑了好一阵子。因此,解决方案是当您需要测试可安装触发器时,只需使用绑定文档即可。

如果有效,附加组件的触发器也将有效。

对于其他事情,你可以做“测试作为插件”

【讨论】:

    猜你喜欢
    • 2018-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    • 2020-09-04
    • 2019-01-19
    • 2016-02-26
    相关资源
    最近更新 更多