はじめに
隔月で発生する手動リマインドが手間でいつか忘れてしまいそうなので、GAS(Google Apps Script)を使って自動化してみました。
GASの標準機能だけでは「隔月の毎週〇曜日」というような変則的なスケジュールを指定できませんが、コードからタイマー(トリガー)を動的に制御することで、変則的なスケジュールの指定ができます。
今回は実際に「奇数月の毎週水曜日」にだけGoogle Chatへ自動でリマインドを投稿する仕組みを作ってみたので、その具体的な実装方法をご紹介します。
実装の手順
実装は以下の4つのステップで進めます。
- Google ChatのWebhook URLを作成する
- リマインド通知の関数を作成する
- トリガーを設定・解除する関数を作成する
- 最初の「毎月1日のトリガー」を登録する
1. Google ChatのWebhook URLを作成する
今回は、Google Chatに外部からメッセージを自動送信するためにWebhookという仕組みを使います。
以下の手順でWebhook URLをGoogle Chat側で作成します。
- 通知を飛ばしたいGoogle Chatのスペースを開く
- スペース名の横にある
⋁からメニューを開き、「アプリと統合」→「Webhook」を選択する - 任意の名前を入力して保存する
- 画面に生成された Webhook URL をコピーする(後ほどGASのコードに貼り付けます)
2.リマインド通知の関数を作成する
GASのエディタを開き、実際にチャットへメッセージを送信する関数を作成します。
function sendNotification() {
const webhookUrl = "https://chat.googleapis.com/v1/spaces/XXXXX/messages?key=XXXXX&token=XXXXX";
const message = {
"text": "<users/all>\n【定期リマインド】\n今月は〇〇の実施月です。\n各自、内容のご確認とご対応をお願いいたします!"
};
const options = {
"method": "post",
"contentType": "application/json",
"payload": JSON.stringify(message)
};
try {
UrlFetchApp.fetch(webhookUrl, options);
Logger.log("通知を送信しました。");
} catch(e) {
Logger.log("エラーが発生しました: " + e.toString());
}
}
webhookUrlを定義
先ほど取得したWebhook URLを指定します。
messageを指定
チャットに送りたいデータを記述します。
<users/all>を先頭につけることで、スペース内の全員へ一斉メンション(@all)を飛ばすことができます。
optionsの設定
Google Chatへデータを送る際の通信ルールや、送信するデータの詳細を設定します。
-
"method": "post":データの送信方法を指定します
今回はGoogle Chat側へデータを新しく送り届けて投稿したいため、今回はpostを指定します -
"contentType": "application/json":送信するデータの形式を指定します
Google ChatのWebhookは JSON(ジェイソン)形式 のデータしか受け取れないルールになっているため、"application/json"を指定します -
"payload": JSON.stringify(message):送信するデータの本体を指定します
今回はメッセージ内容(message)のみをデータ本体として指定します。GASのオブジェクト型のデータのままでは送信できないため、JSON.stringify()でJSON形式の文字列に変換して設定します。
UrlFetchApp.fetchとtry-catch
ここで実際に宛先URLへメッセージを送り出しています。
万が一URLが間違っていたり通信エラーが起きたりしても、エラーをキャッチしてログに原因を出力する設計にしています。
3. トリガーを設定・解除する関数を作成する
月と曜日を自動で判定してタイマーをセットする関数(setTrigger)を、先ほどのコードの下に追加します。今回は「奇数月の毎週水曜日 13:00」を例に記述しています。
function setTrigger() {
const now = new Date();
const currentMonth = now.getMonth() + 1;
const triggers = ScriptApp.getProjectTriggers();
for (let i = 0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() === "sendNotification") {
ScriptApp.deleteTrigger(triggers[i]);
}
}
if (currentMonth % 2 === 1) {
ScriptApp.newTrigger("sendNotification")
.timeBased()
.onWeekDay(ScriptApp.WeekDay.WEDNESDAY)
.atHour(13)
.nearMinute(0)
.create();
Logger.log("今月は対象月のため、毎週水曜日13:00のタイマーをセットしました。");
} else {
Logger.log("今月は対象外の月のため、タイマーはセットしません。");
}
}
currentMonthを設定
getMonth()は0〜11で値が返ってくるため、+1します。
トリガーの重複を防ぐ処理
GASの仕様上、同じトリガーを何度も作成すると二重に登録され、メッセージが連投されてしまいます。
それを防ぐため、新しいタイマーを作る前に既存のトリガーをすべてチェックし、すでに sendNotificationが設定されている古いトリガーを一度削除してリセットしています。
条件分岐(if文の部分)
今月の数字を2で割った余りが1(奇数月)のときだけ、毎週水曜日の13:00頃に自動実行するトリガーを作成しています。
4. 毎月1日にsetTriggerを実行するように設定
以下の手順で、「毎月1日」にsetTriggerを実行するようにします。
- GAS画面の左側メニューから、時計マーク(トリガー) を開く
- 右下の「トリガーを追加」ボタンを押す
- 以下のように各項目を設定して保存する
- 実行する関数:setTrigger
- イベントのソース:時間主導型
- タイプ:月ベースのタイマー
- 日:1日
- 時刻:13:00までの任意の時間
これで、毎月1日になると自動で setTrigger が動き、その月が奇数月であれば「毎週水曜日 13:00頃」のタイマーを全自動で管理してくれるようになります。
最初に1回だけ手動実行が必要
月ベースのトリガーを設定しただけでは、次の「1日」が来るまでタイマーがセットされません。そのため、最初に1回だけ手動で実行して、今月のトリガーを予約しておく必要があります。
- GASのエディタ画面に戻る
- 画面上部の【実行する関数】を
setTriggerに変更 - 「▷ 実行」ボタンをクリック
setNotification()で実行しないよう注意
【実行する関数】をsetNotification()のまま実行してしまうと、「▷ 実行」をクリックした瞬間にGoogle Chatでメッセージが投稿されてしまいます。
実行前に【実行する関数】がsetTriggerであるかを必ず確認してください。
実行結果
設定が完了すると、毎月1日に条件に合わせたタイマーが自動で実行されるようになります。
-
対象の月(奇数月)になったとき:
「毎週水曜日 13:00頃」のトリガーが予約され、指定の曜日・時間になるとGoogle Chatへリマインドメッセージが投稿されます。
-
対象外の月(偶数月)になったとき:
先月のタイマーが削除され、その月はチャットへの投稿が実行されません。
まとめ
今回は日常のちょっとした手動リマインドを自動化しただけですが、思った以上に楽しかったです。
祝日は送信をスキップするなどの機能を追加したり、スプレッドシートへの自動入力など他の業務自動化の仕組み作りにもチャレンジしようと思いました。



