Hubotで自分へのGithubのPullRequest一覧(Reviewerに入っているやつ)をSlackに流す

# 参考
Hubot のインストールと Hello World - Qiita
https://qiita.com/suppy193/items/27ffbe932877a1d7e8ee
SlackのBot(hubot)を作ってみる - Qiita
https://qiita.com/mochidamochiko/items/29c2d77715d8a1ff062a
Hubotにお願いしてPull Requestの一覧を表示 - Qiita
https://qiita.com/ysk_1031/items/7015a9a30888cff0d8f9
Hubotをインストール、hipchatと連携し、foreverでデーモン化(CentOS6.4) - Qiita
https://qiita.com/kon_yu/items/cdc452bcd2bb89f85de1
GitHub API v3 | GitHub Developer Guide
https://developer.github.com/v3/

# 本題

## 成果物の概要
cronで定刻 or hubotに直接声をかけると自分がreviewerに入っているPR一覧を取得できます。

## 注意
reviewerに関するAPIは確定じゃないので修正が入る可能性があるので下記hubotが急に動かなくなる可能性があります。
あとreviewer情報はPR情報とは別のAPIを叩かないと取得できません。

## 環境
さくらのクラウド(たぶん)
Ubuntu 16.04.1 LTS (cat /etc/lsb-release でわかる)
node v9.0.0

```
$ npm version
{ npm: '5.5.1',
  ares: '1.13.0',
  cldr: '31.0.1',
  http_parser: '2.7.0',
  icu: '59.1',
  modules: '59',
  nghttp2: '1.25.0',
  node: '9.0.0',
  openssl: '1.0.2l',
  tz: '2017b',
  unicode: '9.0',
  uv: '1.15.0',
  v8: '6.2.414.32-node.8',
  zlib: '1.2.11' }
```

```
$ npm list -g hubot coffee-script
├── coffee-script@1.12.7 
└──┬ hubot@2.19.0 
   └── coffee-script@1.6.3 
```

## 準備

### とりあえずhubot立てます。

```
$ mkdir prListBot
$ cd prListBot
$ yo hubot
                     _____________________________  
                    /                             \ 
   //\              |      Extracting input for    |
  ////\    _____    |   self-replication process   |
 //////\  /_____\   \                             / 
 ======= |[^_/\_]|   /----------------------------  
  |   | _|___@@__|__                                
  +===+/  ///     \_\                               
   | |_\ /// HUBOT/\\                             
   |___/\//      /  \\                            
         \      /   +---+                            
          \____/    |   |                            
           | //|    +===+                            
            \//      |xx|                            

? Owner test@test.test
? Bot name test
? Description test
? Bot adapter slack
   create bin/hubot
   create bin/hubot.cmd
   create Procfile
   create README.md
   create external-scripts.json
   create hubot-scripts.json
   create .gitignore
   create package.json
   create scripts/example.coffee
   create .editorconfig
                     _____________________________  
 _____              /                             \ 
 \    \             |   Self-replication process   |
 |    |    _____    |          complete...         |
 |__\\|   /_____\   \     Good luck with that.    / 
   |//+  |[^_/\_]|   /----------------------------  
  |   | _|___@@__|__                                
  +===+/  ///     \_\                               
   | |_\ /// HUBOT/\\                             
   |___/\//      /  \\                            
         \      /   +---+                            
          \____/    |   |                            
           | //|    +===+                            
            \//      |xx|                            

npm WARN deprecated connect@2.30.2: connect 2.x series is deprecated
npm WARN deprecated node-uuid@1.4.8: Use uuid module instead
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN hubot-help@0.2.2 requires a peer of coffee-script@^1.12.6 but none is installed. You must install peer dependencies yourself.

+ hubot-google-translate@0.2.1
+ hubot-pugme@0.1.1
+ hubot-scripts@2.17.2
+ hubot-heroku-keepalive@1.0.3
+ hubot-redis-brain@0.0.4
+ hubot-help@0.2.2
+ hubot@2.19.0
+ hubot-slack@4.4.0
+ hubot-shipit@0.2.1
+ hubot-rules@0.1.2
+ hubot-maps@0.0.3
+ hubot-diagnostics@0.0.2
+ hubot-google-images@0.2.7
added 231 packages in 9.466s
```
なんかwarning出たけどスルーで。

### slack連携の設定

slack側の設定画面でhubotを追加してAPI Tokenを発行します。

<img width="1086" alt="スクリーンショット 2017-11-07 15.15.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/70276/c48529a1-5996-6ec7-9d9d-c3b95b55b066.png">
<img width="1111" alt="スクリーンショット 2017-11-07 15.16.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/70276/043137a5-9e00-60b3-a298-a596fb0a0f0b.png">
<img width="1139" alt="スクリーンショット 2017-11-07 15.16.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/70276/428498fa-1ba8-16fa-488b-857e5eadb383.png">

そして発行したAPI Tokenをhubotのbin/hubotに記述します
※環境変数としてサーバーで定義しちゃってもいいんですが、それだと複数hubot入れられないので、ちょくで書いておきます。これは好みです。

```sh:bin/hubot
#!/bin/sh

set -e

npm install
export PATH="node_modules/.bin:node_modules/hubot/node_modules/.bin:$PATH"

HUBOT_SLACK_TOKEN="xoxb-***************************************" \
exec node_modules/.bin/hubot --name "test" "$@"
```
※最後のバックスラッシュ大事！あと、`HUBOT_SLACK_TOKEN=`の後に空行とかいれないでください。

この状態でhubotのRootに移動して`/bin/hubot --adapter slack`を叩きます。

```
$ bin/hubot --adapter slack
up to date in 1.475s
[Tue Nov 07 2017 15:29:31 GMT+0900 (JST)] INFO Logged in as testmaru of andfactory
[Tue Nov 07 2017 15:29:32 GMT+0900 (JST)] INFO Slack client now connected
[Tue Nov 07 2017 15:29:32 GMT+0900 (JST)] WARNING Loading scripts from hubot-scripts.json is deprecated and will be removed in 3.0 (https://github.com/github/hubot-scripts/issues/1113) in favor of packages for each script.

Your hubot-scripts.json is empty, so you just need to remove it.
[Tue Nov 07 2017 15:29:32 GMT+0900 (JST)] ERROR hubot-heroku-keepalive included, but missing HUBOT_HEROKU_KEEPALIVE_URL. `heroku config:set HUBOT_HEROKU_KEEPALIVE_URL=$(heroku apps:info -s | grep web.url | cut -d= -f2)`
[Tue Nov 07 2017 15:29:32 GMT+0900 (JST)] INFO hubot-redis-brain: Using default redis on localhost:6379
[Tue Nov 07 2017 15:29:32 GMT+0900 (JST)] INFO hubot-redis-brain: Data for hubot brain retrieved from Redis
```

すると上みたいなログが出て途中で止まります。(control + c で抜けれます。抜けるとhubotが止まります)
そのまま。slack側を確認すると、hubotがONになっています。
<img width="1460" alt="スクリーンショット 2017-11-07 15.32.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/70276/cb276a1f-decc-dd95-440a-9042713efcec.png">

ひとまずこれでhubotの準備ができました。

## Github周り

ここからはgithubからデータを引っ張ってくる処理です。

### hubotの必要なライブラリを入れます。

作成したhubotのルートパスで以下のコマンドを実行

```
# 日本の祝日判定(cronで祝日なのに通知がくるとうざいので)
$ npm install japanese-holidays

# githubAPIを使うため
$ npm install githubot

# 定刻で動作させるため
$ npm install cron

# hubotを永続化するため
$ sudo npm install forever -g
```

### script作成

作成したhubotのルートパスで以下のコマンドを実行

```
$ vi scripts/cron_job.coffee 
```

下記のscriptを貼り付けます。
そして、SLACK_USER_NAMEの値を自分のusernameに変更します
また、cronの実行時間を変更したい場合は`job = new CronJob '0 0 15 * * 1-5', () ->`の行を修正してください。

```scripts/cron_job.coffee 
module.exports = (robot) ->

  # 定期処理をするオブジェクトを宣言
  JapaneseHolidays = require('japanese-holidays')
  Github = require("githubot")
  CronJob = require('cron').CronJob

  SLACK_USER_NAME = "domonr"

  # pr って言うとpr一覧を出してくれます
  robot.respond /pr/i, (msg) ->
    _notificationPullRequestList(msg)

  # Crontabの設定方法と基本一緒 *(sec) *(min) *(hour) *(day) *(month) *(day of the week)
  # 以下の設定だと平日の15:00に実行されます
  job = new CronJob '0 0 15 * * 1-5', () ->
    today = new Date();
    holiday = JapaneseHolidays.isHoliday(today);
    if holiday 
      console.log("今日は " + holiday + " です")
    else
      _notificationPullRequestList()
  job.start()

  # 特定のチャンネルへ送信するメソッド(定期実行時に呼ばれる)　
  _notificationPullRequestList = (msg) ->
    Github.get 'https://api.github.com/user', (user) ->
      Github.get 'https://api.github.com/user/repos', (repos) ->
        for repo in repos
          do ->
            _repo = repo
            Github.get "https://api.github.com/repos/#{_repo.full_name}/pulls?state=open", (prs) ->
              for pr in prs
                do ->
                  _pr = pr
                  Github.get "https://api.github.com/repos/#{_repo.full_name}/pulls/#{_pr.number}/requested_reviewers", (reviewers) ->
                    for reviewer in reviewers
                      do ->
                        _reviewer = reviewer
                        if _reviewer.login == user.login
                          robot.messageRoom "@#{SLACK_USER_NAME}", "Repo:#{_repo.full_name}\nTitle:#{_pr.title}\nURL:#{_pr.html_url}"
    return

```

### guthubのToken発行

以下にアクセス
https://github.com/settings/tokens

<img width="1179" alt="スクリーンショット 2017-11-07 15.58.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/70276/4ce5d659-9742-c8de-2095-783c4f97e6ff.png">
<img width="1000" alt="スクリーンショット 2017-11-07 18.16.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/70276/2854c733-bcfe-2b39-f7db-9cc871007898.png">
<img width="1089" alt="スクリーンショット 2017-11-07 16.00.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/70276/aa92e98b-f3ab-3250-d644-953c854faa7f.png">

上記のTokenを使って`bin/hubot`を以下のように修正。
※　Tokenはコピーを忘れるとコピーできなくなるので失敗したら再度生成してください。
HUBOT_GITHUB_TOKENには上記で取得したTokenを入力し、HUBOT_GITHUB_USERには自分のUsernameを記載。

```sh:bin/hubot
#!/bin/sh

set -e

npm install
export PATH="node_modules/.bin:node_modules/hubot/node_modules/.bin:$PATH"

HUBOT_SLACK_TOKEN="xoxb-*************************************" \
HUBOT_GITHUB_TOKEN="**************************************" \
HUBOT_GITHUB_USER="*****" \
exec node_modules/.bin/hubot --name "test" "$@"
```

この状態でhubotのロートに移動して`bin/hubot --adapter slack`を実行し、slackから`pr`とメッセージをhubotに対して投稿して問題なく動けばOKです。

## hubotをデーモン化

`bin/hubot`を以下ように修正して、`bin/hubot`を実行してください。

```sh:bin/hubot
#!/bin/sh

set -e

npm install
export PATH="node_modules/.bin:node_modules/hubot/node_modules/.bin:$PATH"

HUBOT_SLACK_TOKEN="xoxb-*************************************" \
HUBOT_GITHUB_TOKEN="**************************************" \
HUBOT_GITHUB_USER="*****" \
forever start -c coffee node_modules/.bin/hubot --adapter slack
```

実行した際に以下のような出力になります

```
warn:    --minUptime not set. Defaulting to: 1000ms
warn:    --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info:    Forever processing file: node_modules/.bin/hubot
```

止める時は

```
$ forever list
$ forever stop [uidのところの数字,0とか1とか]
```

# おわり

なんかまずいところとか、つまづく箇所があったら教えていただけると助かります。