(下書きのまま置いてありました。2015年の記事です)
気がつけば最近は IRC ではなく、 hipchat と slack を日常的に使っていて、bot を作りたいなぁと思い hubot に手を出しました。
PyCon JP スタッフの slack では good と言うと ( ・ㅂ・)و ̑̑ グッ! っと返って来るわけですが、 仕事で使ってる hipchat でもやりたいぞ、と思い、簡単な script を組んでみました。
module.exports = (robot) ->
robot.hear /^(goo+d)/i, (msg) ->
msg.send "( ・ㅂ・)و ̑̑ グッ!"
これを hubot の scripts/ ディレクトリ以下において起動すれば、
hubot> good
( ・ㅂ・)و ̑̑ グッ!
と返ってきます。
すでに hipchat には接続してるので、hipchat 用の hubot を立ち上げれば
返事されました。(adapter は hubot-hipchat を使ってます。)
これをチームに投入したところ、「キーワードとレスポンスを自分たちでも登録したい!」と言う要望が来たので、 hubot.brain を使って書いてみました。
# Description:
# レスポンスをその場で登録出来るようにする script
#
# Commands:
# おぼえて <request> => <response>
module.exports = (robot) ->
BRAIN_KEY = 'nanako'
get_responses = () ->
return robot.brain.get(BRAIN_KEY) or {}
set_reponse = (matcher, response) ->
responses = get_responses()
responses[matcher] = response
robot.brain.set BRAIN_KEY, responses
# 明示的に save しなくても何かのタイミングで保存されるらしい
robot.brain.save()
return responses
get_regex_by_responses = () ->
responses = get_responses()
regex_array = []
for key, value of responses
regex_array.push "(?:#{key})"
console.log(regex_array)
regex_text = regex_array.join('|')
return ///#{regex_text}///i
robot.respond /おぼえて\s(.*)/i, (res) ->
remind_words = res.match[1]
match = /^(\S+)\s?=>\s?(.+)$/.exec(remind_words)
if not match?
res.reply "(´-`).。oO(「おぼえて ほげ => ふが」って言って欲しいなぁ……)"
else
set_reponse(match[1], match[2])
res.reply "#{match[1]} って言ったら #{match[2]} だね。 okay!"
robot.respond /おもいだして/i, (res) ->
responses = get_responses()
content = []
for key, value of responses
content.push "#{key} => #{value}"
res.reply content.join("\n")
res.reply "これで全部のはず"
robot.hear /(.+)/, (res) ->
message = res.message.text
responses = get_responses()
for key, value of responses
if message.match(///^(?:#{key})///i)
res.send value
これで、「hubot おぼえて ほげ => ふが」 と言及すれば対になるキーワードとレスポンスを覚えてくれるようになりました。
robot.hear で受け取れるもの全部受け取ったあとにキーワードを正規表現としてマッチングさせてるので、 「hubot おぼえて go+d => ( ・ㅂ・)و ̑̑ グッ!」と教えれば、
hubot> goooooooooooood
( ・ㅂ・)و ̑̑ グッ!
o が何個並んでも応えてくれるように……!
robot.hear, robot.respond でその場への発言か、自身への言及かを使い分けられて、正規表現でマッチしたものを拾って行くやり方は簡単でいいですね。
ちょっと coffeescript のやり方が分かっておらず、正規表現内での変数展開とかが戸惑ってしまったけど。
返信も res.send か res.reply の使い分けで言及してきた相手へのリプライにするのもお手軽でした。
若干、 hubot.brain の挙動がよく分かってないので暇なときにソース読みたいですね。