これは Hubot Advent Calendar 2014 の 13 日目、のつもりで書いた 16 日目の記事です。真の 13 日目は mako09 さんが 『hubot-slack アダプタ v2 から v3 へ』を書いてくださっているようです。
また、今回は @bouzuya の Hubot 連載の第 10 回です。目次は、第 1 回の記事にあるので、そちらをどうぞ。
ちなみに昨日は @hiconyan さんの 研究室でHubot使ってる話 でした。 @hiconyan さんとこの Huboco ちゃんはアイコンなど、きちんとしていてうらやましいですね。Hubot を定期的なジョブ実行に使う事例はよく見ますね。
前回まで、そして今回は
さて、前回は Hubot スクリプトの読み込み処理を読んでみよう ということで、Hubot の起動処理を追いかけて、Hubot スクリプトがどんな風に読み込まれているのかを確認し、Node.js のプログラムとして単純に require(script)(robot)
されているだけだということが分かりました。
今回は、Hubot スクリプトをつくる際に欠かせないテクニックとして設定を読み込む方法を紹介します。
(ちなみに前日の @hiconyan さんの記事の中で当然のように使われていますが、気にしない方向で)
hubot-hello-world ふたたび
今回は設定を読み込む、ということで、Hubot スクリプトでは一般的な環境変数から値を読み込む処理をつくってみます。
元にする Hubot スクリプトは 第4回 でつくった bouzuya/hubot-hello-world で、それと類似の、設定可能な Hubot スクリプトをつくろうと思います。
で、さっそく
yo hubot:script
でつくってみました。hubot-hello-xxx
という適当な名前で。
# Description
# A Hubot script that responds XXX
#
# Configuration:
# HUBOT_HELLO_XXX_MESSAGE
# HUBOT_HELLO_XXX_MESSAGES
#
# Commands:
# hubot hello - respond XXX
# hubot hello! - respond XXX
#
# Author:
# bouzuya <m@bouzuya.net>
config =
message: process.env.HUBOT_HELLO_XXX_MESSAGE
messages: JSON.parse(process.env.HUBOT_HELLO_XXX_MESSAGES ? '[]')
module.exports = (robot) ->
unless config.message?
robot.logger.error 'process.env.HUBOT_HELLO_XXX_MESSAGE is not defined'
return
robot.respond /hello$/, (msg) ->
msg.send "#{config.message}, #{msg.envelope.user.name}!"
robot.respond /hello!$/, (msg) ->
message = msg.random config.messages
msg.send message if message?
動かしてみましょう
解説の前に動かしてみましょう。
設定(環境変数)なし
$ HUBOT_SHELL_USER_NAME='bouzuya' PATH="./node_modules/hubot/node_modules/.bin:$PATH" $(npm bin)/hubot -a shell -n hubot -r src
[Sat Dec 13 2014 23:52:40 GMT+0900 (JST)] ERROR process.env.HUBOT_HELLO_XXX_MESSAGE is not defined
hubot>
設定(環境変数)あり
$ HUBOT_HELLO_XXX_MESSAGES='["あびゃー","チョリーッス"]' HUBOT_HELLO_XXX_MESSAGE='うるせえ' HUBOT_SHELL_USER_NAME='bouzuya' PATH="./node_modules/hubot/node_modules/.bin:$PATH" $(npm bin)/hubot -a shell -n hubot -r src
hubot> hubot hello
うるせえ, bouzuya!
hubot> hubot hello!
あびゃー
hubot>
解説
簡単な解説をつけます。
process.env.XXX
環境変数からの読み込みは Node.js ユーザーからすればおなじみの process.env.XXX
です。
Hubot は Heroku にデプロイできるようにデザインされているため、設定情報の読み込みは基本的に環境変数です。もちろん、外部から取得するなどの工夫は自由にできますが、一般的には環境変数の値が使われます。
HUBOT_HELLO_XXX_MESSAGE
設定にはプリフィックスを
Hubot の設定に利用する環境変数の名前付けにはルールがあります。
それは先頭に HUBOT_<スクリプト名>_
をつけるというものです。
ただ、あくまでも慣習であって、ここから外れるとどうなるというものではありません。合わせておくのが無難だとは思います。
設定はコメントに記載
また、読み込む環境変数の一覧はコメントの Configuration:
欄に書いておきます。ここに書くときには HUBOT_
を削る派閥もあるようですが、個人的には、何を設定するのか分かりづらいので HUBOT_
つきで書くことにしています。
config.XXX
今回のスクリプトがそうですが、設定項目を config
などにまとめておく人も居ます。
ぼくは普段ほとんどしないのですが、試してみました。まあ、わかりやすいかもしれません。
JSON.parse ...
複数の値を設定値として受け取る方法はいろいろあります。一般的なのはカンマ区切りだと思いますが、個人的にはエスケープなどを検討するのも面倒なので、 JSON を受け取るようにしています。
CoffeeScript であれば、 undefined
や null
の場合のデフォルト値を process.env.XXX ? 'default'
のように提供しておくと良いかもしれません。
unless config.message
設定がなかったときの挙動です。
robot.logger.error ...
設定がなかったときにエラーログを残すようにしています。
ログについてはまた別に回をとって紹介したいと思います。
return
か process.exit(1)
か
設定がなかったときの挙動はスクリプトごとにまちまちなのですが、必須の設定がなかった場合にものによっては process.exit(1)
しているものもあります。
個人的にはログを残しつつ、動作しないようにするのが好きです。
まとめ
Hubot スクリプトから設定(環境変数)を読み込む処理について紹介しました。
最後に
個人用のスクリプトなら自由にやればいいんじゃないですかね(適当)。