GitHubで自動更新のカンバン作ってみたい Webhook受信編

# はじめに
GitHubでProjectがリリースされた頃にカンバンに使えるかもと[Project APIを使ってみる記事](http://qiita.com/KanaSakaguchi/items/fbd244af006dd746ef7e)を書いたもののしばらく手を出していなかった@KanaSakaguchiです。
進捗を示すラベルを張ったプルリクをProjectのカードにして、ラベルに合わせて自動で更新されるカンバン作ってみたいと思います。

# この記事でやること
まずはGitHubのWebhookをGoogle Apps Script(以下GAS)のウェブアプリケーション機能を使って受け取ってみます。
(GASだと別途サーバーを用意する必要はないので便利ですね。)

# GAS側の設定
WebhookからはPOSTでデータを送信されるのでdoPost関数を定義します。どんなデータが送られてくるのかを確認するためにそのJSONを整形してメールするようにてみます。
(あとでGitHubからJSONを送信してもらうように設定します。)

```js:受け取った内容をメールする
function doPost(data) {
  GmailApp.sendEmail('メールアドレス', 'GitHubWebHooksテスト　doPost', JSON.stringify(data, void 0, 2));
}
```

保存したらメニューの`公開>ウェブアプリケーションとして導入...`よりウェブアプリケーション化します。
<img width="392" alt="ウェブアプリケーションとして導入.png" src="https://qiita-image-store.s3.amazonaws.com/0/76523/1cb76800-4d76-be8f-acf2-41ba6367eb02.png">

<img width="487" alt="ウェブアプリケーションとして導入2.png" src="https://qiita-image-store.s3.amazonaws.com/0/76523/e271d152-f833-bad6-37b7-85a01ea7d40e.png">
必ずアプリケーションにアクセスできるユーザーは[全員(匿名ユーザーを含む)]にしてください。
そうしないとGitHubがアプリケーションにアクセスできないのでWebhookを受信できません。

導入を押すとURLが払い出されるのでコピーしておいてください。
<img width="468" alt="ウェブアプリケーションとして導入3.png" src="https://qiita-image-store.s3.amazonaws.com/0/76523/3a1d1811-88d3-93e1-d106-d42235b469af.png">

## ちなみに
GASではプロジェクトのバージョンを作成することは更新にタグ付けするようなイメージです。
タグを消したりバージョンを変更したりすることはできますが、エディタのコードは更新されません。
URLはバージョンにかかわらずプロジェクトごとにユニークです。

# GitHub側の設定
Webhookを設定したいリポジトリのSettingsにあるWebhooksを開きます。
<img width="1009" alt="Webhooks.png" src="https://qiita-image-store.s3.amazonaws.com/0/76523/d94697c0-ad66-b455-4335-1c9ad78c1017.png">
右上にある[Add webhook]ボタンからWebhookを追加できます。
*この時ログインパスワードを求められます。

`Payload URL`に先ほどコピーしたアプリケーションのURLを貼ります。
<img width="721" alt="Webhooks2.png" src="https://qiita-image-store.s3.amazonaws.com/0/76523/b839642d-d4ec-639f-b37f-2a234ac9a490.png">
JSONで受け取りたいので、`Content Type`は`application/json`を選択します。
![ContentType.png](https://qiita-image-store.s3.amazonaws.com/0/76523/aae04fbb-3bbb-5c31-a02f-24f1bb4fd095.png)
特定のイベントのみでいいので`Which events ～`は`Let me select ～`を選択します。
<img width="385" alt="Webhooks3.png" src="https://qiita-image-store.s3.amazonaws.com/0/76523/d30c07e5-6aa1-2676-b04e-d7ad273e2025.png">
そして、今回はラベルの付け外し検知をしたいので`Pull request`にチェックをつけます。
<img width="316" alt="Pull request.png" src="https://qiita-image-store.s3.amazonaws.com/0/76523/4ef9dfeb-3fe2-02e9-a5e8-6d0a98bc1733.png">
もともと`Push`にもチェックが付いていますが、必要ないので外します。
最後に`[Add webhook]`を押して完了です。
<img width="135" alt="webhooks4.png" src="https://qiita-image-store.s3.amazonaws.com/0/76523/43007190-06a5-6618-71bd-47dd05e04690.png">

するとこんな感じのメールが送られていると思います。
ざっくり書くと「〇〇さんが××というリポジトリに対してこういう設定のWebhookを作りました。」という報告です。

```text:初回Webhookの冒頭
{
  "parameter": {},
  "contextPath": "",
  "contentLength": 6591,
  "queryString": null,
  "parameters": {},
  "postData": {
    "type": "application/json",
    "length": 6591,
    "contents": "{\"zen\":\"Half measures are as bad as nothing at all.\",\"hook_id\":WebhookID,\"hook\":{\"type\":\"Repository\",\"id\":リポジトリID,\"name\":\"web\",\"active\":true,\"events\":[\"push\"],\"config\":{\"content_type\":\"json\",\"insecure_ssl\":\"0\",\"url\":\
```


## doPostに渡されるデータの構造
GitHubのWebhookに限らず、doPostでJSONデータを受け取った時のデータは次のような構造になっています。

```json:doPostに渡されるデータの構造
{
  "parameter": {},
  "contextPath": "",
  "contentLength": POSTデータのサイズ,
  "queryString": null,
  "parameters": {},
  "postData": {
    "type": "application/json",
    "length": POSTデータのサイズ,
    "contents": "POSTデータがJSON.stringifyされたもの",
    "name": "postData"
  }
}
```

なので`data.postData.contents`をJSON.parse()すればよさそうです。
最初に提示した関数を次のように書き換えてGitHubからのJSONデータだけメールするようにします。

```js:JSONデータだけメールする
function doPost(data) {
  GmailApp.sendEmail('メールアドレス', 'GitHubWebHooksテスト　doPost', JSON.stringify(JSON.parse(data.postData.contents), void 0, 2));
}
```

初回のPOSTデータは次のような構造になっています。

```JSON
{
  "zen": "Half measures are as bad as nothing at all.",
  "hook_id": WebhookId,
  "hook": {Webhookの情報},
  "repository": {Webhookを設定したリポジトリの情報},
  "sender": {Webhookを設定した人の情報}
}
```

# ほかにやっておいたほうがいいこと
GitHubのWebhookでは名前や説明などは設定できないのと、GASのURLにはプロジェクト名が含まれていたりするわけではないので、複数設定しているとどれが何のプログラムなのかリスと見ただけではわからなくなる可能性があります。
![Webhooks.png](https://qiita-image-store.s3.amazonaws.com/0/76523/dae223a7-c564-7e87-9b84-17e6612a36dc.png)

なので次のようなdoGet関数も定義してURLにアクセスすれば概要がわかるようにしておくといいです。

```js
function doGet(data) {
  return HtmlService.createHtmlOutput("<html><head></head><body>カンバン自動更新システム</body></html>");
}
```

# 次回予告
次は実際にPull requestイベントは何に反応してどんなPOSTデータを送ってくるのか確認してまとめたいと思います。

[GitHubで自動更新のカンバン作ってみたい Pull requestイベント確認編 - Qiita](http://qiita.com/KanaSakaguchi/items/09a330cd361382b86c70)