[GoogleAppsScript] Chrome V8ランタイムで2回目のトリガーが無効になる（GASのバグ）

# はじめに
**2022/01/30 現在**
Google Apps Script（GAS）で`ScriptApp.newTrigger`でトリガーを設定すると、2回目の自動実行が無効になります。2020に導入された`Chrome V8ランタイム`が有効になっている場合に発生するようです。古いGASのソースコードでは発生しておりませんので、V8ランタイムのバグだと言われています。

# 事象詳細
1分後に自分自身の関数を起動するプログラムを作成しました。

```JavaScript:main.gs
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回目の自動実行が行われません。

```text:log
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"
```

トリガーの状態を確認すると`無効`と表示されています。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50563/86cbebfa-758b-b69e-5997-875548674f5f.png)

アイコンをクリックすると 無効理由に`このトリガーは無効になりました。原因は不明です。`と表示されます。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50563/df4b889f-cd29-02ff-790a-e018a0727941.png)

# 回避方法
以下の2つの方法があります。
- V8ランタイムを無効にする。
- WEBアプリをデプロイする。

## V8ランタイムを無効にする
V8ランタイムを無効にします。その場合、ES5（古い構文のJavaScript）でソースコードを書き換えが必要になります。

1. GASのプロジェクト設定で、`Chrome V8 ランタイムを有効にする`チェックを外します。
![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50563/01abd5ac-d853-4128-342e-481c3a0bdd27.png)

## WEBアプリをデプロイする
V8ランタイムを有効にする場合、GASのバグが修正されるまでの暫定的な回避方法になります。参考記事で回避方法を参考にさせていただきました。恒久的な回避方法ではないので注意です。

1. 以下のコードを追加します。

```JavaScript:main.gs
/**
 * V8トリガーバグ対策
 */
function doGet() {
    main();
}
```

2. GASで`デプロイ`から`新しいデプロイ`を選択します。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50563/249be8a5-6467-3bfc-f2f5-f0cd11564629.png)

3. 特に設定の変更は必要なく、`デプロイ`を選択します。
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50563/db90620a-fdea-2a5b-679b-a81226ec3e30.png)

4. デプロイ後のURLをクリックします。1で追加されたコードが実行されます。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50563/813f831a-19ff-70c6-586e-d5809497e9ab.png)

5. 下記のような画面が表示されます。
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50563/ec31c7d9-ed5b-8501-0323-7d2b2a124f17.png)

※デプロイ後、ソースコードを修正した場合、再度デプロイが必要になります。

# 参考リンク
- [【GAS】コードで追加したトリガーが無効になる場合の対処](https://zenn.dev/datsukan/articles/f525e0f7af6859)
- [Google Apps Scriptでスクリプト内から時間ベースのトリガーを作成する](https://or3.hatenablog.com/entry/2021/11/01/192100)

# さいごに
- V8ランタイムを無効にしてソースコードをES5に書き換えて見ましたが意外と大変です。WEBアプリをデプロイした方が楽だと思います。
- ソースコードをGitHubに公開しています。
    - [ソースファイルはこちら](https://github.com/yunbow/sample-GoogleAppsScript/tree/main/Trigger)

以上です。