首页 > 解决方案 > onSubmit 触发器在没有提交表单的情况下执行

问题描述

我创建了一个 Google 表单,链接到工作表以捕获响应,并添加了一个应用程序脚本,该脚本在每次提交表单时运行。通过一堆测试,一切都运行良好 - 表单响应通过,onSubmit功能运行良好。不过,昨晚我们收到了一些脚本的执行,即使表单没有提交。

查看表单本身的响应页面,当我收到通知时没有提交。此外,这不是我组织中的公共表格,除了我自己之外,只有其他人拥有该链接。他证实他在处决时没有提交表格。

Google 表格中有两张表格:1> 表单回复和 2> 数据。数据表使用一些QUERY函数从响应表中提取数据,以不同的格式对其进行格式化(例如,在电话号码中放置连字符,将某些字段呈现为大写等)。此外,数据表标题的标记与表格问题不同(例如,“homeAdd1”而不是“家庭地址行 1”)。这是因为脚本创建了一个 PDF,使用表单响应替换模板 Google Doc 上的占位符 ('%homeAdd1%')。然后该脚本获取生成的 PDF 并将其通过电子邮件发送给提交者。

同样,在昨天的测试之前,一切都很好。我当时并没有意识到,但是当我的同事输入随机值来测试表格时,对于家庭地址第 2 行,他只输入了一个 5 位数的邮政编码。它生成了一个 PDF 罚款,并将其通过电子邮件发送给他,但这导致该QUERY函数呈现 #VALUE 错误。函数如下所示:

=QUERY(Responses!L2:S,"SELECT UPPER(L) UPPER(M)...

因此,当表格看到一个只有 5 位数字的单元格时,它会自动将其呈现为数字,并且UPPER不适用于数字值。我(愚蠢地)没想到将所有两张纸都预先格式化为纯文本,所以发生了这种情况。

链接到表单和 Apps 脚本的 Google 表格上的 #VALUE 错误是否会导致onSubmit功能失灵?这是我能看到的唯一可能导致它的事情,但它没有意义。我已经修复了格式问题,但我不知道错误执行是否意味着其他问题。

随着额外的提交,脚本只是一次又一次地发送最新的 PDF。在 20 秒内,它触发了 5 次,每次都发送通过电子邮件生成的最后一个 PDF。查看 Stackdriver 日志,与我们昨天早些时候测试它时没有什么不同。和命令工作正常console.logconsole.info它们都被列为由onSubmit函数触发。

这是脚本:

提交功能:

function onSubmit(e) {
  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data');
  var list = ss.getRange("A1:A").getValues();
  var row = list.filter(String).length;
  var email = ss.getRange(row,2).getValue();
  var newResponse = ss.getRange(row,3).getValue();
  if (newResponse == 'Generate New') {
    newOne(ss,row,email);
  } else if (newResponse == 'Upload Completed') {
    completed(ss,row,email);
  } else {
  }
}

执行的函数:

function newOne(ss,row,email) {
  var name = ss.getRange(row,4).getValue();
  console.log('Function Start - ' + name);
  var newType = ss.getRange(row,6).getValue();
  var copyFile = DriveApp.getFileById('[file id]').makeCopy();
  var copyDoc = DocumentApp.openById(copyFile.getId());
  var copyBody = copyDoc.getActiveSection();
  // Replacing variables with values on spreadsheet
  console.log('Create file start - ' + name);
  var newInfo = ss.getRange(row, 1, 1, 29).getDisplayValues();
  var header = ss.getRange(1, 1, 1, 29).getDisplayValues();
  for (var i = 1; i <= 5; i++) {
    copyBody.replaceText('%' + header[0][i] + '%', newInfo[0][i].toString());
  }
  var x;
  if (newType == 'Office 1') {
    x = 6;
  } else if (newType == 'Office 2') {
    x = 15;
  } else {
  }
  for (var i = x; i <= (x + 8); i++) {
    copyBody.replaceText('%' + header[0][i] + '%', newInfo[0][i].toString());
  }
  copyBody.replaceText('%' + header[0][26] + '%', newInfo[0][26].toString());
  // Create the PDF file, rename it, and delete the doc copy
  copyDoc.saveAndClose();
  var newFile = DriveApp.createFile(copyFile.getAs('application/pdf'));
  newFile.setName('New - ' + name + '.pdf');
  copyFile.setTrashed(true);
  console.log('Create file finished - ' + name);
  //Mails PDF to submitter
  console.info('Pre-email log for ' + name);
  MailApp.sendEmail(email,'Email Subject','', {
                    noReply: true,
                    htmlBody: "<body>Hello, and thank you.</body>",
                    attachments: [newFile]
                    });
  console.info('Email sent for ' + name);
  appFile.setTrashed(true);
}

任何见解/帮助将不胜感激;谢谢!

乔什

标签: google-apps-scriptgoogle-sheetsgoogle-forms

解决方案


虚假的不需要的事件触发器

我遇到了来自 onFormSubmit 事件触发器的虚假触发器的问题。在我的情况下,它们总是在表单提交发生真正触发之后立即发生。我发现我可以识别它们,因为我要求的问题都没有得到回答。我在这里讨论它。

捕获 e.values 数组并查看是否可以找到一种一致的方法来防止它们导致处理功能失灵可能值得您花时间。


推荐阅读