Azure Functionsを使ってGitLabのWebhookをDiscordに通知するようにしたって話

Azure Functionsを使ってGitLabのWebhookをDiscordに通知するようにしたって話

 生存報告を兼ねて。引っ越しました。

背景、もともとの運用

 しあわせの国での開発は、GitLab.comで発生したイベントを、Discordに表示させる運用をしてます。

 誰かがブランチをプッシュしたら、こんな感じのメッセージが流れてきます。

f:id:kokeiro0_00:20170430171732p:plain  アイコンと口調がちょっとイラッとするのが特徴です。

 開発メンバーの中にはgit使ってない人もいます。そういった人にも作業進捗が見えるようにしたい!というのが俺の建前で、 実際は誰かが作業していることを目に見せることで「俺もやらねば」と煽るのが目的で作成。

 Issueの操作などの、ブランチのプッシュ以外も通知されます。最近はあまりIssueはあんまり使ってないけど。

 これまではRaspberry Piにボットを住まわせて、GitLabからの通知を拾わせてました。 が、引っ越し先に光回線が引かれておらず、回線工事することとなりました。 工事待ちの間はSoftBank Airってのが貸出されてインターネットそのものは利用できるんですが、無線機ってこともあって機能制限がキツイ。

SoftBank Air における機能制限のお知らせ | インターネット | ソフトバンク

ご利用いただけない機能
・ポート転送

影響を受ける可能性がある利用形態
・外部向けサーバーとしての利用、外部からのリモートアクセスの一部
・外部からIPアドレスを指定してアクセスを必要とするもの

 Raspberry Piのボットに待ち受けさせるの無理やん!引越し前と同じ運用は難しそう。。。 というわけで、自宅のRaspberry Piを経由せずにGitLabの通知を拾うシステムを作ろうと思い立ちました。

条件設定

 そもそもRaspberry Piを利用してたのは安いから。

 今回は無料で環境を用意することを目標にしました。

要件

 Discord側のWebhook機能は、Discordに対してjsonを投げつけることでチャットにメッセージを出力することが出来るというもの。 当然ながら、Discordへ送信する際は、決められたフォーマットに従う必要があります

 GitLab側のWebhook機能は、設定したプロジェクトにイベントが発生したときに、予め指定しておいたURLにjsonを投げつけるというもの。 この際、GitLabから送信されるjsonの中身はイベントによって決まってて、GitLab上でフォーマットすることは出来ません。

 GitLabからDiscordにそのまま投げられれば楽だったんだけど、Discord側がソレを受け入れてくれないので、何かしらの方法でフォーマットする必要がある。 (ちなみに、GitHubが吐き出すjsonにはDiscordが対応しているため、フォーマットする必要がない。ゲームでの交流ツールとして生まれたはずなんだけど、開発ツールとして利用されるケースが増えてきてるんかな。)

実装

 さてさて、C#でサーバーレスできればなんでも良いんで、今回はAzure Functionsを用いることにしました。  Visual Studio Dev Essentialsを使えば「¥2,550 の Azure クレジットを 1 年間、毎月ご利用いただけます」ってことなので、とりあえず1年は負担0円で使えそうです(ダイマ)。

 構成はこんな感じ。

f:id:kokeiro0_00:20170430172932p:plain  後述しますが、ベストプラクティス通りにはなってません。

 Azure FunctionsでGitLabからのHTTPリクエストをトリガーに、いい具合にフォーマットしてDiscordに流すようにしました。

 コードとかはGitHubに公開しました(not GitLab.com!!!)。デプロイしてWebhook用のURLを書き換えれば動きます。どうぞ。

github.com

 GitLabからの通知の全てを適切にフォーマットはしていません! ドキュメント見ながら自分たちがよく使う機能のみをゴリゴリ実装しただけなので。

 アイコンとか設定すると、こんな感じの通知が流れてくるようになります。

f:id:kokeiro0_00:20170430173517p:plain わーい!

感想

 コード自体はRaspberryPiに乗っけてたやつの資産の大部分を使えたので、1日位でサクッと実装できました。 便利ですね。

 ローカルの環境整えるのが面倒だったのでブラウザ上のコードエディタで編集しました。 インテリセンスが貧弱なのとブレークポイント貼れないのは思ってた以上に辛かった。。。

 もうすぐVisualStudio2017向けのツールが発表されるかも、とのことだったので楽しみに待機。

Functions Tooling for Visual Studio 2017 · Issue #201 · Azure/Azure-Functions

今後の展望

 今回作成したプロジェクトはベストプラクティスの通りになってません

Azure Functions のベスト プラクティス | Microsoft Docs

可能な限り、大きな関数は、連携して高速な応答を返す、より小さな関数セットにリファクタリングしてください。 たとえば、webhook または HTTP トリガー関数では、一定の時間内に確認応答が必要になる場合があります。 この HTTP トリガー ペイロードは、キュー トリガー関数によって処理されるキューに渡すことができます。 このアプローチを使用すると、実際の作業を遅らせて、即座に応答を返すことができます。 webhook は、通常、即座に応答を必要とします。

 気が向いたら練習も兼ねてベストプラクティスに沿った形に修正します。気が向いたら。

 自分でパーサーを用意するのも面倒なんで、この辺のOSS使うと楽できるかもしれませんね。NGitLabの方はさっぱり見とらんけど。

参考URL