今回は、
スクリプトの基本
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
- 公式ドキュメントは英語ですが、