在不提交表单的情况下执行onSubmit触发器

时间:2019-04-30 21:00:13

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

我创建了一个Google表单,链接到一个工作表以捕获响应,并添加了一个Apps脚本,该脚本在每次提交表单时运行。进行了一系列测试,一切都运行良好-反馈的表单反馈,onSubmit函数运行良好。不过,即使昨晚未提交表单,我们还是收到了一些脚本执行文件。

查看表单本身的“响应”页面,当我收到通知时没有任何提交。另外,这不是我组织中的公共表格,只有我自己以外的其他人才能拥有链接。他确认死刑时没有提交表格。

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

再次,一切工作良好,直到昨天的测试。当时我还没有意识到,但是当我的同事输入随机值来测试表格时,对于家庭住址第2行,他只输入了5位邮政编码。它产生了PDF罚款,并通过电子邮件将其发送给他,但这导致QUERY函数呈现#VALUE错误。功能如下:

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

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

链接到表单和Google 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);
}

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

乔什

3 个答案:

答案 0 :(得分:2)

不需要的虚假事件触发器

我遇到了来自onFormSubmit事件触发器的虚假触发器的问题。就我而言,它们总是紧随表单提交真正触发之后。我发现我可以识别它们,因为我的所有必需问题都没有得到回答。我会here来讨论。

捕获e.values数组并查看是否可以找到一种一致的方法来防止它们导致处理功能失灵,可能是值得您花费时间的。我希望这会有所帮助。

答案 1 :(得分:0)

据我所知,onSubmit(e)不能像您期望的那样工作。

我认为您正在寻找的是onFormSubmit触发器,请尝试使用Class SpreadsheetTriggerBuilder documentation中的以下内容来创建脚本触发器,该脚本触发器在有人向您的链接表单提交响应时执行:

int a = 6;
foo(6); // 6 is a prvalue (and thus is an rvalue)
foo(a); // a is a glvalue

std::vector<int> vec = {1, 2, 3};
bar(vec);            // vec is a glvalue
bar(std::move(vec)); // std::move(vec) is an xvalue (reusable glvalue)
                     // (and thus is an rvalue)

答案 2 :(得分:0)

我安装了电子表格和相应的表格,在表格提交事件中我经常得到重复,这莫名其妙。在其他安装中不会发生。如果是这种情况,您就不能只检查事件是否为null,因为要测试它是否为null,就必须进行测试。如果未定义,则会出现错误。因此,首先测试它是否未定义。尝试以下代码:

`function formSubmitted(e) {
  // Deal with the unusual case that this is a bogus event
  if ((typeof e === "undefined") || (e == null) || (e.length == 0))  { 
    Logger.log("formSubmitted() received a bogus or empty event");
    return;
  }
  ...`