今回は、
スクリプトの基本
Hubotがスクリプトを読み込み実行する仕組みを説明するために、
module.exports = (robot) ->
robot.hear /hello/, (msg) ->
msg.reply 'hi'
このサンプルコードの一番外側を見ると、module.
に関数を代入しています。このmodule.
は、
サンプルコードでは、robot
のhear
メソッドを呼び出してコールバック関数を登録しています。このrobot
は、
このように、Robot
オブジェクトのメソッドを通じてコールバック関数を登録することで、
Node.
スクリプトの読み込み
では、
Hubotが起動してAdapterがチャットツールと接続したとき、./
、./
、hubot-scripts.
, external-scripts.
、HUBOT_
からNode.require
すると同時にmodule.
に代入された関数をRobot
オブジェクトを引数にして呼び出します。
Hubot
211 loadFile: (path, file) ->
212 ext = Path.extname file
213 full = Path.join path, Path.basename(file, ext)
214 if require.extensions[ext]
215 try
216 require(full) @
217 @parseHelp Path.join(path, file)
218 catch error
219 @logger.error "Unable to load #{full}: #{error.stack}"
220 process.exit(1)
216行目で、require
しつつexportされた関数を自分自身を引数として呼び出していることがわかります。
まとめ
スクリプトの登録から呼び出しまでの流れを図1に示します。

まとめると、Robot
オブジェクトにコールバック関数を登録します。最後に、
ここからは、
チャットでの発言に反応するhearとrespond
Hubotは、Robot
クラスのメソッドhear
とrespond
を使用します。hear
とrespond
を使ったコードのサンプルを次に示します。
module.exports = (robot) ->
robot.hear /foo/i, (msg) ->
msg.send "bar"
robot.respond /hoge/i, (msg) ->
msg.send "fuga"
respond
とhear
の使い方について説明します。
hear
書式を以下に記します。
hear: (マッチさせたい正規表現, 正規表現にマッチしたときに呼び出されるコールバック関数)
hear
メソッドは、/foo/
にマッチする発言があった場合にコールバック関数が呼び出され、

正規表現にマッチするならどのような発言にも反応してしまうので、
module.exports = (robot) ->
robot.hear /deploy/i, (msg) ->
# デプロイ処理
と言ったコードを書くと、hear
メソッドは、
respond
書式を以下に記します。
respond: (マッチさせたい正規表現, 正規表現にマッチしたときに呼び出されるコールバック関数)
respond
も、hear
と同じです。 しかし、respond
の場合はHUBOT_/hoge/
だった場合、respond
では

respond
は、hear
とは逆に、
注意点として、respond
メソッドは、^
を使用しても動作しないといった問題に遭遇することがあります。
チャットに発言を投稿するsendとreply
hear
とrespond
と同様にHubotにチャットで発言させる方法にもsend
とreply
の2種類があります。
send
とreply
を使ったコードのサンプルを次に示します。
module.exports = (robot) ->
robot.hear /foo/i, (msg) ->
msg.send "bar"
robot.respond /hoge/i, (msg) ->
msg.reply "fuga"
これまで書いてきたコールバック関数は、msg
という仮引数を持ちますが、Response
オブジェクトを通じてイベントが発生したときの状況を取得したり、
チャットに発言するには、Response
クラスのメソッドsend
もしくはreply
を使用します。
send
書式を以下に記します。
send: (発言内容...)
send
メソッドにHubotに発言させたい文字列を渡すことでHubotに発言させることができます。 引数は可変長となっており、

reply
書式を以下に記します。
reply: (発言内容...)
reply
メソッドを呼び出すと、send
メソッドと同様にHubotが発言しますが、send
メソッドとは

発言内容のキャプチャ
ここまでの内容で、hear
、respond
のどちらを使用した場合でも、
発言内容をキャプチャするコードのサンプルを次に示します。
module.exports = (robot) ->
robot.respond /deploy (.+)/i, (msg) ->
msg.send "deploy: #{msg.match[1]}"
respond
、hear
の第一引数に渡す正規表現がチャット上の発言にマッチした場合、Response
オブジェクトのmatch
プロパティにString.
たとえば、msg.
の中身を次に示します。
[
'hubot deploy web01',
'web01',
index: 0,
input: 'hubot deploy web01'
]
普通にString.
メソッドを使用した場合と同じく、
その他
Hubotのスクリプトでは、
チャットルームの入退室に反応する
Adapterが対応している場合、
module.exports = (robot) ->
robot.enter (msg) ->
msg.send "ようこそ #{msg.message.user.name}-san"
robot.leave (msg) ->
msg.send "さよなら #{msg.message.user.name}-san"

トピックの変更に反応する
Adapterが対応している場合、
module.exports = (robot) ->
robot.topic (msg) ->
msg.reply "トピックを変更しないでください #{msg.message.user.name}-san"
なお、
環境変数からの設定の読み込み
前回、process.
を使用することで環境変数に設定された値を読み取ることができます。
環境変数を読み取る例を次に示します。
optional_value = process.env.HUBOT_DEPLOY_KEY
module.exports = (robot) ->
robot.respond /deploy (.+)/i, (msg) ->
unless optional_value?
msg.reply "HUBOT_DEPLOY_KEYを設定して下さい"
return
# デプロイプロセス
msg.reply "デプロイが完了しました"
エラーハンドリング
Hubotの実行中にcatch
されなかった例外が発生した場合、error
イベントを発生させます。Robot
クラスのerror
メソッドを使用することで、error
イベントが発生した時に独自の処理を実行することができます。
error
イベントを処理する例を次に示します。
module.exports = (robot) ->
robot.error (err, msg) ->
console.log err
また、Robot
クラスのemmit
メソッドを使用することで自分のスクリプト内で意図的にerror
イベントを発生させることもできます。
module.exports = (robot) ->
robot.error (err, msg) ->
console.log err
robot.hear /foo/, (msg) ->
robot.emit 'error', new Error('error'), msg
Responseオブジェクトについて
ここまでの説明でReponse
オブジェクトの使い方をいくらか説明してきましたが、
メソッド
Response
クラスのメソッド一覧を次に示します。
メソッド名 | 用途 |
---|---|
send | チャットルームに通常の方法でメッセージを送る |
emote | 感情表現をチャットルームに送る |
reply | 発言者に対する返信としてメッセージを送る |
topic | チャットルームのトピックを変更 |
play | 音を鳴らす(ほぼCampifire専用) |
locked | ログに残らないように発言する |
random | リストを受け取るとそのリストの中からランダムに1つ選択 |
finish | 今回のメッセージに対してリスナの実行を終了 |
http | scoped-http-clientを使用してHTTPリクエストを作成 |
これらの多くはAdapterのメソッドを呼び出しているため、
playなどのあまり見かけないような機能を持っているのは、
お詫び
前回、
しかし、
尚、
プロパティ
Response
オブジェクトのプロパティのうち普段使うのは大きく分けてmessage
、match
の2種類です。
このうち、match
はrespond
やhear
など正規表現でマッチさせる種類のイベントの場合はString.true
が入っています。 この仕組みは、
message
プロパティには、Response
オブジェクトからmessage
プロパティの内容を抜粋した例を次に示します。
message: {
user: { id:'user', name:'user', room:'#chatroom' },
text: 'hubot ping',
id: undefined,
done: false,
room: '#chatroom'
},
上記の例は、
自分が使用しているAdapterでどのようなメッセージが送られてきているかを確認するには、hear
やrespond
などに渡すコールバック関数で引数のmsg
をconsole.
で出力してみるといった方法が簡単です。
まとめ
今回は、
普段はhear
、respond
とsend
、reply
を使うことが多いと思いますが、
次回は、
- 参考文献
- 公式ドキュメントは英語ですが、
わかりやすくまとまっています
https://github. com/ github/ hubot/ blob/ master/ docs/ scripting. md - ドキュメントに載っていない部分もソースコードを読むと理解しやすいです
https://github. com/ github/ hubot/ tree/ master/ src
- 公式ドキュメントは英語ですが、