🤖

【GAS】コードで追加したトリガーが無効になる場合の対処

2021/06/20に公開

なんの話か

Google App Script(以後GASと呼ぶ)で遭遇した問題に関する共有です。
ScriptApp.newTriggerを使ってプログラムから追加したトリガーが無効になりました。

やろうとしたこと

一回目を手動実行して、2回目以降はプログラム内で次の実行トリガーを追加するコードを書きました。

何が起きたか

2回目の実行(自動実行の初回)は問題なく実行されました。
しかし、3回目の実行(自動実行の2回目)が実行されず、トリガーの"前回の実行"項目には「このトリガーは無効になりました。原因は不明です。」というメッセージが表示されました。

対処内容

ググってみたところ、類似事例は見つかりませんでした。
ですが、GASの不具合でエラーになるケースは多いようです。
その場合、"プロジェクトの設定"から"Chrome V8 ランタイム"を無効にすると正常に動作する報告が多数ありました。
同じく私も無効にしたところ正常に実行されるようになりました。

追記 2021.06.20

同様の事象について触れているページを見つけました。
やはりGASのV8ランタイムでのバグのようです。
https://stackoverflow.com/questions/63663359/google-apps-script-disables-recurring-time-based-trigger

追記 2021.06.21

さらに検証したところ、GASのエディタ画面にある"実行"ではなく、一回ウェブアプリケーションとしてデプロイして、その実行URLから初回実行すると、その後の自動実行が正常に行われ続けることを発見しました。
恐らくですが、実行権限的な問題なのかもしれません。
この方法であれば"Chrome V8 ランタイム"を有効にしたまま実行できます。

追記 2021.07.01

デプロイさえすればトリガーの実行からでも問題なく実行し続けるようです。

注意点

"Chrome V8 ランタイム"を無効にすると使用できるJavaScriptの構文に制限がかかる(多分JavaScriptの実行バージョンが古くなってモダンなバージョンの構文が使えない)ので、処理の書き方を修正する必要が発生するかもしれません。
まぁ無料で使えるのでここらへんは割り切るしかないかもしれません。

参考

今回私が使用した実行トリガーの自動作成の処理を記載しておきます。

メインメソッド

mainメソッドがトリガーの対象になるメソッドです。

function main() {
  setTrigger();  // トリガーを設定する処理
  postMessage(); // 定期実行したいメインの処理 今回はメッセージ送信 ※内容省略
}

トリガー設定メソッド

// トリガーを設定する
function setTrigger() {
  // 他のトリガーを削除する
  deleteTrigger();

  // 現在の日付を取得
  const next = new Date();

  // 一分後の日付に変換
  next.setMinutes(next.getMinutes() + 1);
  next.setSeconds(0);
    
  // mainという関数を実行するトリガーを作成
  ScriptApp.newTrigger('main').timeBased().at(next).create();
}

// トリガーを削除する
function deleteTrigger() {
  // 設定済みのトリガーをすべて取得する
  const triggers = ScriptApp.getProjectTriggers();

 // 取得したトリガーをforeatchで順番に処理する
  triggers.forEach(function(trigger) {
    if(trigger.getHandlerFunction() == "main") {
      // mainメソッドのトリガーの場合は削除する
      ScriptApp.deleteTrigger(trigger);
    }
  });
}
GitHubで編集を提案

Discussion