来到了第三天,想说我们先从一个简单但实用的 Script 开始。但先讲结论,如果你很急着用,可以直接使用这份 Add-On: Email Notification for Google Form。对於想知道怎麽做的人,让我们开始吧!
细数常见的 Google 产品,有一个很常用的就是 Google 表单了,有的人拿它来记帐、有的人拿它来处理报名。而在使用上,有时会听见的是——
我们今天就以回应这三个问题来玩 GAS 罗!
那我们就开始罗!首先先帮我开启一个全新的 Google 表单,并进入到 GAS 的介面。
跟第二篇提到的一样,第一次使用会需要按下「允许授权」。
我习惯将变数弄成一张参数表(Environment.gs
),这边先设定我想要的参数,包括建立一个 form
的 object 呼叫 GAS 的 FormApp
并设定「目前绑定的表单」(如果你是从「第二张」的「进入方式一」,也就是没有绑定者,这边可以透过 FormApp.openById
来设定)。
var form = FormApp.getActiveForm();
// or var form = FormApp.openById('1234567890abcdefghijklmnopqrstuvwxyz');
再来我们来设定时间,这边我希望在中午 12 点开启,下午 5 点结束,先设定一个简单的时间。这边我写成 "2021-09-03 12:00"(YYYY-MM-DD HH:MM
的形式),实际开发时可以多考虑时区,不管是 GAS 的执行时区,以及设定时间的时区(可以参考第二篇的补充:时区设置)
var start_time = "2021-09-03 12:00";
var end_time = "2021-09-03 17:00";
我们可以在主要执行的 .gs
档案中,写上「开启」与「结束」的程序。在这边,我们透过的功能叫 setAcceptingResponses()
。并透过 Logger.log()
来通知执行的程序。
function startAcceptResponse() {
form.setAcceptingResponses(true);
Logger.log("Your Google Form is opening");
}
function stopAcceptResponse() {
form.setAcceptingResponses(false);
Logger.log("Your Google Form is closing");
}
这边我们透过无痕模式来测试其功能的结果。
在这边,可以透过程序码设定,或是直接用 GAS 的 UI 来执行。透过 UI 的方式比较直观,就是设定你要几点启动开启(startAcceptResponse
)或结束(stopAcceptResponse
)。
这边也同时说明,要怎麽透过设定的参数来执行。我们透过 ScriptApp.newTrigger()
来创造。其中 newTrigger()
里面要放的是你要执行的 function 名,以及要设定是以时间为基底(timeBased()
),并在指定(at(date)
)的时间(new Date()
)会触发。
function setTrigger(){
ScriptApp.newTrigger("startAcceptResponse")
.timeBased()
.at((new Date(start_time)))
.create();
ScriptApp.newTrigger("stopAcceptResponse")
.timeBased()
.at((new Date(end_time)))
.create();
};
其他设定 Time-Based Trigger 的方式 还有依据日期(atDate(year, month, day)
)、设定每小时都 Trigger 一次等(everyHours(n)
)。
这样就完成了基本的设定。如果是设定单次性的 Trigger,那其实这样就可以了,因为到其它会自动关掉。但如果是一个定期检查的呢?总不会希望它一直吃自己的 GAS Quota吧?那我们可以设定一个「一次性的清理 Trigger 的 Trigger」(有点饶口)
这个时候我们可以设定一个时间,透过 deleteTrigger()
把所有 trigger 都删掉。
function deleteTriggers() {
var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
ScriptApp.deleteTrigger(triggers[i]);
}
}
但,那如果我们只打算清理一个 Trigger 呢?可以加入透过加入一个 if 和 getHandlerFunction()
来达到。
function deleteTriggers() {
var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
if (Triggers[i].getHandlerFunction() == "stopAcceptResponse") {
ScriptApp.deleteTrigger(triggers[i]);
}
}
}
写完後,最後再透过 Step 4 设定个一次性的 Trigger 来排定删除 Trigger 就完成罗!好,那这样我们完成了第一题,那如果我想限定报名人数怎麽办?
一样在设定的参数表(Environment.gs
)中设定。如果我们希望表单最多只收 30 个回应,这边就也再设置一个回应数量。如果想绑定不要重复报名,简单的做法是限定必须登入才能回应(一个帐号只能回应一次)
var max_response_count = "30";
我们先设定一个 Trigger 叫做 checkCount()
,我们预期它每次要在每次表单送出(Submit)时检查人数。
function checkCount(){
if (FormApp.getActiveForm().getResponses().length >= max_response_count) {
stopAcceptResponse();
form.setCustomClosedFormMessage("报名已经额满了");
} else{
Logger.log("报名成功 +1");
}
}
如果你想让後进者(也就是关闭表单後才点开连结的人)看到客制化讯息,记得用 setCustomClosedFormMessage()
,这样他们点开就会看到像这样的画面。
再来,我们透过 onFormSubmit()
来在送出时检查是不是已经超过人数了。也可以设定其他的限制,像是预算表总额金额超过一定时跳提醒等等。那在写好之後,我们一样可以透过程序码来设定,或是一样透过程序码来达成。
function setLimitTrigger(){
ScriptApp.newTrigger("checkCount")
.forForm(form)
.onFormSubmit()
.create();
}
这样就好「检查数量」罗!但目前的逻辑是「当报名超过人数时,之後的人就不能点开表单」。假设此时有一百人已经正在填表单,我们要怎麽样让「正在填表单的人」知道他没有抢到票呢?此时就是进入我们第三题了。
在这边,因为目前 Google 表单并不支援动态调整,也就是说,正在填表单的人,不会更新到最新版本的回应。所以目前的方式比较阳春,是需要透过「另行通知」来执行。
所以目前 work-around 的做法会是,搜集 Email 并在「填完表单」的页面说「会寄结果信给您」,在结果通知信中显示「报名成功」或「报名失败」。因为 Email 的设定也是个不小的主题,详细的作法会在明天的文章中介绍。
好,所以今天完整的程序码如下——
var form = FormApp.getActiveForm();
function setTrigger(){
ScriptApp.newTrigger("startAcceptResponse")
.timeBased()
.at((new Date(start_time)))
.create();
ScriptApp.newTrigger("stopAcceptResponse")
.timeBased()
.at((new Date(end_time)))
.create();
};
function deleteTriggers() {
var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
if (Triggers[i].getHandlerFunction() == "stopAcceptResponse") {
ScriptApp.deleteTrigger(triggers[i]);
}
}
}
function checkCount(){
if (FormApp.getActiveForm().getResponses().length >= max_response_count) {
stopAcceptResponse();
form.setCustomClosedFormMessage("报名已经额满了");
} else{
Logger.log("报名成功 +1");
}
}
function setLimitTrigger(){
ScriptApp.newTrigger("checkCount")
.forForm(form)
.onFormSubmit()
.create();
}
没关系,今天讲的内容其实已经有为 Google Developer Expert 将它做成了 Add-On,所以直接使用 Email Notification for Google Form 就可以了。但对於想客制化、开发的人来说,希望透过今天的流程,有帮你更了解一些。
最後小提醒,也别设定太多 Trigger 喔,记得 Quota for Trigger 是 20 / user / script
。
好,那今天就是我们的 D3,明天 D4 会继续介绍结合 Email 的使用方式,如果不想错过可以订阅按赞小铃铛(?),也欢迎留言跟我说你还想知道什麽做法/主题。我们明天见。
<<: 写给MLOps人才培育苦手 | MLOps落地指南 - 团队篇
没有props还可以传资料吗 v-bind和v-on在没有props的情况下一样可以得到父层的资料。...
前言 前一篇介绍了 forEach、filter、map、reduce,算是平常我比较常使用,而且在...
来到铁人赛第二天,今天我们来聊聊 Hexo 这个架设工具。 Hexo 是什麽? Hexo 是利用 N...
Bootstrap已是目前全球被大量网页开发者使用的一个网页UI框架了,其特色在於使用简单,开发快速...
在设定 GAS demos.html 时,我们能看到3.20後的版本多了一个区块 此区块即为新增的网...