どうもこたにんです。
GASで自作トリガー!ClockTriggerBuilder を使ってトリガーをカスタマイズしてみた!
ちょっくら作りたいものがありましてですね。
Gmailで受信するメールのうち、特定のメールを受信した時にスクリプトを実行させたい。
前回は、GAS側からGmailの受信トレイを検索して特定のメールを拾う、というのをやりました。
今回は続き、そのスクリプトを1分間隔で実行するためにトリガーを設定してみます。
- GASで自作トリガー!ClockTriggerBuilder を使ってトリガーをカスタマイズしてみた!
- GAS標準のトリガーは起動時刻を固定できない
- ClockTriggerBuilder でトリガーをカスタマイズする!
- 考察:カスタムトリガーの応用
GAS標準のトリガーは起動時刻を固定できない
GAS標準のトリガーに「時間主導型」というトリガーがあります。
時間主導型は、以下6種類。
タイプ |
概要 |
特定の日時 |
固定日付を指定し1回だけ実行する YYYY-MM-DD HH:MM |
分ベース |
一定の分間隔で実行する 1/5/10/15/30 分おき |
時間ベース |
一定の時間間隔で実行する 1/2/4/6/8/12 時間おき |
日付ベース |
1日1回、特定の1時間の中で実行する 各時間帯(0-1時/1-2時/2-3時…) |
週ベース |
1週間1回、特定の曜日の中で実行する 毎週月火水木金土日 |
月ベース |
1ヶ月1回、特定の日付の中で実行する 毎月固定日付(1日/2日/3日…) |
これらを、画面上で簡単に設定することができます。
今回やりたいこと、1分間隔のトリガーも、簡単に設定できます。
できた!
ただしこれでは、1日1440分、1440回叩かれることになります。
そうなんです。
コンソール上で設定できるトリガーは、ちょっとかゆいのです。
バシッとスケジューリング、ができないのです。
日付ベースで設定しても、1時間のうち何分に実行されるのかがわからないのです。
crontab を使い慣れている勢としては、かゆくてしかたがないのです。
なので今回はスクリプト側から、任意の時間帯で発動できるようにします。
具体的に文字にすると、こういう動きを実現してみます。
「8:00-10:00まで1分間隔で動くトリガー」
1440回ではなく、たった120回だけ動くようにしたいです。
画面上で設定するトリガーでは実現できないので、GAS内に用意されているクラスに頼ることにしましょう。
ClockTriggerBuilder でトリガーをカスタマイズする!
通常の時間主導型トリガーは、起動したり停止したりすることができません。
なので「起動・停止を行うスクリプトを実行する」という方式を取ります。
その際に利用するのは ClockTriggerBuilder クラス。
このクラスを利用することで、画面上で設定するトリガーと同じことをスクリプトで実現できます。
ここからは「8:00-10:00まで1分間隔で動くトリガー」を実際に作っていきましょう。
8:00-10:00まで1分間隔で動くトリガーの完成イメージ
今回実現するカスタムトリガーを図示します。
箇条書きで流れを説明します。
- 0時:トリガーを2つ登録するスクリプト main を実行
- 8時:mailTrigger を登録するスクリプト minuteTrigger を実行
- mailTrigger:1分おきにトリガーを実行するスクリプト
- 8〜10時:メイン処理が走る
- 10時:mailTrigger を削除するスクリプト deleteMailTrigger を実行
百聞は一見にしかず、スクリプトを見ていきましょう。
起動時刻指定でトリガーを作成する
まずは、8時起動・10時起動の2つのトリガーを作るmain関数を作ります。
function main() {
deleteTrigger('minuteTrigger');
var registerDate = new Date();
registerDate.setHours(08);
registerDate.setMinutes(00);
ScriptApp.newTrigger('minuteTrigger').timeBased().at(registerDate).create();
deleteTrigger('deleteMailTrigger');
var registerDate = new Date();
registerDate.setHours(10);
registerDate.setMinutes(00);
ScriptApp.newTrigger('deleteMailTrigger').timeBased().at(registerDate).create();
}
function deleteTrigger(triggerName) {
ScriptApp.getProjectTriggers().forEach(function(trigger) {
if (trigger.getHandlerFunction() == triggerName) {
ScriptApp.deleteTrigger(trigger);
}
});
}
GAS内でトリガーを作成するには ScriptApp.newTrigger() を利用します。
引数にトリガー名を渡すと、その名前でトリガーを作成してくれます。
newTrigger() は TriggerBuilder クラスでチェーンできるので、時間主導型トリガーを示す timeBased() メソッドをつなぎます。
timeBased() はさらに ClockTriggerBuilder クラスでチェーンできます。
at() メソッドで起動時刻を指定してやりましょう。
最後に create() でバシッと作っておわり。
また、このmain関数は1日1回起動するため、前日に登録していたトリガーを削除する処理も組み込んでおきましょう。
deleteTrigger()メソッドをさくっと自作しておきました。
1分間隔のトリガーを作成する
1分間隔でメイン処理を動かすトリガーを作るminuteTrigger関数を作ります。
function minuteTrigger() {
deleteTrigger('mailTrigger');
ScriptApp.newTrigger('mailTrigger').timeBased().everyMinutes(1).create();
}
作り方は先ほどとほとんど同じです。
ただ、1分間隔を設定するため everyMinutes() メソッドで1分を指定します。
ここで注意なのが、関数名を先に登録したトリガー名と合わせておくこと。
関数名とトリガー名が紐付くので。
メイン処理を書く
残すはメイン処理です、さくっと書きましょう。
function searchMail() {
var threads = GmailApp.search('subject:返却完了 label:unread');
GmailApp.getMessagesForThreads(threads).forEach(function(msg) {
var date = Utilities.formatDate(msg[0].getDate(), 'Asia/Tokyo', 'yyyy-MM-dd HH:mm:ss');
sendSlack('返却完了 ' + date);
msg[0].markRead();
});
}
これは前回記事で作成済みなので、説明も省略。
カスタムトリガー完成!
これで完成です!
作った関数を実行させてトリガーを画面で確認するとちゃんとできていることがわかります。
あとは、メイン関数を1日ごとのトリガーとして登録しておけば、動くぞ。
考察:カスタムトリガーの応用
今回はやりたいことが細かったので少し複雑なカスタムトリガーになりました。
が、作り方によっては、もっとライトなものも作れます。
- 毎日9:00に実行する
- 火曜と金曜の23:30に実行する
- 12:00-13:00/18:00-19:00実行する
無理のない頻度でスクレイピングしたり、スプレッドシート反映したり。
やりたいことに合わせて好きなようにカスタマイズできそうです。
好きなだけ好きなようにトリガーをカスタマイズして素敵なGASライフ!!