Hubot を Twitter の公開タイムラインに住まわせる


３連休中ですがボッチなので、せめてボットと戯れようと Twitter の公開タイムラインを監視＆応答ツイートする Hubot のアダプターを試してみました。

> ちなみに、Hubot のアダプター一覧はここで参照できます。
> ⇒ https://github.com/github/hubot/blob/master/docs/adapters.md

今回の大まかな方針としては、次のとおりです。

- Hubot は **Heroku** で動かします。
	- どれくらい CPU を使うか未検証なので、無料枠に収まるかは分かりませんw
	- ただ今回のもの程度であれば、私の環境では無料枠で動いています。
- ボットは Twitter の **公開タイムライン** を監視します。
	- よって、とりこぼしがあっても仕方なし、とします。
- ボット用の Twitter アカウントを用意します。
	- Twitter へのアプリケーション登録もします。

ボットの作成で必要なものは、Mac、Yeoman の環境、Heroku のアカウントです。これらの環境を用意する手順については先日、似たようなものをこちらに書いたので、宜しければ参考にしてください。
⇒ [Yoeman で Hubot を作成して Heroku へデプロイし Slack と連携する](http://qiita.com/hkusu/items/1dc7db9607ab8cb35150)

# 雛形ボットの作成と動作確認

## ボットの作成 

- 適当な作業用のディレクトリを作成して、ジェネレータを起動。
	- ジェネレータのインストールについては、上記リンクの手順をご覧ください。現在のバージョンは `0.1.4` です。

	```shell:
	$ mkdir hubot_twitter
	$ cd hubot_twitter
	$ yo hubot
	```

- `Bot name` と `Description` を適当に入力し、`Bot adapter` は `twitter` と入力します。
	- `Bot name` は Hubot の起動オプション `-n` で指定するので、ここでは適当でいいです。

	![スクリーンショット_2014-11-23_17_29_52.png](https://qiita-image-store.s3.amazonaws.com/0/35733/564e7b9a-ce09-7ca5-360e-9c28d249b0ea.png "スクリーンショット_2014-11-23_17_29_52.png")


- 次のようにファイルが展開されました。`package.json` はこんな感じ。

	![スクリーンショット_2014-11-23_17_36_13.png](https://qiita-image-store.s3.amazonaws.com/0/35733/6e115c93-a41c-200b-c5e1-e47621eac91e.png "スクリーンショット_2014-11-23_17_36_13.png")

- まずは、この状態で動作するか、ローカルで動作確認します。

	```shell:	
	$ cd hubot_twitter 
	$ ./bin/hubot
	```

- `Hubot>` コンソールで、次のように応答が返ってこればOK。動作確認したら `exit` で抜けます。

	![スクリーンショット 2014-11-23 19.08.35.png](https://qiita-image-store.s3.amazonaws.com/0/35733/6abaf305-aa64-a4ed-110a-6a2485ddceaa.png "スクリーンショット 2014-11-23 19.08.35.png")

## Twitter 側でアプリケーション登録

適当なボット用の Twitter アカウントを用意し、ログイン状態で `https://apps.twitter.com/` にアクセスします。

適当にアプリケーション名や説明、ウェブサイトを記載し、

![スクリーンショット_2014-11-23_18_14_22.png](https://qiita-image-store.s3.amazonaws.com/0/35733/3daa8f20-f4ba-5e74-b171-336292dd537c.png "スクリーンショット_2014-11-23_18_14_22.png")

`Premissions` タブにて、権限を `Read and Write` に変更します。

![スクリーンショット 2014-11-23 18.15.55.png](https://qiita-image-store.s3.amazonaws.com/0/35733/f292b254-b33b-11eb-daa5-9e16ddde93b1.png "スクリーンショット 2014-11-23 18.15.55.png")

`Keys and Access Tokens` タブにて、`Access Token/Secret` を新たに発行します。後の為に控えておくのは次の４つの情報です。
 
- `Consumer Key (API Key)`
- `Consumer Secret (API Secret)`
- `Access Token`
- `Access Token Secret`

![スクリーンショット_2014-11-23_18_17_45.png](https://qiita-image-store.s3.amazonaws.com/0/35733/c949ca46-1e4a-4ac2-ab17-f9fa5e083b46.png "スクリーンショット_2014-11-23_18_17_45.png")

## ローカルで動作確認

次のように Hubot の起動スクリプトを作成し、

```sh:hubot_twitter/local_run.sh
#!/bin/sh

export HUBOT_TWITTER_KEY="控えていた情報"
export HUBOT_TWITTER_SECRET="控えていた情報"
export HUBOT_TWITTER_TOKEN="控えていた情報"
export HUBOT_TWITTER_TOKEN_SECRET="控えていた情報"

bin/hubot -a twitter -n HogeTweetBot
```

※ 上記の例でいうと `HobeTweetBot` が語りかけ対象のボット名になります。

起動スクリプトに実行権限を付与して、実行します。

```shell:
$ cd hubot_twitter
$ chomod +x local_run.sh
$ ./local_run.sh
```

Twitterで、確認してみます。世界中の誰がつぶやいても応答するのですが、今回はボット自らのアカウントでつぶやきます。

![スクリーンショット 2014-11-24 14.41.35.png](https://qiita-image-store.s3.amazonaws.com/0/35733/80c33ff1-1397-0fe8-3a21-b28eba407233.png "スクリーンショット 2014-11-24 14.41.35.png")

## Heroku へのアップロードし動作確認

- 先ほどの `local_run.sh` と同じ立ち上げ方を Heroku 上で出来るよう `Procfile` を修正します。

```:Procfile
web: bin/hubot -a twitter -n HogeTweetBot
```

- Git でコミットします。

	```shell:
	$ cd hubot_twitter
	$ git init
	$ git add .
	$ git commit -m "firs comment"
	```

	> 先ほどの `local_run.sh` には トークン等を記載してしまっているため、ファイル名を `.gitignore` に追記して、コミットされないようにしてください！

- Heroku へプッシュします。

	```shell:
	$ heroku create
	$ git push heroku master
	```

- Heroku が動いているか確認します。

	```shell:	
	$ heroku open
	```

	![スクリーンショット 2014-11-23 19.21.29.png](https://qiita-image-store.s3.amazonaws.com/0/35733/a39d3688-20c9-76b1-60cf-a962f6e89344.png "スクリーンショット 2014-11-23 19.21.29.png")

	エラー出ますが、とりあえずはOK。

- Heroku へ環境変数を追加し、もう一度 `$ heroku open` してみます。

	```shell:
	$ heroku config:add HUBOT_TWITTER_KEY="控えていた情報"
	$ heroku config:add HUBOT_TWITTER_SECRET="控えていた情報"
	$ heroku config:add HUBOT_TWITTER_TOKEN="控えていた情報"
	$ heroku config:add HUBOT_TWITTER_TOKEN_SECRET="控えていた情報"
	```

	次のように表示されればエラーは出てません。

	![スクリーンショット 2014-11-23 19.24.28.png](https://qiita-image-store.s3.amazonaws.com/0/35733/f0aa78fa-b263-8ed8-272e-6ed610ce120b.png "スクリーンショット 2014-11-23 19.24.28.png")

- Twitterで動作確認してみます。

	![スクリーンショット 2014-11-24 14.48.19.png](https://qiita-image-store.s3.amazonaws.com/0/35733/67f60e2b-5421-7a2b-5663-5e6218754b4f.png "スクリーンショット 2014-11-24 14.48.19.png")

# ボットを作成してみる

ここまで出来てたら、あとは適当なボットを作成するのみです。簡単な例で、`あいうえお` に対して「こんにちわ！」、`かきくけこ` に対して「こんばんわ！」を応答するには次のようにします。

```coffeescript:scripts/tweet_sample.coffee
module.exports = (robot) ->

  robot.respond /あいうえお/i, (msg) ->
    msg.send "こんにちわ！"

  robot.respond /かきくけこ/i, (msg) ->
    msg.send "こんばんわ！"
```

上記のファイルをコミット、Heroku へ反映した後、つぶやいてみます。

![スクリーンショット 2014-11-24 14.53.17.png](https://qiita-image-store.s3.amazonaws.com/0/35733/df3cd919-722d-894d-3ab2-c77d7068d398.png "スクリーンショット 2014-11-24 14.53.17.png")

また当然、Hubot の組み込みスクリプト（`external-scripts.json` で組み込んでいるもの）も利用できますので、試しに猫の画像を探してもらいます。

![スクリーンショット 2014-11-24 14.54.44.png](https://qiita-image-store.s3.amazonaws.com/0/35733/b62d2277-6471-0830-5acd-c8773acf900c.png "スクリーンショット 2014-11-24 14.54.44.png")

いろいろ出来そうですね^^

# 補足：今回の Twitter 用アダプターについて

アダプターのソースは `node_modules/hubot-twitter/src/twitter.coffee` です。ソースの中身をみてみると、Twitter の API名で言うと `Streaming API` の `Public streams` の `statuses/filter` で `track(検索キーワード)` を指定して、ボット名を抽出しています。

> Twitter の APIリファレンス(statuses/filter)
> ⇒ https://dev.twitter.com/streaming/reference/post/statuses/filter

Twitter の仕様上、全タイムラインの監視はできず取りこぼしが発生し、またこのアダプターの仕様上、ボットに指示を出す場合はボット名で呼びかける必要があります。（チャットのタイムラインを `robot.hear` でだらっと眺める、ということが出来ない。）

もし、本格的に Twitter ボットのようなものを実現したい場合は、Node.js 用の Twitter ライブラリである [twit](https://github.com/ttezel/twit) を利用したり、上記の Twitter アダプターのソースを参考にしたり、[hubot-scripts](https://github.com/github/hubot-scripts) にある Twitter 系のソースを参考にしたりして、自分で作るのが良いかと思います。

また、ボットの Twitter アカウントと フォロー/フォロワー の関係を作れば、Twitter の `Streaming API` を利用したとしても、より取りこぼしが少ない抽出の仕方ができるかと思いますし、もしくは `Streaming API` を使わず、普通に Twitter クライアントアプリケーションのようなものを作ることも可能かと思います。

> Twitter の APIリファレンス(Streaming API)
> ⇒ https://dev.twitter.com/streaming/overview

# おまけ：Hubot に hubot-scripts を組み込む方法

Hubot の組み込みスクリプト（`external-scripts.json` で組み込んでいるもの）以外にも、「hubot-scripts」とうのも予め用意されていますので、これらも簡単に利用することが出来ます。

> hubot-scripts
> ⇒ https://github.com/github/hubot-scripts

結構な量があるので、何がどういうものか分かりませんね^^;

今回の環境でいうと `node_modules/hubot-scripts/` 配下に各ソースが格納されています。これらを Hubot へ組み込むには `hubot-scripts.json` に利用するものを追記して、Hubot を起動するだけです。

```json:hubot-scripts.json
["twitter.coffee"]
```

※ `.coffee` も書くのに注意。

もし依存するモジュールがあれば（だいたい各ソースの先頭に説明が記載されています）、`package.json` に追記して `$ npm install` してください。

# おわりに

今回のソースは GitHub に置きました。
⇒ https://github.com/hkusu/Hubot_Twitter_sample

Hubot は Heroku に簡単に載せられ(= グローバルにインターネット公開できる)、アクションを定期実行でき、各種サービス連携のアダプターも豊富、HTTPリクエストの受け取り/発行もできるしで、「チャット連携」にかぎらず、何かちょっとしたツールやサービスを作るのにも手軽でいいのかなと思います。