はじめに
2022/01/30 現在
Google Apps Script(GAS)でScriptApp.newTrigger
でトリガーを設定すると、2回目の自動実行が無効になります。2020に導入されたChrome V8ランタイム
が有効になっている場合に発生するようです。古いGASのソースコードでは発生しておりませんので、V8ランタイムのバグだと言われています。
事象詳細
1分後に自分自身の関数を起動するプログラムを作成しました。
function main() {
try {
console.log('>>> main start');
// 1分後にトリガーをセットする
let date = new Date();
date.setMinutes(date.getMinutes() + 1);
date.setSeconds(0);
console.log(`Trigger=${date}`);
setTrigger(date);
} catch (e) {
console.error(e.stack);
} finally {
console.log('>>> main end');
}
}
function setTrigger(date) {
// 古いトリガーを削除する
const oldTriggerList = ScriptApp.getProjectTriggers();
for (let i in oldTriggerList) {
const oldTrigger = oldTriggerList[i];
if (oldTrigger.getHandlerFunction() == 'main') {
ScriptApp.deleteTrigger(oldTrigger);
}
}
// 新しいトリガーを設定する
ScriptApp.newTrigger('main')
.timeBased()
.at(date)
.create();
}
(1) 手動実行(GASで関数を指定して実行)して、1分後にトリガーを設定します。
(2) 1回目の自動実行(トリガーから起動)して、1分後にトリガーを設定します。しかし、2回目の自動実行が行われません。
2022-01-30 12:43:10:548 DEBUG main(20) ">>> main start" // (1)
2022-01-30 12:43:10:732 DEBUG main(26) "Trigger=Sun Jan 30 2022 12:44:00 GMT+0900 (Japan Standard Time)"
2022-01-30 12:43:11:434 DEBUG main(33) ">>> main end"
2022-01-30 12:44:32:614 DEBUG main(20) ">>> main start" // (2)
2022-01-30 12:44:32:829 DEBUG main(26) "Trigger=Sun Jan 30 2022 12:45:00 GMT+0900 (Japan Standard Time)"
2022-01-30 12:44:33:554 DEBUG main(33) ">>> main end"
アイコンをクリックすると 無効理由にこのトリガーは無効になりました。原因は不明です。
と表示されます。
回避方法
以下の2つの方法があります。
- V8ランタイムを無効にする。
- WEBアプリをデプロイする。
V8ランタイムを無効にする
V8ランタイムを無効にします。その場合、ES5(古い構文のJavaScript)でソースコードを書き換えが必要になります。
WEBアプリをデプロイする
V8ランタイムを有効にする場合、GASのバグが修正されるまでの暫定的な回避方法になります。参考記事で回避方法を参考にさせていただきました。恒久的な回避方法ではないので注意です。
- 以下のコードを追加します。
/**
* V8トリガーバグ対策
*/
function doGet() {
main();
}
※デプロイ後、ソースコードを修正した場合、再度デプロイが必要になります。
参考リンク
さいごに
- V8ランタイムを無効にしてソースコードをES5に書き換えて見ましたが意外と大変です。WEBアプリをデプロイした方が楽だと思います。
- ソースコードをGitHubに公開しています。
以上です。