HubotをHerokuでSlackに繋げるまで

この記事では、ゼロから Hubot を Heroku にデプロイして Slack と連携します。
[BotKitをHerokuでSlackに繋げるまで](http://qiita.com/chibi929/items/c410553b868dac602b61) こっちでは BotKit を扱いました。

# Node.js の準備と設定

Hubot を動かすには Node.js が必要になります。
各種モジュールを取得するために npm を使います。

## nodenv のインストールと設定

https://github.com/nodenv/nodenv

```bash
// nodenv のクローン
$ git clone https://github.com/nodenv/nodenv.git ~/.nodenv
$ git clone https://github.com/nodenv/node-build.git ~/.nodenv/plugins/node-build

// 各種設定
$ echo 'export NODENV_ROOT=~/.nodenv' >> ~/.bashrc
$ echo 'export PATH=$NODENV_ROOT/bin:$PATH' >> ~/.bashrc
$ echo 'export "eval "$(nodenv init -)"' >> ~/.bashrc

// 反映
$ source ~/.bashrc

// インストール確認
$ nodenv --version
nodenv 1.1.0-3-g27f0d7b

$ nodenv versions
Warning: no Node detected on the system
```

## node のインストール

```bash
$ nodenv install 6.9.5
$ nodenv global 6.9.5

$ nodenv versions
* 6.9.5 (set by /home/chibi/.nodenv/version)

$ node --version
v6.9.5

$ npm --version
3.10.10
```

# Hubot の準備と設定

Hubot の準備には npm でモジュールをインストールして、
Yoeman を使って雛形を作成します。

## 各種モジュールのインストール

```bash
$npm install -g yo generator-hubot
```

## Hubot の雛形作成

```bash
$ mkdir dragonbotz
$ cd dragonbotz
$ yo hubot
yo: コマンドが見つかりません

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

? Owner chibi929
? Bot name dragonbotz
? Description A simple helpful robot for your Company
? 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|                            

```

## 動作確認

```bash
$ ./bin/hubot 
dragonbotz> [Fri Mar 17 2017 23:42:01 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.
[Fri Mar 17 2017 23:42:01 GMT+0900 (JST)] ERROR hubot-heroku-alive included, but missing HUBOT_HEROKU_KEEPALIVE_URL. `heroku config:set HUBOT_HEROKU_KEEPALIVE_URL=$(heroku apps:info -s  | grep web-url | cut -d= -f2)`
[Fri Mar 17 2017 23:42:01 GMT+0900 (JST)] INFO hubot-redis-brain: Using default redis on localhost:6379
[Fri Mar 17 2017 23:42:01 GMT+0900 (JST)] INFO hubot-redis-brain: Data for hubot brain retrieved from Redis

dragonbotz> dragonbotz ping
dragonbotz> PONG
```

# Slack との連携

Hubot と Slack を連携するには `Configure Apps` の `Hubot` を追加してトークンを取得します。
取得したトークンを使って、上記で準備した Hubot と連携させます。

## Slack 側の準備

https://my.slack.com/services/new/hubot
ここから `Hubot` を登録できます。

### Bot の名前を決める

![20170318000444.png](https://qiita-image-store.s3.amazonaws.com/0/53393/f152ecf7-a211-b11e-70c6-f2d4fdf45a17.png)

### Bot の設定画面でアイコンなどを設定する

![20170318000503.png](https://qiita-image-store.s3.amazonaws.com/0/53393/5a9d19a7-9b58-709e-c842-e77cd687d089.png)

最後に保存をする。
赤枠で囲ったトークンは後で使いますのでコピーしておきます。

## Hubot 側の準備

先ほどのトークンを設定しつつ、Hubotを起動します。

```bash
$ export HUBOT_SLACK_TOKEN=xoxb-*********************************
$ ./bin/hubot --adapter slack
[Sat Mar 18 2017 00:17:42 GMT+0900 (JST)] INFO Logged in as dragonbotz of z-enjoy-it
[Sat Mar 18 2017 00:17:43 GMT+0900 (JST)] INFO Slack client now connected
[Sat Mar 18 2017 00:17:43 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.
[Sat Mar 18 2017 00:17:44 GMT+0900 (JST)] ERROR hubot-heroku-alive included, but missing HUBOT_HEROKU_KEEPALIVE_URL. `heroku config:set HUBOT_HEROKU_KEEPALIVE_URL=$(heroku apps:info -s  | grep web-url | cut -d= -f2)`
[Sat Mar 18 2017 00:17:44 GMT+0900 (JST)] INFO hubot-redis-brain: Using default redis on localhost:6379
[Sat Mar 18 2017 00:17:44 GMT+0900 (JST)] INFO hubot-redis-brain: Data for hubot brain retrieved from Redis
```

## 動作確認

![20170318002118.png](https://qiita-image-store.s3.amazonaws.com/0/53393/185319a2-5251-96d4-4cfa-d40f015825e0.png)

# Heroku との連携

Heroku のアカウント登録は終わっているものとします。
上記のローカル上で試した `Slack との連携` を Heroku 上で行います。

## Heroku のプロジェクトの作成

### 新しい Heroku App を作成する

![20170318003350.png](https://qiita-image-store.s3.amazonaws.com/0/53393/b95c8015-6717-1804-f2c7-043e5e68fb4f.png)

### アプリ名を決める

- アプリ名は空っぽの場合は適当に決まるようです
- そのまま Create App ボタンを押下します

![20170318003415.png](https://qiita-image-store.s3.amazonaws.com/0/53393/28183b8d-450e-a977-3fbf-a998372dfd50.png)

## "heroku CLI" の導入

https://devcenter.heroku.com/articles/heroku-cli

```bash
$ sudo apt-get install software-properties-common # debian only
$ sudo add-apt-repository "deb https://cli-assets.heroku.com/branches/stable/apt ./"
$ curl -L https://cli-assets.heroku.com/apt/release.key | sudo apt-key add -
$ sudo apt-get update
$ sudo apt-get install heroku

$ heroku --version
heroku-cli/5.7.0-713be60 (linux-amd64) go1.7.5
```

## "heroku CLI" でログイン

```bash
$ heroku login
Enter your Heroku credentials:
Email: hoge@example.com
Password: **************
Two-factor code: ******
Logged in as hoge@example.com
```

## Heroku へデプロイ

```bash
$ cd dragonbotz
$ git init
$ heroku git:remote -a {HEROKU_APP_NAME}

$ git add .
$ git commit -m "First commit."
$ git push heroku master
```

## Heroku への設定

```bash
$ heroku config:add HUBOT_SLACK_TOKEN=xoxb-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
$ heroku config
HUBOT_SLACK_TOKEN: xoxb-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

さっき使ったトークンを heroku の環境変数に登録します。

## 動作確認

- ローカル上の Hubot は落ちていることを確認します
- Heroku 上の Hubot を動かします

![20170318005955.png](https://qiita-image-store.s3.amazonaws.com/0/53393/e322669a-3ee9-59c4-e323-ea0d995a11dd.png)

# Bot のスクリプトを書く

`scripts/` の下に `example.coffee` というものがありますが、
ここに `dragonbotz.coffee` を作成します。

## dragonbotz.coffee

```coffeescript:dragonbotz.coffee
module.exports = (robot) ->    
  robot.hear /タッカラプトポッポルンガプピリットパロ/, (msg) ->
    msg.send ":polunga:"
```

## Heroku へデプロイ

```bash
git add scripts/dragonbotz.coffee
git commit -m "Add dragonbotz"
git push heroku master
```

## 動作確認

![20170318012558.png](https://qiita-image-store.s3.amazonaws.com/0/53393/690dc3a5-b31a-1dfb-2eaa-288395b30f11.png)

※適当に拾ってきた画像を使わせて頂きました。

# 作業中のトラブルシュート
## `yo` でエラーが発生した件

```bash
$ yo doctor
? ==========================================================================
We're constantly looking for ways to make yo better! 
May we anonymously report usage statistics to improve the tool over time? 
More info: https://github.com/yeoman/insight & http://yeoman.io
========================================================================== (Y/n) 

/home/chibi/.nodenv/versions/6.9.5/lib/node_modules/yo/node_modules/rx-lite/rx.lite.js:75
    throw e;
    ^

SyntaxError: Invalid regular expression: /.{1,0}/: numbers out of order in {} quantifier
    at RegExp (native)
    at breakLines (/home/chibi/.nodenv/versions/6.9.5/lib/node_modules/yo/node_modules/insight/node_modules/inquirer/lib/utils/screen-manager.js:108:15)
    at ScreenManager.render (/home/chibi/.nodenv/versions/6.9.5/lib/node_modules/yo/node_modules/insight/node_modules/inquirer/lib/utils/screen-manager.js:55:22)
    at Prompt.render (/home/chibi/.nodenv/versions/6.9.5/lib/node_modules/yo/node_modules/insight/node_modules/inquirer/lib/prompts/confirm.js:85:15)
    at Prompt._run (/home/chibi/.nodenv/versions/6.9.5/lib/node_modules/yo/node_modules/insight/node_modules/inquirer/lib/prompts/confirm.js:65:8)
    at Prompt.run (/home/chibi/.nodenv/versions/6.9.5/lib/node_modules/yo/node_modules/insight/node_modules/inquirer/lib/prompts/base.js:57:8)
    at Object.<anonymous> (/home/chibi/.nodenv/versions/6.9.5/lib/node_modules/yo/node_modules/insight/node_modules/inquirer/lib/ui/prompt.js:84:12)
    at module.exports (/home/chibi/.nodenv/versions/6.9.5/lib/node_modules/yo/node_modules/run-async/index.js:15:21)
    at AnonymousObservable.__subscribe (/home/chibi/.nodenv/versions/6.9.5/lib/node_modules/yo/node_modules/insight/node_modules/inquirer/lib/utils/utils.js:16:7)
    at AnonymousObservable.tryCatcher (/home/chibi/.nodenv/versions/6.9.5/lib/node_modules/yo/node_modules/rx-lite/rx.lite.js:63:31)
```

とりあえずターミナルを再起動だったか、OS再起動したら直った。
npm でインストールしたモジュール関連がちゃんとロードされていなかったのだろうか。