初心者がHubot × Herokuで、twitter上に投稿された癒やし画像をslackに流してみた

# はじめに
卒業後現在も活動を続けている、大学のサークルにslackを年末（勝手に）導入しました。twitterと連携して、自分のツイートや特定の単語を含むツイートをslack上に流せる事は噂で聞いていたので、ちょうどいい機会だし試しにやってみました。

せっかくqiita書くなら、為になる（？）ネタでチャレンジしようと思い「電車遅延に関連したツイートをslackに流す」をやろうと思ったのですが、既出ネタだったので「癒やし画像をslackに流す」で挑みます（笑

ちなみに自分はHubotもHerokuも使ったことない超初心者です〜。

## 参考になったサイト
[初心者がHubotを使ってHeroku上で動くSlack bot作ってみた（導入編）](http://qiita.com/susuwatarin/items/019e0e701754161f7c4c)
[Heroku+HubotでTwitter検索結果をSlackに流す](http://blog.spacemarket.com/code/twitter-watch-hubot-for-slack-on-heroku/)

# 導入
Homebrew経由で、`npm`をインストールします。

```
$ brew install npm
```

npm経由で、`Yeoman`と`hubot-generator`をインストールします。
globalじゃなくてもいいんですけど、パスの指定が面倒なので、今回はglobalにします。

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

適当なディレクトリを作り、hubotを作成します。

```
$ mkdir hubot_for_slack
$ cd hubot_for_slack
$ yo hubot
```

<img width="800" alt="1.png" src="https://qiita-image-store.s3.amazonaws.com/0/95091/445c0a5a-6cdf-86c4-85d6-23eb7ce3adc8.png">


こんな感じでHUBOT君との対話が始まるので、適宜答えてください。
Bot adapterと聞かれる所は`slack`と入力してください。

# ローカル上でhubotの動作確認をする
まずは、ローカル上でhubotを起動し、検索したい単語を設定しツイートをslackに流してみましょう。

## hubotの起動
早速ですが、起動します。

```
$ ./bin/hubot
```

<img width="800" alt="2.png" src="https://qiita-image-store.s3.amazonaws.com/0/95091/0d231661-8541-a53a-aaf1-513aa0f8b16f.png">


おやおや、なんかエラーが出ました。
まず、`hubot-scripts.json`が空だから削除しろって言われているので削除します。
次に、`hubot-heroku-alive included, but missing HUBOT_HEROKU_KEEPALIVE_URL`というエラーがありますが、`hubot-heroku-alive`の設定が出来ていなくて怒られていますね。

詳しくは後述するので、一旦`external-scripts.json`をエディタで開いて、`hubot-heroku-alive`を消しましょう。

<img width="300" alt="3.png" src="https://qiita-image-store.s3.amazonaws.com/0/95091/14028ffc-9266-5e71-6d4a-995736ae85c8.png">


もういちど、hubotを起動します。

```
$ ./bin/hubot
```

エラーは起きなくなりました。
今回作ったhubotの名前は`hubot-for-slack`なので、`hubot-for-slack ping`と打ちましょう。
`PONG`が帰ってきたら動作確認完了なので、exitで抜けます。

<img width="800" alt="4.png" src="https://qiita-image-store.s3.amazonaws.com/0/95091/857db31c-2d96-8d54-fedb-fd5de70aeebb.png">


## Twitterとの連携準備
さて、指定した単語を含むツイートをHubotが取ってくれる、便利なライブラリが既に存在しているので、それをインストールします。

```
$ npm install --save hubot-twitter-search
```
次に、`eternal-scripts.json`の配列内に`"hubot-twitter-search"`を追加します。

さて、このライブラリを利用するために、設定しなければいけない環境変数が6つ存在します。

```
HUBOT_TWITTER_CONSUMER_KEY ... twitterのConsumer Key
HUBOT_TWITTER_CONSUMER_SECRET ... twitterのConsumer Secret
HUBOT_TWITTER_ACCESS_TOKEN_KEY ... twitterのAccess Token
HUBOT_TWITTER_ACCESS_TOKEN_SECRET ... twitterのAccess Token Secret
HUBOT_TWITTER_MENTION_QUERY ... 検索するキーワード
HUBOT_TWITTER_MENTION_ROOM ... slackに流すチャンネル名
```
上記4つは、twitterから取得しなければなりません。
ということで、まずはTwitter Developersにアクセスします。[こちら](https://dev.twitter.com/)

<img width="800" alt="4.png" src="https://qiita-image-store.s3.amazonaws.com/0/95091/410704ca-7f2f-61c0-1285-49083a654522.png">

ページ下部の`Manage my apps`をクリック。
遷移先のページの右上に`Create New App`があるのでクリックし、適当に入力してください。

「Keys and Access Tokens」タブの、`Consumer Key`、`Consumer Secret`、`Access Token`、`Access Token Secret`に表示されている文字列を控えておきます。

<img width="800" src="https://qiita-image-store.s3.amazonaws.com/0/95091/21cecfc0-2be0-fdb9-9ee5-5d4d809570f2.png">


## Slackとの連携準備
さて、slackのために設定する環境変数があります。

```
HUBOT_SLACK_TOKEN ... slackのAPI Token
```
slackとのトークンを取得しましょう。
まずは、連携したいチャンネル名を右クリックし、Add an app or integrationをクリック。

<img width="300" alt="8.png" src="https://qiita-image-store.s3.amazonaws.com/0/95091/02b15147-ee62-7717-f2a2-162608b88f9b.png">

Hubotと入力します。

<img width="800" alt="9.png" src="https://qiita-image-store.s3.amazonaws.com/0/95091/22696ed9-bca7-4c62-a558-107a75b4a1d4.png">

hubotに名前をつけてあげて作成。

API Tokenに記載された文字列を控えておきます。
<img width="800" src="https://qiita-image-store.s3.amazonaws.com/0/95091/e11e7cd9-cbdc-4a68-d909-b76eccbeb277.png">


最後に、そのチャンネルに`Hubot`をinviteしておきます。

<img width="600" alt="12.png" src="https://qiita-image-store.s3.amazonaws.com/0/95091/adc21a5c-1cc7-3a8f-de41-f477f3359ac9.png">

## slackに流してみる

これで必要な情報は取得したので、環境変数にセットして、ローカル上でHubotを起動します。
動作確認をする上で、`Redis`が必要なので、インストールします。

```
homebrew install redis
```
インストール完了後、起動します。

```
$ redis-server
```

先程控えた情報を環境変数にセットします。が、ターミナルから1つ1つ環境変数をセットするのも面倒くさいし、ターミナルを閉じるたびにセットし直さないといけないので、今回は簡単なシェルスクリプトを実装してみました。

```
#!/bin/sh

export HUBOT_TWITTER_CONSUMER_KEY='twitter-consumer-key'
export HUBOT_TWITTER_CONSUMER_SECRET='twitter-consumer-secret'
export HUBOT_TWITTER_ACCESS_TOKEN_KEY='twitter-access-token'
export HUBOT_TWITTER_ACCESS_TOKEN_SECRET='twitter-access-token-secret'
export HUBOT_TWITTER_MENTION_QUERY='検索したい単語'
export HUBOT_TWITTER_MENTION_ROOM='slack-channel-name'
export HUBOT_SLACK_TOKEN='slack-token'

bin/hubot -a slack
```

これを`run.sh`とします。
ちなみに、githubにcommitしたい場合は、gitignoreされている`.conf`等を作り、そこにアクセストークン等を記載し、シェル内で環境変数を読み込むようにしましょう。

今回は`HUBOT_TWITTER_MENTION_QUERY`に`動物`と入力して、動作確認をします。
では、シェルを実行

```
$ sh run.sh
```


<img width="800" alt="13.png" src="https://qiita-image-store.s3.amazonaws.com/0/95091/29b1ad92-32d3-2f95-9616-20c85be996d4.png">

問題は起きて無さそうですね。ではslackを確認。

<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/95091/0b4c6004-10e1-7517-add2-5e5c95e73d58.png">

slackに動物ツイートが流れております。動作は問題ないみたいですね。
では、hubotやredisを一旦止めます。

最後に、先程削除した`"hubot-heroku-keepalive"`を`external-scripts`に書き加えましょう！

# heroku上で動作確認
現状だと、ローカルPCがシェルを実行している時のみしか動かないので、herokuで運用してみましょう。
アカウント登録していない方はアカウント登録しましょう。

## heroku toolbeltをインストール
Heroku用コマンドラインツール等が詰まったアプリケーションです。インストールは[こちら](https://toolbelt.heroku.com/)

## アカウント認証
アカウント認証をします。

```
$ heroku login
```

<img width="485" alt="15.png" src="https://qiita-image-store.s3.amazonaws.com/0/95091/f5162784-9ea1-8a80-5816-d3db8319d196.png">


## herokuにデプロイ
herokuは、Gitのリポジトリをそのままデプロイ出来るので、作ったものをローカルリポジトリにcommitしましょう。

```
$ git init
$ git add .
$ git commit -m "twitter bot for slack"
```

herokuに新しいアプリケーションを作成。

```
$ heroku create <application name>
```

<img width="800" alt="16.png" src="https://qiita-image-store.s3.amazonaws.com/0/95091/bbc1dea0-e287-6a29-0861-76d78c5f436f.png">

## redisをherokuに追加
先程登場しましたが、Hubotは`Redis`を使うので、addon追加します。

```
$ heroku addons:apps redistogo
```

（注）クレジットカードの情報を入力しないと、下記のメッセージが表示されaddon出来ないです。

```
Please verify your account to install this add-on plan
```


## 環境変数をherokuにセットする
先程シェルで実行した環境変数のセットを、herokuでも行います。先程のローカルでの動作確認と違い、PCをシャットダウンした後にセットし直す必要とかないので、シェルは書かずに直接ターミナルからセットします。

```
$ heroku config:set HUBOT_TWITTER_CONSUMER_KEY='twitter-consumer-key'
$ heroku config:set HUBOT_TWITTER_CONSUMER_SECRET='twitter-consumer-secret'
$ heroku config:set HUBOT_TWITTER_ACCESS_TOKEN_KEY='twitter-access-token'
$ heroku config:set HUBOT_TWITTER_ACCESS_TOKEN_SECRET='twitter-access-token-secret'
$ heroku config:set HUBOT_TWITTER_MENTION_QUERY='検索したい単語'
$ heroku config:set HUBOT_TWITTER_MENTION_ROOM='slack-channel-name'
$ heroku config:set HUBOT_SLACK_TOKEN='slack-token'
```
これに加えて更に2点設定する必要があります。`redistogo`と`hubot-heroku-keepalive`です。

先程addonした`Redis To Go`の具体的なURLを環境変数としてセットする必要があり、Herokuのアプリダッシュボードから参照することができます。
herokuコマンドが使えるのなら、下記コマンドで参照せずにセット出来ます。初見の自分はちょっと探すのに手間取ってしまったので、おとなしくコマンドから行きましょう。

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

## 無料でheroku運用するための設定
herokuでは、様々な課金プランと無料プランがありますが、無料プランには、一定期間アクセスがないと自動的に落とすという仕様があります。
なので、`hubot-heroku-keepalive`を利用し、定期的に必ず自分自身にアクセスすることで24時間アプリケーションを落とさずに済むという手段があります。

しかし2016年6月に、無料プランは「24時間の内6時間は落とさないといけない」制約が新たに加わりました。
結果、24時間無料で稼働する事は出来無さそうなので、Hubotの稼働開始時間・稼働終了時間を環境変数として設定します。

```
$ heroku config:set HUBOT_HEROKU_WAKEUP_TIME=HH:MM
$ heroku config:set HUBOT_HEROKU_SLEEP_TIME=HH:MM
$ heroku config:set TZ='Asia/Tokyo'
```
（注：開始時間・終了時間を6時間以上開けるように設定してください）

Heroku Schedulerをaddonします。

```
$ heroku addons:create scheduler:standard
```

以下のコマンドを叩くと、ブラウザ上で設定が出来ます。

```
$ heroku addons:open scheduler
```

開始時間を入力します。世界協定時刻（UTC）で設定する必要があるので`-9時間`してください

<img width="340" alt="18.png" src="https://qiita-image-store.s3.amazonaws.com/0/95091/0cb8d869-35aa-a2da-cd50-6f739df35b2d.png">

コマンドを入力する箇所があるので、以下を入力します。

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

## HUBOT_TWITTER_MENTION_QUERYの設定
twitterは、言語・ネガティブポジティブ・場所・日時等で絞ることができる高度な検索機能を備えてます。
今回は画像ツイートだけを流したいので、`動物 filter:images`で試しに動かしてみた所、`filter:images`が検索オプションではなく文字列と認識されてしまい、失敗。。。
hubot-twitter-searchは、検索オプションを利用できなかったので断念。

今回は安直に「萌え画像」でセットしました。

## herokuにデプロイ

```
$ git push heroku master
```

## slackにて確認

では該当チャンネルで動作されているかどうか確認します。

<img width="340" alt="18.png" src="https://qiita-image-store.s3.amazonaws.com/0/95091/11b4337a-2686-3baa-f389-a426748f85d3.png">

た、確かに動作は問題ないですね、たまに画像とは関係ないツイートも流れてしまいますが・・・

# まとめ
思ったよりも癒やされませんでしたが、コード書かずに設定するだけで実現できたのはとても楽でした。
（無料プランでは現実的ではないですが）地震情報をslackに流したり、テレビ番組やアニメ実況をハッシュタグから拾ってきてslackに流すことも出来るので、いろいろやれるなーと思いました。twitterで見れば済m（cry

今回できなかった高度な検索機能オプションは、Hubotが拾えるようなライブラリを今度作ってみようかなと思います。

ちなみに今回作ってみたHubotは、便利なシェルと共にgithub上に上げました。[こちら](https://github.com/genshun9/last_will)