🌊

【GAS】正確な時間に起動するトリガーを作る

2020/10/30に公開2

はじめに

みなさんGASを使っているでしょうか。
Javascriptライクな仕様に加えGoogle関連のサービスと非常に相性がよく、Gmailを自動送信したりGoogleSpreadSheetの中身を操作したりと活用できる場面は非常に広いです。

そんなGASの機能として「トリガー」というものがあります。
予め記述されたコードを特定の条件で実行させる機能なので、バッチ処理などをこれで賄っている方もいるのではないでしょうか?

そんなGASのトリガーですがちょっとした欠点があります。
UIから時間を指定して扱おうとすると、下記のようにしか条件を設定できません。

trigger1

そうです、実行時間に幅が生じるのです。
時間指定のトリガーを選択しても、実際の実行時間には1時間の幅ができてしまいます。
ランタイムから何から用意してもらっている手前、あまり文句も言えないなぁと思っていたのですが、しっかりと解決策がありました。

ただ、UIからでなくコード内で対処する必要があったので記事としてまとめたいと思います。

コード

まず初めに完成品となるコードです。

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

// 翌日の日付に変換
next.setDate(next.getDate() + 1);

// 09:30:00に時刻を設定
next.setHours(9);
next.setMinutes(30);
next.setSeconds(0);
  
// hogeという関数を9時に実行するトリガーを作成
ScriptApp.newTrigger('hoge').timeBased().at(next).create();

最後の1行に見慣れないモジュールがあるので、そこを中心に解説していきます。

ScriptApp.newTrigger

ScriptApp.newTriggerGASで標準で用意されているモジュールで、トリガー(TriggerBuilder型)のインスタンスを生成します。

引数には文字列で、実行させたい関数名を指定します。

// test()を実行するTriggerBuidlerを生成
const testTrigger = ScriptApp.newTrigger('test');

まだこの段階ではトリガーは設定されません。
生成したインスタンスのcreate()を実行することではじめてトリガーが設定されます。

// testTriggerを設定
testTrigger.create();

timeBasedを使ってClockTriggerBuilderを生成

目的のトリガーは、時間を指定して起動するタイプのトリガーです。
なので通常のTriggerBuilderではなくClockTriggerBuilder型のインスタンスを使用する必要があります。

ClockTriggerBuilderTriggerBuilderインスタンスのtimeBased()を実行することで生成されます。
生成したClockTriggerBuilderインスタンスにはat()を使って実行時間を指定することができます。
引数はDate型です。

// testTriggerからClockTriggerBuilderを生成
const testClockTrigger = testTrigger.timeBased();
// 2020/01/01 00:00:00で時間指定し、トリガーをセット
testClockTrigger.at(new Date(2020,11,25)).create();

実行結果

先の完成版コードを実行した場合、UIでトリガーを確認すると以下のような表示となっています。

trigger2

トリガーのタイプが「日付ベースのトリガー」から「特定の日時」に変わり、実行時間も1時間の幅がなく、正確な時刻が設定されていることが分かります。

まとめ

毎日決まった時刻に起動する処理を作成するには、この仕様を利用するのがミソです。
実行処理の最後に「自分自身を呼び出す時間指定トリガーをセット」することで、擬似的に毎日決まった時間に動作するトリガーを生成することができます。

Discussion

hato-codehato-code

参考になりました!
他の記事の投稿も楽しみに待ってます!

nekonikinekoniki

コメントありがとうございます!励みになります!!