[2017年版]HubotをSlackで利用 ローカル環境構築、デバッグ、およびHerokuへのデプロイ方法

# はじめに
hubotが登場し早数年、随分とセットアップ方法が楽になった。
またnodeのバージョンも上がりローカルのデバッグの方法も随分楽になったのでその方法を改めて共有しておこう

## 予備知識

* slackをすでに利用していてある程度の操作方法がわかっていること
* Herokuのアカウントを持っていること

# ローカル環境構築

## 実行環境

nodeとnpmがインストールされていること、開発時のそれぞれのバージョンは以下

* 実行OS: OSX Sierra
* node: v7.4.0
* npm: 3.10.10


### hubot generator のインストール

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

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

```sh
> mkdir myhubot
> cd myhubot

# slack連携しつつ、botの名前をHubotにしてdescriptioやowner設定を纏めてする
# ここでオプションを設定しなくてもインタラクティブに入力を聞いてくれる
> yo hubot --adapter=slack --name="Hubot" --description="hogehoge" --owner="kon_yu<hogehoge@example.com>"
```

※ yo hubotコマンドを実行する際に--nameオプションでbot名をhubotにするとなんだかよくわからないエラーが出るので注意だ


### Hubotの起動と動作確認	

```sh
# hubot起動
bin/hubot

# とりあえずechoコマンドが動くことを確認
Hubot> hubot echo "aaa"
Hubot> "aaa"
```

### Slackとの連携

#### Slackの管理画面から設定
Slackの管理画面の左端にあるメニューから **Configure Apps** を選択し、
Appsの中から **Hubot** を選択する
選択すると表示されるUsernameでHubotのSlack上の表示名を設定する(ここではhubotとする)
**Add Configration** ボタンを押し、Hubotが投稿する適当なChannelを選択する(generalとか)

Setup Instructionsの項目にある環境変数をコピーしておく

画面下方の **Save Integration** ボタンを押してセットアップ完了

#### Slack上でHubotに発言させたいChannelの追加

Slackを起動し、Hubotに発言させたいChannelを開き、メッセージウインドウに先程設定したHubotの名前(hubot)をchannelに招待する

```
/invite @hubot
```

※ SlackのHubotの設定画面においてChannelsの箇所に招待したChannelが追加されていることを確認できる

#### Slackからhubotを呼び出す

Hubotをローカル端末から起動する際にコピーしておいた環境変数(HUBOT_SLACK_TOKEN)を設定し、アダプタ設定をslackにして起動する

```sh
HUBOT_SLACK_TOKEN=xoxb-YOUR-TOKEN-HERE ./bin/hubot --adapter slack
```

参考) https://slackapi.github.io/hubot-slack/#running-hubot


## debug環境を整える

デバッグするためには、bin/nodeで起動するのではなく、coffeeコマンドを利用して起動する必要がある。

coffeeスクリプトの実行コマンドをインストール

```
npm install -g coffee-script
```

ローカルでHubotコマンドを打つ場合
--inspectがポイント

```
coffee --nodejs --inspect node_modules/.bin/hubot
```

Slack上でHubotのコマンド打つ場合

```sh
HUBOT_SLACK_TOKEN=xoxb-YOUR-TOKEN-HERE coffee --nodejs --inspect node_modules/.bin/hubot --adapter slack
```


## オリジナルのコマンドを作成

scriptsディレクトリ以下にあるexample.coffeeをコピーして、sample.coffeeファイルを作る

sample.coffeeに下記のような変更を加え

```
module.exports = (robot) ->
  robot.respond /who are you/i, (msg) ->
   　msg.send "I'm hubot!"
```

デバッグのやり方でslackアダプタを利用した状態(-a slackをつけて)hubotを起動する。

```
> HUBOT_SLACK_TOKEN=xoxb-YOUR-TOKEN-HERE coffee --nodejs --inspect node_modules/.bin/hubot --adapter slack
Debugger listening on port 9229.
Warning: This is an experimental feature and could change at any time.
To start debugging, open the following URL in Chrome:
    chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/c9bc2176-7ce4-4d18-a9eb-de23caa2790d
Hubot> [Wed Jan 25 2017 14:21:51 GMT+0900 (JST)] INFO /Users/kon_yu/development/myhubot/scripts/backlog.coffee is using deprecated documentation syntax
[Wed Jan 25 2017 14:21:51 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.
[Wed Jan 25 2017 14:21:51 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)`
[Wed Jan 25 2017 14:21:51 GMT+0900 (JST)] INFO hubot-redis-brain: Using default redis on localhost:6379
[Wed Jan 25 2017 14:21:51 GMT+0900 (JST)] INFO hubot-redis-brain: Data for hubot brain retrieved from Redis
```

実行した時に表示されるログの中から下記のようにcherome-devetools://から続く文字列を見つけて,　これをchromeブラウザで開く

```
chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/c9bc2176-7ce4-4d18-a9eb-de23caa2790d
```

Chromeブラウザで開くと、ｓcriptのソースコードに　breakpointを置くことができ、変数の中身などを確認しながら開発することができる

![スクリーンショット 2017-01-25 14.26.03.png](https://qiita-image-store.s3.amazonaws.com/0/5390/caa0741a-4cfc-d348-1916-f30b2229c9ed.png)


slack上で下記のようにメッセージを入力すると

```
@hubot who are you
```

hubotがレスポンスを返すことを確認できる

```
I'm hubot
```

### Webhookを利用した外部サービスとの連携をデバッグする方法

#### ngrokをインストールする
Webhookを利用して、外部サービスからローカルマシンにhttpで接続する必要がある。
それを簡単に実現する方法に[ngrok](https://ngrok.com/)がある

事前にhomeｂrewとhomebrew-caskをインストールしておくこと

homebrewをインストール 

```
>　/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

homebrew-caskのインストール

```
> brew install caskroom/cask/brew-cask
```

ngrokをインストールする

```
brew cask install ngrok
```

ngrok起動し、ローカルマシンの8080ポートと接続するように起動する

下記のコマンドで、http://eb96e826.ngrok.io へアクセスするとローカルマシンの８０８０ポートへ接続されるようになる。
http://eb96e826.ngrok.io の「eb96e826」はngrokに自動で決められるサブドメイン。

```
> ngrok http 8080
ngrok by @inconshreveable                                              (Ctrl+C to quit)

Session Status                online
Account                       kon_yu (Plan: Free)
Version                       2.2.4
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://eb96e826.ngrok.io -> localhost:8080
Forwarding                    https://eb96e826.ngrok.io -> localhost:8080

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00
```

http://eb96e826.ngrok.io をwebhookを利用する外部サービスのURLに設定してあげると
外部サービスでWebhookを起動させるとローカルで起動しているhubotにアクセスする。

[上で説明しているデバッグ方法](http://qiita.com/kon_yu/items/57fb169cb871a009393b#%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%8A%E3%83%AB%E3%81%AE%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E4%BD%9C%E6%88%90)でhubotを起動しておくと、chromeでデバッグできる


## Herokuにデプロイする

### Herokuアプリを生成する

```
> heroku create foobar-bot
Creating ⬢ foobar-bot... done
https://foobar-bot.herokuapp.com/ | https://git.heroku.com/foobar-bot.git
```

### herokuにデプロイする

Herokuアプリを作成したときに出力されたhttps://xxx.gitをもとに
gitのプッシュ先にherokuを追加する

```
> git remote add heroku https://git.heroku.com/foobar-bot.git 
```

確認方法、下記のようにherokuというリモートプッシュ先が追加されていること

```
> git remote -v
heroku	https://git.heroku.com/foobar-bot.git (fetch)
heroku	https://git.heroku.com/foobar-bot.git (push)
origin	git@github.com:hogehoge/hubot.git (fetch)
origin	git@github.com:hogehoge/hubot.git (push)
```


```
> git push heroku
```

### 環境変数の設定

Slack用のAPIトークンHUBOT_SLACK_TOKENを設定する

```
> heroku config:set HUBOT_SLACK_TOKEN=hogehogexoxb-12345678-XXXXXXXXXXXXXXX
Setting HUBOT_SLACK_TOKEN and restarting ⬢ foobar-bot... done, v4
HUBOT_SLACK_TOKEN: hogehogexoxb-12345678-XXXXXXXXXXXXXXX
```

## hubot-heroku-keepaliveの設定

Herokuのフリープランの場合、1日に6時間以上起動**しない**ようにする必要がある
hubotを起動しておく時間を働いている時間程度に収めるのがhubot-heroku-keepaliveというデフォルトでついているアドオンを利用する

定期的に作成したherokuアプリのURLにアクセスしてサーバが寝ないようにする

herokuアプリのURLを環境変数に追加する

```
heroku config:set HUBOT_HEROKU_KEEPALIVE_URL=$(heroku apps:info -s | grep web_url | cut -d= -f2)
```

herokuアプリの環境変数にタイムゾーンの設定と起動時間と終了時間の設定をする

```
heroku config:add TZ="Asia/Tokyo"
heroku config:add HUBOT_HEROKU_WAKEUP_TIME=8:00
heroku config:add HUBOT_HEROKU_SLEEP_TIME=24:00
```

サーバがスリープ状態から起こすために朝起動する時間にherokuアプリのURLにアクセスし
スケジューラのアドオンを追加する

```
> heroku addons:create scheduler
```

```
curl ${HUBOT_HEROKU_KEEPALIVE_URL}heroku/keepalive
```

実行時間をUTC23時にする -> 日本時間の朝8時に設定する

![スクリーンショット 2017-01-24 15.47.23.png](https://qiita-image-store.s3.amazonaws.com/0/5390/a3b62de2-9e82-42db-9fff-d44119972a3a.png "スクリーンショット 2017-01-24 15.47.23.png")

## 参考情報
* [hubot リポジトリ](https://github.com/github/hubot)
* [hubot document](https://hubot.github.com/docs/)
* 特に[Getting Started With Hubot](https://hubot.github.com/docs/#getting-started-with-hubot)