雖然表單已經有 formLimit 這個外掛程式就已經夠用了,但自己手動做一個的感覺就是不一樣,有需要的夥伴請自行複製貼語法到 表單的 Apps Script 再執行 setFormOpenCloseTimes 這個 function 就能使用囉!大家順便也幫忙測試看看是否正常運作!感謝啦!

3.複製下列語法貼到 Apps Script 中( 只需修改想要的開啟和關閉時間,其他都不用動)
🎯 這邊月份設定比較特別:0 表示1月、1 表示2月、2 表示3月......11 表示 12月
// 全域變數:設定表單開啟和關閉時間 (以 UTC+8 時間表示,並轉換為 UTC)
var OPEN_TIME = convertToUTC(2025, 2, 24, 16, 05); // 2025年3月24日16:05
var CLOSE_TIME = convertToUTC(2025, 2, 24, 16, 10); // 2025年3月24日16:15
var TIMEZONE_UTC8 = 'Asia/Taipei';
function setFormOpenCloseTimes() {
try {
var form = FormApp.getActiveForm();
var now = new Date();
var nowLocal = formatLocalTime(now);
var openTimeLocal = formatLocalTime(OPEN_TIME);
var closeTimeLocal = formatLocalTime(CLOSE_TIME);
Logger.log('Form ID: ' + form.getId());
Logger.log('Current Time (UTC+8): ' + nowLocal);
Logger.log('Open Time (UTC+8): ' + openTimeLocal);
Logger.log('Close Time (UTC+8): ' + closeTimeLocal);
Logger.log('Current Form Status: ' + (form.isAcceptingResponses() ? 'Open' : 'Closed'));
deleteExistingTriggers();
var minutesToOpen = (OPEN_TIME - now) / (1000 * 60);
var minutesToClose = (CLOSE_TIME - now) / (1000 * 60);
Logger.log('Minutes to Open: ' + minutesToOpen);
Logger.log('Minutes to Close: ' + minutesToClose);
if (now > CLOSE_TIME) {
Logger.log('Current time is past close time - keeping form closed');
form.setAcceptingResponses(false);
} else if (now >= OPEN_TIME && now < CLOSE_TIME) {
Logger.log('Within open period - opening form and setting close trigger');
openForm();
} else {
Logger.log('Before open time - setting open trigger');
form.setAcceptingResponses(false);
if (minutesToOpen >= 1) {
var trigger = ScriptApp.newTrigger('openForm')
.timeBased()
.after(Math.max(1, minutesToOpen) * 60 * 1000)
.create();
Logger.log('Open trigger set for: ' + openTimeLocal + ' [Trigger ID: ' + trigger.getUniqueId() + ']');
ScriptApp.newTrigger('checkFormStatus')
.timeBased()
.after(Math.max(2, minutesToOpen + 1) * 60 * 1000)
.create();
}
}
} catch (e) {
Logger.log('Error in setFormOpenCloseTimes: ' + e.toString());
}
}
// 定義 UTC+8 時間 (小時和分鐘),然後轉換為 UTC
function convertToUTC(year, month, day, hourUTC8, minuteUTC8) {
var hourUTC = hourUTC8 - 8;
var dayOffset = 0;
if (hourUTC < 0) {
hourUTC += 24;
dayOffset = -1;
}
return new Date(Date.UTC(year, month, day + dayOffset, hourUTC, minuteUTC8));
}
function formatLocalTime(date) {
return date.toLocaleString('zh-TW', { timeZone: TIMEZONE_UTC8 });
}
function openForm() {
try {
var form = FormApp.getActiveForm();
var now = new Date();
var nowLocal = now.toLocaleString('zh-TW', { timeZone: 'Asia/Taipei' });
var closeTimeLocal = CLOSE_TIME.toLocaleString('zh-TW', { timeZone: 'Asia/Taipei' });
Logger.log('Attempting to open form at: ' + nowLocal);
Logger.log('Form ID: ' + form.getId());
form.setAcceptingResponses(true);
Utilities.sleep(1000);
if (!form.isAcceptingResponses()) {
Logger.log('Failed to open form!');
return;
}
Logger.log('Form successfully opened at: ' + new Date().toLocaleString('zh-TW', { timeZone: 'Asia/Taipei' }));
var minutesToClose = (CLOSE_TIME - now) / (1000 * 60);
if (minutesToClose >= 1) {
var trigger = ScriptApp.newTrigger('closeForm')
.timeBased()
.after(Math.max(1, minutesToClose) * 60 * 1000)
.create();
Logger.log('Close trigger set for: ' + closeTimeLocal + ' [Trigger ID: ' + trigger.getUniqueId() + ']');
} else {
Logger.log('Close time too close, closing immediately');
form.setAcceptingResponses(false);
}
} catch (e) {
Logger.log('Error in openForm: ' + e.toString());
}
}
function closeForm() {
try {
var form = FormApp.getActiveForm();
var now = new Date();
var nowLocal = now.toLocaleString('zh-TW', { timeZone: 'Asia/Taipei' });
Logger.log('Attempting to close form at: ' + nowLocal);
Logger.log('Form ID: ' + form.getId());
form.setAcceptingResponses(false);
Utilities.sleep(1000);
if (form.isAcceptingResponses()) {
Logger.log('Failed to close form!');
} else {
Logger.log('Form successfully closed at: ' + new Date().toLocaleString('zh-TW', { timeZone: 'Asia/Taipei' }));
}
} catch (e) {
Logger.log('Error in closeForm: ' + e.toString());
}
}
function deleteExistingTriggers() {
try {
var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() === 'openForm' ||
triggers[i].getHandlerFunction() === 'closeForm' ||
triggers[i].getHandlerFunction() === 'checkFormStatus') {
ScriptApp.deleteTrigger(triggers[i]);
Logger.log('Deleted trigger: ' + triggers[i].getHandlerFunction() + ' [ID: ' + triggers[i].getUniqueId() + ']');
}
}
} catch (e) {
Logger.log('Error in deleteExistingTriggers: ' + e.toString());
}
}
function checkFormStatus() {
try {
var form = FormApp.getActiveForm();
var now = new Date();
var nowLocal = now.toLocaleString('zh-TW', { timeZone: 'Asia/Taipei' });
var openTimeLocal = OPEN_TIME.toLocaleString('zh-TW', { timeZone: 'Asia/Taipei' });
var closeTimeLocal = CLOSE_TIME.toLocaleString('zh-TW', { timeZone: 'Asia/Taipei' });
Logger.log('Checking form status at: ' + nowLocal);
if (now >= OPEN_TIME && now < CLOSE_TIME && !form.isAcceptingResponses()) {
Logger.log('Form should be open but is closed - fixing');
form.setAcceptingResponses(true);
Utilities.sleep(1000);
if (form.isAcceptingResponses()) {
Logger.log('Form fixed - now open');
var minutesToClose = (CLOSE_TIME - now) / (1000 * 60);
if (minutesToClose >= 1) {
ScriptApp.newTrigger('closeForm')
.timeBased()
.after(Math.max(1, minutesToClose) * 60 * 1000)
.create();
}
} else {
Logger.log('Failed to fix form status');
}
}
} catch (e) {
Logger.log('Error in checkFormStatus: ' + e.toString());
}
}

搞定,收工!快來試試吧~

沒有留言:
張貼留言
歡迎大家一起留言討論!