Google Calendar for Team EventのSlack通知が来なくなったので、Makeで代理通知するシナリオを作ってみた
事の発端
READYFORでは、リリース予定がバッティングすることを防ぐため、Googleカレンダーに「プロダクト開発カレンダー」という共有カレンダーを作り、リリース予定が決まったらプロダクト開発カレンダーに予定を登録する、という運用をしています。
プロダクト開発カレンダーの予定は、Slack 向け Google Calendar for Team Eventsを利用してSlackへ通知するようになっているのですが、2023年1月の2週目あたりから、急にSlackへ通知されなくなってしまいました。
過去にも度々通知されなくなることはあったものの、連携しなおしたり設定を更新することで対処できていたのですが、今回はどうにもうまくいきません。
2023年の3月には非推奨になるアプリでもあるので、もう望みは薄いだろうな…ということで、Make(integromat)を利用して、Google Calendar for Team Eventsの代わりにリリース予定を通知する仕組みを作ってみました。
Makeを採用するまで
条件
代替手段を探すにあたり、MustとWantの条件を定めます。
今までできていたことはMust、「多分今まではできていたんだろうなぁ」というところはWantにします。
Must
- 複数人で管理ができること
- 共有カレンダーを連携できること
- 任意のパブリックチャンネルへ投稿できること
- 開始時間のn分前に投稿できること
- 今まではリリース予定の開始15分前に通知するようにしていたため、同様に開始5-15分ぐらい前に投稿できるようにします
- 月200ぐらいの予定を通知できること
- 直近3ヶ月にカレンダーに入っていた予定の平均を参考に、余裕を持たせたバッファを込みにすると大体これぐらいかな…のざっくり計算です
Want
- 1ヶ月あたりMax1600の予定を通知できること
- 雑に全営業日にぎっしりリリース予定が登録された場合を計算すると、
- 1つの予定を30分枠、1日8時間の中にぎっしり予定を詰め込んだとして、1時間あたり2予定 * 8時間 = 16予定
- 16予定 * 5営業日 * 月の営業日目安として20日 = 1600予定
- 雑に全営業日にぎっしりリリース予定が登録された場合を計算すると、
代替手段の検討
- Google Calendarアプリ
- Google App Scriptで自作
- Zapier
- Make
Google Calendarアプリ
Google Calendar for Team Eventsのページにも
これに代わるツールをお探しの場合は、Google カレンダーアプリをお試しください。
https://slack.com/intl/ja-jp/help/articles/360047938054
と掲載されているため、ひとまずGoogle Calendarのアプリで同様の動きができるか確認します。
Must条件 | 対応可否 |
---|---|
複数人で管理ができること | ? |
共有カレンダーを連携できること | ◯ |
任意のパブリックチャンネルへ投稿できること | × |
開始時間のn分前に投稿できること | ◯ |
月200ぐらいの予定を通知できること | ◯ |
2023年1月現在、Google Calendarアプリでは任意のチャンネルへの投稿はできないようで、この時点で今回採用するのは厳しそうです。
もしかするといつか実装されるかもしれない…ので、期待をしつつ、いつまでも待つことはできないので、今回は見送ることにしました。
(今後に期待…!)
Google App Scriptで自作
元々コードの管理や運用のコストが懸念として上がっていたところもあったので、最終手段かなぁ…と考えていました。
Must条件 | 対応可否 |
---|---|
複数人で管理ができること | ◯ |
共有カレンダーを連携できること | ◯ |
任意のパブリックチャンネルへ投稿できること | ◯ |
開始時間のn分前に投稿できること | ◯ |
月200ぐらいの予定を通知できること | ◯ |
コードを書く必要はありますが、複数人での編集も招待すれば可能で、他の条件もAPIでどうにかはできます。
条件としてはMustもWantも全て満たせるのですが、やっぱりコストがなぁ…ということで、一旦保留にして他のサービスを検討します。
Zapier
連携と言えばiPaaSかなと、とりあえず思い浮かんだZapierを見ていきます。
Must条件 | 対応可否 |
---|---|
複数人で管理ができること | △ |
共有カレンダーを連携できること | ◯ |
任意のパブリックチャンネルへ投稿できること | ◯ |
開始時間のn分前に投稿できること | ◯ |
月200ぐらいの予定を通知できること | △ |
すごく良さそう…ではあるのですが、複数人での管理、月200ぐらいの予定を捌けるかどうかはプラン次第なところがあります。
「Slackに投稿」のようなアクションがZapierのタスクにあたり、Freeプランは月100タスクまでという制限があります。
Zapierを使う場合に想定される1回あたりのタスクは、Googleカレンダーの予定取得 + Slack投稿の2回なので、Freeプランの範囲内では、月50回しか通知ができなさそうです。
また、Teamプラン以上でないと複数人での管理ができないため、今回は見送りました。
参考
Make
「なんか昔良いなーと思ったけど、初見での操作が難しくてすぐ離れちゃったのあったんだよなぁ」と思ってなんとか思い出したのがIntegromatです。
いつの間にか名称がMakeに変わっていました。
Must条件 | 対応可否 |
---|---|
複数人で管理ができること | ◯ |
共有カレンダーを連携できること | ◯ |
任意のパブリックチャンネルへ投稿できること | ◯ |
開始時間のn分前に投稿できること | ◯ |
月200ぐらいの予定を通知できること | ◯ |
なにやら良い感じです。
Zapierではタスクと呼ばれていたものがMakeでは(ほぼ)オペレーションにあたり、Freeプランは月1000オペレーションまでという制限があります。
Makeを使う場合に想定される1回あたりのオペレーションも、Googleカレンダーの予定取得 + Slack投稿の2回なので、Freeプランの範囲内では月500回と、Wantの1600回までは難しいですが、超単純計算ではMust条件は満たしています。
(厳密にはカレンダーの予定が2つ取得されたら、Slack投稿は2回で計3回だったりと、タイミングによって前後します)
代理として使えるかどうかは、とりあえずFreeプランの範囲内で運用してみて考えようか、ということで、今回はMakeを採用することにしました。
参考
Makeで予定通知できるようにする
Templateを探す
今回のような「カレンダーに入っている予定を、n分前に特定のチャンネルへ投稿する」といった用途は多方面でニーズがありそうなので、まずはTemplateを漁ってみたものの、ドンピシャなものは見つけられませんでした。
近いもので「リマインダーをセットする」というテンプレートはあったので、自分にだけのリマインダーをセットする用途であれば使えるかもしれません。
シナリオを作る
なければ作るのみなので、Makeでモジュールを追加してシナリオを作っていきます。
ユーザーがカレンダーへ予定を追加した後、Makeでは作成されたイベントを拾い、Slackへ投稿する流れを作ります。
作り方
-
Google Calendarのアプリを選択
シナリオを新規作成すると、真ん中に「+」のマークが表示されます。
「+」を選択するとアプリ選択のポップが出てくるので、その中から「Google Calendar」を探し、選択します。
-
「Watch Events」を選択
今回は追加された予定を取得して予約投稿できるようにしたいので、「Watch Events」を選択します。
-
連携するカレンダーの設定
- Connection
連携するGoogle Calendarのアカウントを選択します - Calendar
連携するカレンダーを選択します - Watch Events
イベントの作成、更新、開始、が選択できるようになっていますが、今回は作成されたイベントを処理するため、「By Created Date」を選択します
-
Slackのアプリを追加
追加したGoogle Calendarモジュールの右側をホバーすると「add another module」という文字が表示されるので、選択します。
アプリ選択のポップが表示されるので、その中から「Slack」を探し、選択します。
-
「Make an API Call」を選択
「Create a Message」のモジュールではすぐにメッセージが投稿されてしまい、「n分後に投稿する」という挙動にできないため、Slackの予約投稿のAPIを利用します。
選択できるモジュールの中には予約投稿はないですが、モジュール選択のポップの一番下に任意のSlack APIを実行できるモジュールがあるので、こちらを利用します。
-
POSTするSlack APIの設定
SlackのScheduling messagesのドキュメントを参考に、POST内容等を設定していきます
- Connection
連携するSlackのアカウントを選択します
Integromat Appのbotとして投稿するか、認証したユーザアカウントとして投稿するかを選択します - URL
利用するAPIのパスを入力します
今回は「/chat.scheduleMessage
」のAPIを利用します - Method
/chat.scheduleMessage
のAPIはMethodがPOSTなので、「POST」を入力します - Headers
Content-Type
はデフォルトでapplication/json
が入っているので、そのままにします - Body
表示したい内容と、投稿するSlackのチャンネルIDをJSONで記述します
- フィルターを設定する
過去の日時を/chat.scheduleMessage
のAPIに送るとエラーになるので、Google Calendarから取得したイベントの開始日時が現在時刻+m分を切っている場合は、SlackへのPOSTを行わないようにしたいです。
この場合「イベント開始日時 >= 現在時刻+m分」が条件になるので、フィルターのConditionのところに「1.start
/ Greater than equal to /add_minutes(now; m)
」を設定します。
「1.start
」はGoogle Calendarのイベント情報を参照できる変数、「now
」は、Makeで利用できる関数です。
今回、Slackに投稿されてほしい時間は予定の15分前ですが、タイミングによってAPIエラーになることを防ぐため、余裕を持たせて16分前にしています。
テストする
設定したモジュール単体でテストをしたい場合は、対象のモジュールを右クリックするといくつかメニューが表示されるので、「Run this module only」を選択します。
一連の流れを1回だけ流してテストしたい場合は、画面左下の「Run once」から実行できます。
プロダクト開発カレンダーさんの代理として動いてもらうため、Google Calendarっぽい表示になるよう、Slack APIのリクエストBodyとして下記のようなJSONを設定しました。
{
"channel": "SLACK_CHANNEL_ID",
"text": "",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*プロダクト開発カレンダー(代理)*\nEvent starting in 15 minutes:"
}
}
],
"attachments": [
{
"color": "#f691b3",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*<{{1.htmlLink}}|{{1.summary}}>*\n{{formatDate(1.start; "YYYY年MM月DD日")}} from {{formatDate(1.start; "HH:mm")}} to {{formatDate(1.end; "HH:mm")}}"
}
}
]
}
],
"post_at": {{formatDate(addMinutes(1.start; -15); "X"; "JST")}},
}
それっぽい表示になりました。
フィルター設定したときと同様に、「1.hogehoge
」はGoogle Calendarイベントの変数、formatDate
やaddMinutes
はMakeで利用できる関数です。
post_at
は投稿する日時(未来の日時)をUNIX timeで指定する必要があるので、イベント開始時間 - 15分の日時を変換して指定しています。
block部分はSlackがbuilderを用意してくれているので、画像を入れる場合のjsonなども簡単に作れるようになっています。
スケジュール設定をする
テストして問題なければ、シナリオ編集画面左下の「SCHEDULING」のトグルをONに変更するだけで、15分毎にシナリオが実行されるようになります。
今回はFreeプランで動作させていることもあり、オペレーションのカウントを極力減らすため、平日の特定時間帯で15分毎に実行されるようにしました。
課題
とりあえず投稿できるようにはなりましたが、/chat.scheduleMessage
のAPIへ投げっぱなしになっているので、予定の変更にとても弱いです。
そのため、変更前の予定でSlackに投稿されたり、削除した予定が投稿されることもあります。
また、Makeの実行スケジュールもFreeプランでは最低15分毎(有料プランは1分〜)だったり、設定したフィルターによる制限があったりと、時間による制約がいくつかあるので急な予定も対応できないことがあります。
MakeにはData storeがあるので、APIを投げた後、レスポンスをゴニョゴニョしてData storeに保存するようにし、カレンダーの予定更新をトリガーにして、予定が変更されていたらスケジュールし直す、ということもできるかもしれませんが…その分オペレーションのカウントを消費するので、様子見中です。
あくまでも代理という位置付けなので、緩く運用しつつ、SlackのGoogle Calendarアプリが任意のチャンネルに流せるようになるか、Google Calendar for Team Eventsに変わる何かが現れるのを期待しておこうと思います。
「みんなの想いを集め、社会を良くするお金の流れをつくる」READYFORのエンジニアブログです。技術情報を中心に様々なテーマで発信していきます。 ( Zenn: zenn.dev/p/readyfor_blog / Hatena: tech.readyfor.jp/ )
Discussion