GitHubのprojectsにカードが作成された時にslackに通知する


GCPのCloudFunctionsとGitHubのwebhookを使用して、Slackに通知してみます

## 順番
1. GitHubのrepositoryを作成
2. GCP or firebaseでCloudFunctionsを使用できるようにする
3. Slackアカウントの作成と通知用の部屋の準備
4. 動作確認

※Firebase CloudFuncionsは無料枠だと外部IPからのアクセスを許可できないので従量課金か$25のプランに入るしか無い

## GitHubのrepositoryを作成 && Webhookの設定

GitHubがProjectsの変化を察知してWebhookでこちらが準備したエンドポイントにpayloadを送信するように設定します

まずはRepositoryを作成します 詳しくは書きません

次にwebhookの設定をします

[webhookとは](http://qiita.com/soarflat/items/ed970f6dc59b2ab76169)利用しているサービス(ここではGitHub)が特定のイベント(ここではprojectsの作成)を受け取った時に、登録されているAPI POSTエンドポイントにイベント情報を送信する仕組みのこと

GitHub: 'projectsにカード追加されたで、POSTリクエストしたろ'
CloudFunctions: 'ぎふはぶからpayload送られてきたな、slackに通知してやろ'
Slack: 'にゃーん'

こんな感じです

実際にwebhookの設定をする時は
https://github.com/あなたのGitHubId/作成したリポジトリ/settings/hooks 
の`Add webhook`から設定します

設定ページでやることは
- Payload URLの設定
- Which events would you like to trigger this webhook?項目のLet me select individual eventsを選択し、Project cardの項目のみにチェックを入れて保存

Payload URLは何でもいいですが、後に作成するCloudFunctionsのエンドポイントを入れました


## CloudFunctionsでwebhook用のエンドポイントを作成

何らかのPostで受け取ることの出来るエンドポイントを用意します
`https://あなたのCloudFunctionsのdomain/githubProjectWebHookPOST`
のようなAPIをHTTPトリガーで用意したとします
必要な場合はCloudFunctionsのコード格納用のStorageバケットを作成してください

コードは以下
とりあえず最終的に動くものをあげましたが、最初は200返すだけのものを作ってwebhookから正しくリクエストを受け取れるか確認したほうがいいです

```javascript
const https = require('https');

exports.githubProjectWebHookPOST = function githubProjectWebHookPOST(req, res) {
  if (
    req.body.action === 'created' &&
    req.body.project_card.column_id === カラム指定してるのでカラムID
  ) {
    https.get('https://slack.com/api/chat.postMessage?token=後で作成するSlackToken&channel=%23'+encodeURIComponent('チャンネル名')+'&username=あとで作成するSlackApp名&text='+encodeURIComponent(req.body.project_card.creator.login+'がお告げを追加された。\n')+encodeURIComponent(req.body.project_card.note)+'&as_user=false', (resp) => {
    let data = '';
 
    resp.on('data', (chunk) => {
      data += chunk;
    });
    resp.on('end', () => {
        console.log(JSON.parse(data).explanation);
      });
    }).on("error", (err) => {
      console.log("Error: " + err.message);
    });
    
  }
  res.status(200).send('success');
};

```

実際にPOSTリクエストを送信してリクエストが成功することを確認します ※このまま書いても現段階では動きません
OKならGitHubのrepository内のsetting -> webhookのPayloadURLにCloudFunctionsAPIのURLを入れて保存します

エンドポイントの準備は以上


## Slackアカウントの作成と通知用の部屋とアプリとtokenの準備

Slackアカウントの作成と通知用の部屋は作ってください

次に通知用のAppの作成をします
https://api.slack.com/apps
でCreate New Appを選択します
App Nameに通知アプリケーション名を入れます
通知したい部屋を持つチームを選択してCreate App
作成した後の画像とかは適当に…

次に通知するためのtokenを生成します
https://api.slack.com/custom-integrations/legacy-tokens
このページ内に通知したい部屋を持つチームがいると思うので作成してください

ここで作成したApp名とtokenをCloudFunctionsのSlack通知用のURLに設定します
Projectsカラムの指定がない場合はif文の条件を削除してください、そのリポジトリの全てのProjectsに追加されたカードの通知が来るようになります



## 動作しているか確認

GitHub Projectsに新しいカードを追加してください
通知が来ない場合に確認することは
1. webhookが動作しているか
2. APIでバグが起きていないか
3. slack通知が出来るか

1.はGitHubのリポジトリのwebhook設定ページの下部にログが出てるので成功しているか確認しましょう

2.はCloudFunctionsのログを確認しましょう

3.は送信用のURLだけcurlなどで送信して通知が来るか確認しましょう

以上


## 参照

[GitHub GraphQL API v4 Webhook](https://developer.github.com/webhooks/)
[GitHub REST API v3 Event Types & Payloads ProjectCardEvent](https://developer.github.com/v3/activity/events/types/#projectcardevent)
[SlackのAPIでメッセージ通知を送る(PHP)](http://qiita.com/daigon/items/474064e484dcd7136bae)
[5 Ways to Make HTTP Requests in Node.js](https://www.twilio.com/blog/2017/08/http-requests-in-node-js.html)
[Slack APIのTokenの取得・場所](http://qiita.com/ykhirao/items/0d6b9f4a0cc626884dbb)
[Node.jsでURIエンコードを行う方法](http://qiita.com/kenfdev/items/642d94301314ca81d2ad)