Domoraen は、 id:tily さんが作った最強のTwitter botなのだが、
実装が公開されている。
この実装をもとに、Domoraen botを社内運用できる気がしたので色々試した。
前提として、 Domoraen は非常に厳しいライセンスのソフトウェアで、経緯は
@udzura まさか fork されるとは思わずスパムに悪用しないでねぐらいの意味でそのライセンス書いたんですが自分でも忘れてました、フェアユースだと思います
— tily (@tily) 2014, 8月 18
とのことだった。なので利用者もフェアユースの範囲でのインハウス運用等でお願いしたい。
HTTP API の追加
コードを読んだ所 Domoraen に必要な機能は一つのモジュールに集約されていたので、それをそのまま用いて Sinatra ベースで HTTP API を作った。この API サーバを社内に立てておく。
Hubot 経由で API を叩く
こんな感じの雑なラッパーを書く。 `request` ドチャクソ便利だと思う。Hubot標準のHTTP Clientはなんとなく好かんので。
余談だけど、コールバック関数を
accessDomoraen "#{apiRoot}/tools.json", onSuccess: (data) -> msg.send data.message onError: (err) -> msg.send "失敗したよ...: #{err}"
こんな感じでオプションで書けるようにするとCoffeeScript的にはコードが書きやすくなると言う気付きがあった。基本CoffeeScriptではぼくはクソコードしか書けないっすけど...
とつぜん Domoraen が便利な道具を出す
hubot, domoraen で道具を出してくれるけど、全然何の脈絡もなく道具を出してくれる方が面白いので、発言を拾ったりするようにする。
ランダムで拾う実装
robot.hear /(.*)/, (msg) -> return if Math.random() > 0.05 seed = encodeURIComponent(msg.match[1]) accessDomoraen "#{apiRoot}/tools/#{seed}.json", onSuccess: (data) -> return if data.message.match(/もう大人でしょ|自分でなんとかしろよ|それ無理/) msg.send data.message onError: (err) -> 'pass' # do nothing
道具の取得に失敗した場合は何も出力しない。ランダムで発言を拾っといて「自分でなんとかしろよ...」とかしゃべるのはそれはそれで面白いが、そのうちイラっとしそう。
いきなり狂ったようにアイテムを出す実装
Hubotの機能では「入っている部屋一覧」は取得できないので、自力で作る。
robot.enter (msg) -> if msg.message.user.name == robot.name robot.joinedRooms ?= [] robot.joinedRooms.push msg.message.room
あとはおもむろにランダムに部屋を取得して道具を取り出せば良い。
ncb000gt/node-cron · GitHubのようなオシャレなものを使わなくても、setTimeoutで問題なし。あと、 robot.on('start') みたいなイベントがあれば良いんだけど、無いんで、トップレベルにズバっと書いて初期化するイメージ。
nextDomoraenTickSeconds = () -> Math.round(Math.random() * 90 * 60) + 30 * 60 invokeDomoraen = () -> if robot.joinedRooms?.length room = robot.joinedRooms[ Math.floor(Math.random() * robot.joinedRooms.length) ] accessDomoraen "#{apiRoot}/tools.json", onSuccess: (data) -> robot.messageRoom room, data.message onError: (err) -> 'pass' # do nothing robot.logger.info nextDomoraenTickSeconds() * 1000 setTimeout invokeDomoraen, nextDomoraenTickSeconds() * 1000 setTimeout invokeDomoraen, nextDomoraenTickSeconds() * 1000
なお、ここまでのコードは全部hubot-irc前提なので、ほかの環境の方はがんばってほしい。そこまでがんばらなくても大丈夫だと思うけど。
まとめ
こんな感じで思いつきのプラグインや機能をどんどんHubotに搭載すると、CoffeeScriptの勉強にもなるし、良い。
Hubotはドキュメントが微妙に足りないので、本体のCoffeeScriptをちゃんと読むことになる。それも勉強になる(ポジティブ)。
あと、tilyさんの設計が奇麗すぎてHTTP APIを秒速で実装できたのが便利だった...。