これは Hubot Advent Calendar 2014 の 7 日目の記事です。
また、今回は @bouzuya の Hubot 連載の第 6 回です。目次は、第 1 回の記事にあるので、そちらをどうぞ。
前回は 簡単な Hubot スクリプトをゼロからつくろう ということで、generator-hubot という Yeoman ジェネレーターで Hubot スクリプトのひながたを用意し、そこから Hubot スクリプトをつくりました。
今回は Hubot が提供している機能をもうすこし知るために、Hubot スクリプト界隈では定番の「おみくじ」系のスクリプトをつくりたいと思います。
また、今回から Hubot 2.10.0 にバージョンアップされています。
スクリプトの完成イメージ
まず、今回つくろうとしている Hubot スクリプトのイメージを共有しましょう。
今回は「おみくじ」系スクリプトということで、選択肢を挙げて「選んで!」とお願いすると、ランダムにひとつを選んで返してくれる Hubot スクリプト hubot-choice をつくりましょう。
実行例はこんな感じです。
bouzuya> だいこん、たまご、こんにゃく、はんぺん、ちくわから選んで!
hubot> bouzuya: だいこんで!
さっそくつくる
とりあえず Hubot スクリプトのひながたを生成します。このへん分からないのであれば、過去の連載記事を参照してください。
$ mkdir hubot-choice
$ cd hubot-choice
$ yo hubot:script
次に src/choice.coffee
を編集します。
# Description
# A Hubot script for choosing at random
#
# Configuration:
# None
#
# Commands:
# <item1>、<item2>、<item3>から選んで - choose at random
#
# Author:
# bouzuya <m@bouzuya.net>
module.exports = (robot) ->
robot.hear /(.+)から選んで/, (msg) ->
items = msg.match[1].split(/[ ・、\s]+/)
item = msg.random items
msg.reply "#{item}で!"
こうだ!
実行してみましょう。
$ HUBOT_SHELL_USER_NAME='bouzuya' PATH="./node_modules/hubot/node_modules/.bin:$PATH" $(npm bin)/hubot -a shell -n hubot -r src
hubot> だいこん、たまご、こんにゃく、はんぺん、ちくわから選んで!
bouzuya: だいこんで!
長いですね。あと Hubot 2.10.0 からの機能をしれっと使っています。こちらの名前が 'bouzuya' になるようにしています。
今回の新しい要素
上記のスクリプトの新しい要素は、次の 4 つくらいでしょうか。
robot.hear
msg.match
msg.random
msg.reply
CoffeeScript 的に新しい "#{...}"
なんてのもありますけど、そのあたりは http://coffeescript.org/ に任せるということで割愛します。 (Hubot さわりはじめたひとで CoffeeScript つらいという意見はよく聞きますが…… JavaScript でも書けるのでお好きにどうぞ)
適当に解説つけます。
robot.hear
これは listener を登録するメソッドです。
robot.respond(pattern, cb)
は指定した pattern が @hubot pattern
などで動くように書き換えられるのに対して、robot.hear(pattern, cb)
は指定した pattern がそのまま使われます。
当然ですが、誤爆(関係ないメッセージに誤ってマッチ)しやすいので注意が必要です。
msg.match
これは正規表現のマッチした結果を取り出しています。
今回の msg.match[1]
は最初の例で言うと、正規表現が /(.+)から選んで/
で、入力が 'だいこん、たまご、こんにゃく、はんぺん、ちくわから選んで!'
なんで、'だいこん、たまご、こんにゃく、はんぺん、ちくわ'
になります。
msg.random
これは与えられた Array からランダムにひとつを返します。
今回は最初の例で言うと [だいこん', 'たまご', 'こんにゃく', 'はんぺん', 'ちくわ']
からひとつ ('だいこん'
) を選んでくれています。
msg.reply
これはアダプター依存ですが、メッセージを送信した個人に対して返信するメッセージをチャットに送信します。
補足
紛らわしいのですが、msg
という変数は robot.Response
を new
したものに相当します。ソースコード追うとわかります。ちなみに、ぼくの個人的な Hubot スクリプトでは res
という変数名にしています。変数名なので、好きなようにすればいいと思います。
まとめ
今回は Hubot が提供している機能をもうすこし知ろうということで、いくつか標準の機能を紹介しました。
今回はソースコードを見てもらえるように GitHub のリンクを貼りました。Hubot のソースコードは大した量ではありません。ぼくのゴミみたいな解説を読む時間で、本体のソースコードを読むほうが速いし確実です。ぜひ、ソースコードを読んでください。
Response#http
などで HTTP リクエストなどを紹介したいところですが、正直、使い勝手がたいへん悪いので、大多数の人が request
などの他のメジャーな npm パッケージを使っているのが現実だと思います。外部の npm パッケージの利用については後日紹介します。
ちなみに今回のサンプルは bouzuya/hubot-choice にあります。うまく動かない、などがあれば参考にどうぞ。
最後に
Hubot のソースコードを読んだら、いかに Hubot がひどいかが分かり、クローンをつくりたい衝動にかられると思います。
最後に、のネタを考えてたら投稿が遅れて 2014-12-08 になってしまった。