フィヨルドブートキャンプではチャットをSlackからDiscordに移行しようとしています。
DiscordにはSlackのようなReminder機能がメジャーなBotの中には無いので定期的なミーティングのリマインドを簡単に移行することができません。
有名なreminder-botでは「72時間おきにリマインド」のような単純Interval形式しか対応してません。「毎月1日の9時にリマインド」のようなことができないので困ってました。
ブートキャンプでは現在リマインドすべきものは3つしかなく、SlackのようなReminder Botを僕が作るのも面倒なのでCloud Functionsでやってみました。
流れ
Cloud Scheduler -> Pub/Sub -> Cloud Functions -> Discord
Cloud Schedulerでcronと同じインターフェースで時間を指定できるのでjobを作ります。
ターゲットにはHTTPを指定してリクエストを飛ばしたりもできますが、Pub/Subも指定できます。
Pub/Subはややこしいかと思ってたんですが単に名前決めて作るだけでした。
Cloud FunctionsではPub/Subで作ったイベントをSubscriptionしてそのタイミングで実行できます。
コード
require 'functions_framework'
require 'net/http'
require 'json'
FunctionsFramework.cloud_event 'reminder_sub' do |event|
uri = URI.parse(ENV['WEBHOOK_URL'])
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
params = { "content" => "💬 14:00からふりかえりミーティングが 🔈ミーティング チャンネルで始まります。" }
headers = { "Content-Type" => "application/json" }
http.post(uri.path, params.to_json, headers)
end
Discordの発言はwebhookにPOSTするだけです。Cloud Schedulerからpayloadに何か値を入れてれば上記のeventの中にそれが(base64でエンコードされて)入っているのでその内容を使って処理を分けたりもできます。(実際のコードでは3種類の通知をそれで出し分けてます。)
最初のテンプレにGemfileも含まれていて、gemを使うのも何にも苦労せずでした。
Cloud Functionsは高度な用途もありますが、こういうふうに週1回しか動かないクソちょっとしたプログラムを動かすにも安くていいなと思います。