概要
GoogleAppsScriptで毎回定時にスクリプトを実行したくて、実行されるたびに次のトリガーをセットするコードを書いたところ、2回目が実行されず「このトリガーは無効になりました。原因は不明です。」という表示が?
ググってみたら似たような事例があるようで、V8ランタイムのバグなんだとか。
複数のページで紹介されていた回避方法は、V8ランタイムを無効にするか、コードをデプロイしWEBアプリとして実行するというもの。
V8無効はなんか嫌だしWEBアプリってのも面倒だなぁ・・・と別の方法を試したところ、あっさり解決したので投稿。
方法
エラーに共通しているのが、最初の実行を手動で行っているという事。
WEBアプリからの実行で回避する方法もそうだけど、もしかして初回を手動で実行しなければ行けるんじゃね?と思い試してみたのが次の方法。
もったいつけてみたけど超簡単で 最初の実行をトリガーから実行 しただけ。
もうちょっと詳しく
例えばこんなコードを作ったとする。
function set_trigger() {
var triggers = ScriptApp.getProjectTriggers();
for(var trigger of triggers){
if(trigger.getHandlerFunction() == 'set_trigger'){
ScriptApp.deleteTrigger(trigger);
}
}
myFunction();
var time = new Date();
time.setMinutes(time.getMinutes()+1);
ScriptApp.newTrigger('set_trigger').timeBased().at(time).create();
}
set_trigger
を実行すると、set_trigger
がセットされたトリガーを削除、myFunction
を実行、新しくset_trigger
を実行するトリガーを1分後にセットする。
(myFunction
は何でもいいので省略)
これで、1分毎にmyFunction
が実行されるはず・・・。
だけど「このトリガーは無効になりました。原因は不明です。」となってしまう。回避するには概要で書いた方法が一般的。
無効になる場合
①手動実行
②トリガーがセットされる
③なぜか無効になる
回避できる場合
①WEBアプリで実行
②トリガーがセットされる
③実行され次のトリガーもセット
以降③の繰り返し
そこで試してみたのが
最初からトリガーで実行すれば、回避できる場合の③からスタートしたことにならないかなと思って、set_trigger
を時間主導型のトリガーにセットして実行してみた。
こんな画像が証拠になるとは思わないけど^^;
あっさりエラー回避できてしまった。
最後に
今回のmyFunction
は、スプレッドシートに実行時間を書き出すだけの簡単なコードで、手動実行からはエラーになり、確かにこの方法でエラーを回避できたわけだけど、他のコードでも必ず回避できるかは検証してないので悪しからず。
試してみたら意外と上手くいくかもよって程度の記事。