GitHubのメンションをSlackに通知する。

GitHubのメンションをSlackに通知するアプリを作りました。
GitHub App, Slack Appを使って実装しました。
誰でも使うことができます。

[サービスページ](https://github-mention.com)で使い方を詳しく説明しています。


この記事では、使い方と仕組みを書いていこうと思います。

## 動作

<img width="500" alt="mention-5x1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51795/ed9496cc-9d04-5645-1088-626fce517ad7.png">

:point_down: :point_down: :point_down:

<img width="500" alt="slack-post-5x1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51795/6cd539d9-714a-5263-df2d-6571d7fc36fd.png">


## 使い方

1. Slack Appをインストールします。
2. GitHub Appをインストールします。
3. SlackでSlash commandを使い、GitHubアカウントを紐付けます。
4. SlackでSlash commandを使い、通知を受け取りたいレポジトリを指定します。

### Slack Appをインストールします。

[Slack Appをインストール](https://ghmention.web.app)します。

### GitHub Appをインストールします。

[GitHub Appをインストール](https://github.com/apps/ghmention)します。

ここからインストールします。
この時、通知を受け取りたいレポジトリを選択して下さい。

### SlackでSlash commandを使い、GitHubアカウントを紐付けます。

Slackで `/ghmention` と入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51795/24c25707-f6b2-a84a-4171-83a30c65136a.png)

### SlackでSlash commandを使い、通知を受け取りたいレポジトリを指定します。

Slackで `/ghmention subscribe owner/repo` と入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51795/1eccd212-a6c1-0203-dd6c-305d2b413ad4.png)


## 登場人物
1. GitHub Apps
2. Slack Apps

### GitHub Apps とは
:warning: 注意 :warning: OAuth Appsとは異なります。
[違いを知る](https://developer.github.com/apps/differences-between-apps/)


GitHub AppsはOrganizationまたはUserアカウントにインストールされます。
レポジトリ単位にインストールされるものではありません。
GitHub Appはアクセスを許可されたレポジトリでしか動作しません。
つまり、アカウント単位でインストールされ、レポジトリ単位で動作します。
インストール時に最低一つのレポジトリへのアクセスを許可する必要があります。

GitHub Appsはレポジトリに対して様々なことが可能になります。
何が可能になるかは、インストールするGitHub Appsが求める権限によります。

例えばGitHub Appsは, Webhooksを利用してGitHubのイベントを受け取ることができます。
Webhooksには様々な[イベント](https://developer.github.com/webhooks/)が用意されています。


その中の一つに、`issue_comment-created` イベントがあります。
このイベントはイシュー（もしくはプルリクエスト）のコメントが作成された時に発火されます。
Webhooksを通じて、GitHub Appsはイシューコメントが作成されたことをリアルタイムで知ることができます。

### Slack Apps とは

Slackのワークスペースにインストールされるもの。

Slack Apps はワークスペースに対して様々なことができるようになります。

代表的な例は、Slack Appsがボットのようにメッセージを送信することです。

他には、Slash commandがあります。
Slash commandはSlackアプリで使える便利なオペレーションです。
(Slack アプリで `/remind` と入力してみてください。)
Slack Appsは独自のSlash commandを提供できます。

## 仕組み

GitHubでのメンションをSlackに通知する仕組みを説明します。

必要なプロセスは3つです。

1. GitHubのユーザーとSlackのユーザーを紐付ける
2. Slackユーザーは、メンションを通知してほしいGitHubのレポジトリを登録する
3. GitHubでメンションされる

### 1 GitHubのユーザーとSlackのユーザーを紐付ける

#### なぜこれが必要か？
GitHubでどの名前がメンションされた時に、あなたに通知を送ればいいかわからないからです。
Slackに通知を送るにはSlackのユーザーIDが必要です。
あなたのSlackのユーザーIDとあなたのGitHubのユーザーIDを、
われわれのサービス上で紐付ける必要があります。

#### フロー
![ghmlog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51795/759ac83e-a84a-0dac-78e4-09554d24d52e.png)

あなたはSlash commandを使ってGitHubアカウントを紐付ける必要があります。
Slash commandを使うと、あなたのSlackユーザーIDをわれわれは知ることができます。
Slash commandから帰ってきた、GitHubのOAuth URLを開きます。
もしあなたがGitHubへのアクセスを承認すれば、
われわれはあなたのGitHubのユーザーIDを知ることができます。

### 2 Slackユーザーは、メンションを通知してほしいGitHubのレポジトリを登録する

#### なぜこれが必要か？

どのGitHubレポジトリの通知を、どのSlackチャンネルへ通知すればいいかわからないからです。
あなたがリード権限のある全てのレポジトリの通知を、Slackのダイレクトメッセージに通知することも可能でしたが、
われわれはそれはあまり役に立たないと判断しました。
あなたは必要なレポジトリの通知を、必要なチャンネルのみに通知できるようコントロールすることができます。

#### フロー
![ghsub2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51795/49c98fbf-0698-25e7-d626-6b38bf44ec98.png)

あなたはSlash commandを使って、通知してほしいGitHubのレポジトリを登録する必要があります。
Slash commandを使ったSlackチャンネルにそのレポジトリの通知が来るようになります。
指定したレポジトリに対して、
1で紐付けたあなたのGitHubアカウントはリード権限を持っている必要があります。


### 3 GitHubでメンションされる

#### フロー
![ghm-post.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51795/8f3b16f8-a70d-5933-b07b-ae6028d788da.png)


GitHubのWebhooksにより、イシューコメントなどのメッセージが作成されたら
われわれのサーバーに通知が来ます。
メッセージからメンションを抽出します。
メッセージが作成されたレポジトリのコラボレーター一覧をわれわれは取得します。
コラボレーターの名前にない、メンションを除外します。
レポジトリとメンションされたGitHubのユーザーIDで、Slackユーザーの登録を確認します。
確認されたSlackユーザーに通知を送ります。