onSubmit 触发器在没有提交表单的情况下执行
onSubmit Trigger Executed Without Form Submission
我创建了一个 Google 表单,link 编辑到 Sheet 以捕获响应,并添加了一个 Apps 脚本,该脚本在每次提交表单时运行。 运行 通过一系列测试,一切正常 - 表单响应通过,onSubmit
功能运行良好。不过,昨晚,即使未提交表单,我们也收到了一些脚本执行。
查看表单本身的“回复”页面,当我收到通知时没有任何提交。此外,这不是我组织中的 public 表格,除了我之外,只有其他人拥有 link。他确认他在处决时没有提交表格。
Google Sheet 中有两个 sheet:1> 表单响应和 2> 数据。数据 sheet 使用一些 QUERY
函数从响应 sheet 中提取数据,以不同的方式格式化(例如,将连字符放入 phone 数字中,将某些字段呈现为大写, ETC。)。此外,数据 sheet headers 的标记与表单问题不同(例如 'homeAdd1' 而不是 'Home Address Line 1')。这是因为脚本创建了一个 PDF,使用表单响应替换模板 Google 文档上的占位符 ('%homeAdd1%')。该脚本然后获取生成的 PDF 并将其通过电子邮件发送给提交者。
同样,在昨天的测试之前,一切都运行良好。当时我并没有意识到,当我的同事在输入随机值来测试表格时,对于家庭地址第 2 行,他只输入了一个 5 位数的邮政编码。它生成了一个 PDF 文件,并通过电子邮件发送给他,但这导致 QUERY
函数呈现 #VALUE 错误。函数如下所示:
=QUERY(Responses!L2:S,"SELECT UPPER(L) UPPER(M)...
因此,当 Sheets 看到只有 5 位数字的单元格时,它会自动将其呈现为数字,而 UPPER
不适用于数字值。我(愚蠢地)没想到 pre-format 所有 sheet 都是纯文本,所以这发生了。
Google Sheet link 到表单和 Apps 脚本的 #VALUE 错误会导致 onSubmit
函数失灵吗?这是我能看到的唯一可能导致它的原因,但它没有意义。我已经修复了格式问题,但我不知道错误执行是否意味着其他问题。
随着额外的提交,脚本只是一次又一次地发送最新的 PDF。在 20 秒内,它发射了 5 次,每次都通过电子邮件发送最后生成的 PDF。查看 Stackdriver 日志,与我们昨天早些时候测试时没有什么不同。 console.log
和 console.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);
}
任何见解/帮助将不胜感激;谢谢!
乔希
据我所知,onSubmit(e) 并不像您期望的那样工作。
我认为您正在寻找的是 onFormSubmit 触发器,请尝试使用 Class SpreadsheetTriggerBuilder documentation 中的以下内容来创建一个脚本触发器,该触发器会在每次有人对您的链接表单提交回复时执行:
var sheet = SpreadsheetApp.getActive();
ScriptApp.newTrigger("function name")
.forSpreadsheet(sheet)
.onFormSubmit()
.create();
虚假的不需要的事件触发器
我遇到过来自 onFormSubmit 事件触发器的虚假触发器的问题。在我的例子中,它们总是在表单提交发生真正的触发之后立即发生。我发现我可以识别它们,因为 none 我需要的问题得到了回答。我讨论一下.
可能值得花时间捕获 e.values 数组,看看是否可以找到一种一致的方法来防止它们导致处理函数失灵。
我安装了一个电子表格和相应的表单,在表单提交事件中我经常出现重复,莫名其妙。它不会出现在其他安装中。如果这是你的情况,你不能只检查事件是否为空,因为要测试它是否为空,你必须要测试一些东西。如果它是未定义的,你会得到一个错误。所以首先测试它是否未定义。试试这个代码:
`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;
}
...`
我创建了一个 Google 表单,link 编辑到 Sheet 以捕获响应,并添加了一个 Apps 脚本,该脚本在每次提交表单时运行。 运行 通过一系列测试,一切正常 - 表单响应通过,onSubmit
功能运行良好。不过,昨晚,即使未提交表单,我们也收到了一些脚本执行。
查看表单本身的“回复”页面,当我收到通知时没有任何提交。此外,这不是我组织中的 public 表格,除了我之外,只有其他人拥有 link。他确认他在处决时没有提交表格。
Google Sheet 中有两个 sheet:1> 表单响应和 2> 数据。数据 sheet 使用一些 QUERY
函数从响应 sheet 中提取数据,以不同的方式格式化(例如,将连字符放入 phone 数字中,将某些字段呈现为大写, ETC。)。此外,数据 sheet headers 的标记与表单问题不同(例如 'homeAdd1' 而不是 'Home Address Line 1')。这是因为脚本创建了一个 PDF,使用表单响应替换模板 Google 文档上的占位符 ('%homeAdd1%')。该脚本然后获取生成的 PDF 并将其通过电子邮件发送给提交者。
同样,在昨天的测试之前,一切都运行良好。当时我并没有意识到,当我的同事在输入随机值来测试表格时,对于家庭地址第 2 行,他只输入了一个 5 位数的邮政编码。它生成了一个 PDF 文件,并通过电子邮件发送给他,但这导致 QUERY
函数呈现 #VALUE 错误。函数如下所示:
=QUERY(Responses!L2:S,"SELECT UPPER(L) UPPER(M)...
因此,当 Sheets 看到只有 5 位数字的单元格时,它会自动将其呈现为数字,而 UPPER
不适用于数字值。我(愚蠢地)没想到 pre-format 所有 sheet 都是纯文本,所以这发生了。
Google Sheet link 到表单和 Apps 脚本的 #VALUE 错误会导致 onSubmit
函数失灵吗?这是我能看到的唯一可能导致它的原因,但它没有意义。我已经修复了格式问题,但我不知道错误执行是否意味着其他问题。
随着额外的提交,脚本只是一次又一次地发送最新的 PDF。在 20 秒内,它发射了 5 次,每次都通过电子邮件发送最后生成的 PDF。查看 Stackdriver 日志,与我们昨天早些时候测试时没有什么不同。 console.log
和 console.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);
}
任何见解/帮助将不胜感激;谢谢!
乔希
据我所知,onSubmit(e) 并不像您期望的那样工作。
我认为您正在寻找的是 onFormSubmit 触发器,请尝试使用 Class SpreadsheetTriggerBuilder documentation 中的以下内容来创建一个脚本触发器,该触发器会在每次有人对您的链接表单提交回复时执行:
var sheet = SpreadsheetApp.getActive();
ScriptApp.newTrigger("function name")
.forSpreadsheet(sheet)
.onFormSubmit()
.create();
虚假的不需要的事件触发器
我遇到过来自 onFormSubmit 事件触发器的虚假触发器的问题。在我的例子中,它们总是在表单提交发生真正的触发之后立即发生。我发现我可以识别它们,因为 none 我需要的问题得到了回答。我讨论一下
可能值得花时间捕获 e.values 数组,看看是否可以找到一种一致的方法来防止它们导致处理函数失灵。
我安装了一个电子表格和相应的表单,在表单提交事件中我经常出现重复,莫名其妙。它不会出现在其他安装中。如果这是你的情况,你不能只检查事件是否为空,因为要测试它是否为空,你必须要测试一些东西。如果它是未定义的,你会得到一个错误。所以首先测试它是否未定义。试试这个代码:
`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;
}
...`