JIRAを使った社内向けの通知機能の構築

こんにちは。ちょびえです。

今日はPHPの記事を、と思ったんですがたまには趣向を変えてカスタマーサポート(CS)チームやQAチームとの連携周りの話しでも書いてみようかな、と思います。

弊社ではカスタマーサポートチーム、QAチーム、開発者が協力して行うオペレーションに関してはAtlassian社のJIRAというプロジェクト管理システムを利用しています。JIRAはプラグインによる柔軟な拡張や、JIRA Query Language(JQL)をつかったデータの選択も行えるのでとても便利なツールで、日々作成されるチケットはJIRAを使ってトラッキング、集計が行えるようになっております。

どのようにJIRAを使って複数チームと連携しているか、特に通知周りの部分について開発者視点で簡単に説明してみます。

チーム間連携ツールとしてのJIRA

一般的なWebサービスやゲームなどを自社で提供・運営していく場合、CS・QAチームとプロダクトとの連携は切っても切れない関係になります。
開発中の品質保証検証プロセスではQAチームとの連携は欠かせませんし、サービス運用中に発生するお客様とのコミュニケーションはCSチームと開発者が連携して問題解決を行っています。

jira_conbinaitions

JIRAではIssue Typeに応じて適切なワークフローがカスタマイズできるので、弊社ではCS・QAチームとプロダクトが連携する際のワークフローを決めて運用しています(ワークフローというのはJIRAにおいてはチケットの状態遷移をまとめたもの、だと考えてください。)

さて、こういったBTSツールを導入するとなると開発者の皆さんであれば、通知の仕組みが気になりますよね。更新されたかどうか自分で巡回したり、メールチェックしたり、、、、となると面倒なのでIRC等の普段使っている開発系のツールで確認ができるととても楽です。

また、当然利用者の中にはJIRAやBTSの操作があまり得意でない方もいますので、通知が的確な場所に行え、かつ素早く通知できるとチーム間連携のオーバーヘッドが抑えられることが期待出来ます。(BTSの使い方を詳しく説明するよりこの通知みて!って言ったほうが導入は楽ですよね)

チケットの更新状況を知る必要がある人に的確に通知できる、ということは多数のプロジェクトを運用するにあたって非常に重要です。

JIRAを使った通知方法の構築

JIRA本体の機能としてチケット更新時にメールで通知する仕組みがありますので当初はその機能を利用しようとしたのですが、メール通知機能は内部で一定間隔でキュー処理を行っている関係上即時の通知が行えない、という制約が有りました(ほんのちょっとのラグですがQAプロセス中などではこういう挙動が気になっちゃいますよね)

では、その他の通知手段として何が有るか、といいますとJIRA5から追加されたWebhook機能を使って通知システムを組み上げる、ことも可能です。
しかし、Webhook機能ではカスタムイベントの処理が行えない、という制限があり、私達のカスタムイベントを駆使したワークフローではイベントの通知が意図したとおりに行えませんでした。

さて、どうしたものか、、と

・・・・

冒頭にも記載したとおりJIRAは「プラグインで自由にカスタマイズが出来ます」。

と、いうことは自分たちでプラグインを書けば問題解決出来そうですね!ということで私達はJIRAに通知用のPluginを自分たちで作成して、追加する方法を選びました。

今回は記事の都合上プラグインの開発方法に関しては書きませんが、ご興味の有る方はAtlassian Developersを参考にしてみてください。

設計方針について

JIRAのプラグインAPIを使えばJIRAに自由なデータを持たせることも可能です。伝統的なJIRAプラグインであれば、プロジェクトごとに配送先やルールのデータを保存して・・・とプラグイン単体ですべて行えるように作るかと思うのですが、今回の場合使う人(設定を行う人)が限られていますし、今後継続して利用していく際にデータスキーマのマイグレーション等のオペレーションは行いたくなかったので、プラグインの設計方針としてはシンプルにイベントが発行されたら指定されたエンドポイントにHTTPで通知する、という設計方針で進む事にしました。

jira_events

このような構成であればJIRA側のAPIの構造が変わったとしてもそこまで改修が大変ではないですし、メンテナンスを引き継ぐ場合の難易度も下がります。
受け側は一般的なWeb開発で使われるライブラリを使っておけばメンテ出来る人も多くなるので後々を考えても楽です。

まぁ、そんな建前はおいといて、機能をJIRA側のイベント通知と受信側アプリケーションでの配送先制御に分割することで問題発生時の切り分けが簡単になりますし、なにより受信側アプリケーション側への機能追加が楽ってのがあります。

余談ですが、社内向けの通知関連の仕組みを作っていると「このタイミングでは受けたくない」とか「このイベントは通知して欲しい」と色々な要望がきたりするのでこれをまともに実装しようと思うと複雑トリッキーな実装になってしまいます。
JIRA側で複雑なデータセットを持たせることもありだったのですが、運用中に一括変更などを行ったりするのが面倒になってしまうので今回はこんな仕組みを選びました。

あとは最近楽になりましたがプロジェクト数多くなると個別設定とかつらすぎる、という問題もあります。

実は、一番最初の実装ではKestrelとPHPを使ってQueue処理をしていましたが、そんな構成だと他の人に引き継ぐのが面倒なのでHTTPでシンプルに受けるだけに変更しました。

イベント受信サーバーでの配送先の制御

通知の仕組みは仕事の合間にちょろっと書いたものを基本としていてどの環境でもデプロイしやすいようにRailsで作成しています。
通知先の決定は動的に変更できるようにgem therubyracerを使ってJavaScriptで配送先の決定がプログラマブルに出来るようになっています。

一時期はセレクトボックスなどの組み合わせで配送先が制御出来るようにしようかと思ったんですが、Workflowによってイベントなどが変わってきたりするのでHTMLで書くのは非常に面倒です。いっそJavaScriptでかけば楽だろ、ということで関数定義をして通知先が動的に選択出来るようにしました。

配送イベントを処理するJavaScript側のgetRouteByEventという通知先のアドレスを返す関数になっていて、シンプルなルールであれば下記のようなものになります。

jira_receive

payloadに様々なJIRAの情報が入っているので特定のキーワードが入ったものだけ、などのような処理も簡単に行なえます。
尚、配送ルール定義をしない場合はデフォルトの配送ルールが適用されるようになっているので一括での配送ルール更新などもお手軽です。

あとがき

JIRAやConfluence共に自分たちで使いやすいように片手間でカスタマイズできるのがとっても魅力ですね。
プラグインが導入しづらい場合はJIRAにREST APIがありますのでそれを使ってごにょごにょすると通知とか集計とか幸せになれるかもしれません。

JIRAを使って運用されている皆さんも是非Pluginにチャレンジして日々の運用を楽にするのがオススメです。