簡単な Hubot スクリプトをゼロからつくろう

これは [Hubot Advent Calendar 2014][hubot-adventar-2014] の 6 日目の記事です。

また、今回は @bouzuya の Hubot 連載の第 5 回です。[目次は、第 1 回の記事にある][hubot-adventar-2014-bouzuya-index]ので、そちらをどうぞ。

昨日、 5 日目は [Hubot で docomo 「雑談対話」API を使う — “敬称”を Hubot コマンドに][hubot-adventar-2014-5] でした。流れに乗ってます (?) ね、いいですね。ちなみに Hubot はキャラ付けはとても大切な要素だと思っています。 Hubot をキャラ付けするためにもメッセージ (口調) やパターンの工夫は重要ですね。自然な会話になりませんしね。

前回は [Hubot スクリプトの追加][hubot-adventar-2014-4] について紹介しました。ここまでで Hubot スクリプトを書き換えて、任意のメッセージをやりとりできるようになっているかと思います。

ただ、前回は、いそぎあしになってしまったので、今回は改めてゼロから Hubot スクリプトをつくっていきましょう。

ちなみに今回は `hubot-oden` という「おでん」を返す Hubot スクリプトをつくってみましょう。

# Yeoman ジェネレーターで Hubot スクリプトを生成する

現時点で公式に推奨されているであろう Yeoman ジェネレーターをつかった方法を紹介します。

まずは Yeoman と Hubot のためのジェネレーター (gerator-hubot) をインストールします。これは [第 2 回][hubot-adventar-2014-2] で紹介したものと同じです。

```bash
# 権限が足りない場合は sudo を付けます。
$ npm install -g yo generator-hubot

$ npm list -g generator-hubot yo   
/usr/local/lib
├── generator-hubot@0.1.4 
└── yo@1.3.3 
```

次に Hubot スクリプトを生成します。

```bash
$ pwd
/home/bouzuya

$ mkdir hubot-oden
$ cd hubot-oden

$ yo hubot:script

...

```

あとは質問に適当に答えるだけ。

![yo-hubot-script.png](https://qiita-image-store.s3.amazonaws.com/0/3486/7be9d5c2-0238-3485-05bd-27132907f9bd.png)

これで Hubot スクリプトのひながたが生成されました。

# 生成された Hubot スクリプト

生成された Hubot スクリプトのひながたを見ていきましょう。

生成された Hubot スクリプトは Gruntfile.js が用意されており、テストコードのひながたも用意されています (`generator-hubot@0.1.4` では `coffee-script` への依存関係が足りない (おそらくバグ) ため、テストは動きませんが……) 。テストコードについては、また次回以降で見ていきましょう。

前回と同じように本体だけを編集してみましょう。

# Hubot スクリプト本体の作成

上記のコマンドで生成した場合、`src/oden.coffee` に以下のようなファイルが生成されています。

```coffeescript:src/oden.coffee
# Description
#   A Hubot script that returns an oden
#
# Configuration:
#   LIST_OF_ENV_VARS_TO_SET
#
# Commands:
#   hubot hello - <what the respond trigger does>
#   orly - <what the hear trigger does>
#
# Notes:
#   <optional notes required for the script>
#
# Author:
#   bouzuya <m@bouzuya.net>

module.exports = (robot) ->
  robot.respond /hello/, (msg) ->
    msg.reply "hello!"

  robot.hear /orly/, ->
    msg.send "yarly"
```

これを以下のように書き換えます。

```
# Description
#   A Hubot script that returns an oden
#
# Configuration:
#   None
#
# Commands:
#   hubot おでん - returns an oden
#
# Author:
#   bouzuya <m@bouzuya.net>

module.exports = (robot) ->
  robot.respond /おでん/, (msg) ->
    msg.send '─□○△'
```

さっそく動作を確認します。

```bash
$ PATH=./node_modules/hubot/node_modules/.bin:$PATH $(npm bin)/hubot -a shell -n hubot -r src
hubot> hubot おでん
hubot> ─□○△
```

動きそうです。

すこしだけ解説します。

`PATH` は `$(npm bin)/hubot` が `npm install -g coffee-script` されている前提になっているため、これを設定しないと以下のようにエラーになります。

```bash
$ $(npm bin)/hubot -a shell -n hubot -r src
/usr/bin/env: coffee: No such file or directory
```

`$(npm bin)` は `npm` の機能で `hubot` コマンドなどの実行パスが置かれるディレクトリになります。おそらく `./node_modules/.bin` になります。(`echo $(npm bin)` すればわかります)

`a` オプションは第 2 回でも書いたとおりアダプター名、ここでは `shell` アダプターですね。

`n` オプションは第 2 回で書いたとおり BOT 名、ここでは `hubot` ですね。

`r` オプションはスクリプトの読み込みパスです。Hubot スクリプトのあるディレクトリを指定します。

解説おわり。

# Hubot スクリプトの git リポジトリの公開

あとは前回同様に GitHub などに Hubot スクリプトの git リポジトリを push すれば完了です。

```
$ pwd
/home/bouzuya/hubot-oden

$ git init
$ git add -A
$ git commit -m 'initial commit'

$ # hub コマンドで GitHub にリポジトリをつくっています。なければ Web ブラウザでつくってください。
$ hub create -d 'A Hubot script that returns an oden'

$ git push origin master
```

慣れた手順でご自由に、という感じですね。

# Hubot へ、作成したスクリプトの追加

前回、第 4 回で説明したので割愛！

# まとめ

これで Hubot スクリプトをゼロからつくれるようになりました。

といっても昨日と違う部分はせいぜい最初の `yo hubot:script` くらいだと思います。そんなに難しくないと思います。

きっと、もっといろいろなことがしたいと思うので、次回は Hubot に用意されている機能を使ってみましょう。

# 最後に

えっと、今日 Hubot 2.10.0 が出ました。次回からバージョン変えましょうかね。ハイ。

[getting-started-with-hubot]: https://github.com/github/hubot/tree/v2.9.3/docs#getting-started-with-hubot
[bouzuya/hubot-hello-world]: https://github.com/bouzuya/hubot-hello-world/
[github/hubot]: https://github.com/github/hubot/
[hubot.github.com]: https://hubot.github.com/
[hubot-adventar-2014]: http://www.adventar.org/calendars/384
[hubot-adventar-2014-1]: http://qiita.com/bouzuya/items/c7d0ad80c357aab6b696
[hubot-adventar-2014-2]: http://qiita.com/bouzuya/items/11c0c6da2b3ad54b827f
[hubot-adventar-2014-3]: http://qiita.com/bouzuya/items/2a200c9e8a45e2478bc2
[hubot-adventar-2014-4]: http://qiita.com/bouzuya/items/4c0206d72ff22ade9339
[hubot-adventar-2014-5]: http://pasero.net/~mako/blog/s/685
[ops-for-everyone]: https://speakerdeck.com/johndbritton/ops-for-everyone
[hubot-adventar-2014-bouzuya-index]: http://qiita.com/bouzuya/items/c7d0ad80c357aab6b696