見出し画像

GASでもっと自由になるtriggerセットの方法

Google Apps Scriptを書いてて、Utilities.sleep() でもっとたくさん待ちたいと思ったことはありませんか?

現在のGASの仕様上では Script runtimeは実行毎6分に制限がされています

自動化に関する様々な処理を検討していると、下記のようなことが稀にあったります。

(SUCCESS!から1時間後に決め打ちでトリガーをセットして、前処理がコケてたら何もせずにスキップしたらいいのでは?って話はトリガーを紹介できなくなるので、思いっきり一旦置いておきます)

そんな際に、スクリプト上でtriggerを作成すれば6分間の制限から解放されて、もっと自由になれる気がした…そんな記事になります。

スクリプトからtriggerを作成

そんなとき、GASでスクリプトからトリガーをセットしたり、削除したりすることが可能です。

流れ

・最初のプロセスが実行
・次のプロセスを2時間後に実行するトリガーをセット
・次のプロセスが2時間後に実行される

利用するスプレッドシート

こんな感じのものを用意して読み書きします。

トリガーを作成

トリガーを作成します。たしか割と細かい単位で設定が可能だったと思います。※詳しくはこちらのリファレンス

// トリガーを作成
function setTrigger() {
   // トリガーをセットしたい関数を記載
   const funcName = "succeedProcess";
   // triggerTime分後に実行されるトリガー作成
   const triggerTime = configSheet.getRange("D2").getValue();
   ScriptApp.newTrigger(funcName).timeBased().after(triggerTime * 60 * 1000).create();
   const trigger = ScriptApp.getProjectTriggers();
   const id = trigger[0].getUniqueId();
   // シートへ triggerId をセット
   configSheet.getRange("B2").setValue(id);
   GmailApp.sendEmail("slack@example.slack.com", "件名", "トリガーセットの完了");
}

トリガーを削除する

ワンタイムなトリガーですが残ったままだとGAS以外でもトリガーを使ってた場合、管理が煩雑になるため削除します(残っているとなんらかの制限に引っかかるとかもあるのかも)

// トリガー削除
function deleteTrrigers() {
   // シートから triggerId を取得
   const triggerId = configSheet.getRange("B2").getValue();
   const currentTriggers = ScriptApp.getProjectTriggers();
   // トリガーを削除
   currentTriggers.some(currentTrigger => {
       if (currentTrigger.getUniqueId() === triggerId){
           ScriptApp.deleteTrigger(currentTrigger);
           GmailApp.sendEmail("slack@example.slack.com", "件名", "トリガー削除の完了", options);
       }
   });
}

コード全体

// 最初に実行されるプロセス
function precedeProcess() {
   try {
       // なんらかの処理を記述
       execute();
       configSheet.getRange("A2").setValue("実行完了");
       // 後続処理(GAS)のためのトリガーをセット
       setTrigger();
   } catch (e) {
       GmailApp.sendEmail("slack@example.slack.com", "件名", e, options);
   }
}


// 次に実行されるプロセス
function succeedProcess() {
   const datetime = Utilities.formatDate(new Date(), "JST", "yyyy/MM/dd (E) HH:mm:ss Z");
   configSheet.getRange("C2").setValue(datetime);
   deleteTrrigers();
   try {
       const result = configSheet.getRange("A2").getValue();

       if (result === "実行完了") {
           // 処理を記述
           executeAgain();
           configSheet.getRange("A2").setValue("");
       } 
   } catch (e) {
       GmailApp.sendEmail("slack@example.slack.com", "件名", e, options);
   }
}


// ----- トリガー ----- //

// トリガーを作成
function setTrigger() {
   // トリガーをセットしたい関数を記載
   const funcName = "succeedProcess";
   // triggerTime分後に実行されるトリガー作成
   const triggerTime = configSheet.getRange("D2").getValue();
   ScriptApp.newTrigger(funcName).timeBased().after(triggerTime * 60 * 1000).create();
   const trigger = ScriptApp.getProjectTriggers();
   const id = trigger[0].getUniqueId();
   // シートへ triggerId をセット
   configSheet.getRange("B2").setValue(id);
   GmailApp.sendEmail("slack@example.slack.com", "件名", "トリガーセットの完了", options);
}


// トリガー削除
function deleteTrrigers() {
   // シートから triggerId を取得
   const triggerId = configSheet.getRange("B2").getValue();
   const currentTriggers = ScriptApp.getProjectTriggers();
   // トリガーを削除
   currentTriggers.some(currentTrigger => {
       if (currentTrigger.getUniqueId() === triggerId){
           ScriptApp.deleteTrigger(currentTrigger);
           GmailApp.sendEmail("slack@example.slack.com", "件名", "トリガー削除の完了", options);
       }
   });
}


参考記事


この記事が気に入ったらサポートをしてみませんか?