フィヨルドブートキャンプではチャットを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を作ります。

Image from Gyazo

ターゲットにはHTTPを指定してリクエストを飛ばしたりもできますが、Pub/Subも指定できます。

Pub/Subはややこしいかと思ってたんですが単に名前決めて作るだけでした。

Cloud FunctionsではPub/Subで作ったイベントをSubscriptionしてそのタイミングで実行できます。

コード

Image from Gyazo

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を使うのも何にも苦労せずでした。

Image from Gyazo

Cloud Functionsは高度な用途もありますが、こういうふうに週1回しか動かないクソちょっとしたプログラムを動かすにも安くていいなと思います。

Comments


Option