您可以使用FormTriggerBuilder 类来动态创建和销毁触发器。您可以使用 PropertiesService 来持久化创建的触发器的 id,然后使用 programmatically delete it later 像这样:
var formID = 'XXXXXXX';
var properties = PropertiesService.getScriptProperties()
function onInstall() {
createSubmitHandler()
}
function createSubmitHandler() {
var form = FormApp.openById(formID);
var trigger = ScriptApp.newTrigger('onSubmit')
.forForm(form)
.onFormSubmit()
.create();
properties.setProperty('triggerID', trigger.getUniqueId())
}
function destroySubmitHandler() {
var triggerID = properties.getProperty('triggerID')
var form = FormApp.openById(formID);
var allTriggers = ScriptApp.getUserTriggers(form)
for (var i = 0; i < allTriggers.length; i++) {
if (allTriggers[i].getUniqueId() == triggerID) {
ScriptApp.deleteTrigger(allTriggers[i]);
break;
}
}
}
function onSubmit() {
// we've been called, remove trigger, set timeout, re-enable, and then run function
destroySubmitHandler();
Utilities.sleep(5 * 1000)
createSubmitHandler();
myFunction()
}
function myFunction() {
// do stuff here
}
或者,正如 ScampMichael 指出的那样,您可以使用 Lock Service。在Concurrency and Google Apps Script 上的这篇文章中有一篇很棒的文章。但是,我不确定这就是我想要的。锁服务将等待执行的代码排队。这解决了并发执行的问题,但没有解决每个脚本每天只能触发 20 个触发器的问题,具体取决于配额的衡量方式。
这是一个如何使用锁定脚本来防止并发调用的示例:
function onSubmit() {
// we've been called, get a public lock, wait for other job to finish, run the function, and release the cracken
var lock = LockService.getScriptLock();
lock.tryLock(30 * 1000);
myFunction();
lock.releaseLock();
}
function myFunction() {
// do stuff here
}