HipChatを使う機会があったので、lambdabotをHipChatへ組み込むプラグインを書いてる。とりあえず年内ぎりぎりでなんとなくは動くようになった。
以下、この件に関するメモ。
HipChatのAPI
WEB APIとXMPPが使える。メッセージのストリーミングはXMPPを使うことになってるっぽいので、lambdabotのようなユーザの発言に反応するbotはこちらを使ったほうが良い。ただし、WEB APIの方がXMPPでは指定できないような細いことにも対応しているので、いろんな操作をしたければこちらを叩くことになる。
HaskellのXMPP
更新されてそうなpontarius-xmppを使った。network-protocol-xmpp の方も一応は更新されてそう。
HipChatでグループチャットの発言を拾うためにはMUCに対応する必要があるのだが、こちらに対応しているのはhaskell-xmppとXMPPの2つだけだが、あまり更新されてないので採用しなかった。
lambdabotのXMPPサポートについては、実は2007年に形跡があるが削除されている。今はXMPP関連のコードは残っていない。と思う。2008年にもXMPP用のforkが作られた形跡がある。が、だいぶ古いしWEB APIも併用したいので、今回はガン無視してスクラッチから書いた。
lambdabot
IRCに密結合している。masterブランチ見た感じだと、本体とプラグインを分けようとしているっぽく、今回作ったものもこれに便乗してパッケージを切った。
lambdabot-irc-pluginsを読むとやるべきことはだいたいわかる。Lambdabot.Monad の received と addServer がエントリポイントで、こいつらを呼べばbotの処理に参加できる。ユーザから受け取ったメッセージは、前者の関数にひたすら流す。botの発言はaddServerに登録したハンドラに流れてくるので、これを再びユーザに返せばよい。
ただし、どちらのインタフェースもIRCと密結合しており、IrcMessage型を必要とする。XMPPやWEB APIの言葉をそれっぽくIRCの言葉に翻訳する必要がある。メッセージの先頭が「:」から始まるとか、割と生のプロトコルが見える形なので、気持ち悪い。
lambdabotのIRCへの接続は、ドキュメントで見てもわかるようにコマンドライン引数の -e で irc-connect コマンドを実行させることで行う。このオプションを渡さないと offline コマンドが呼び出される仕組み。シンプル過ぎる。同様に今回作ったプラグインでHipChatへ繋げたい場合は、コマンドライン引数で -e に hipchat コマンドを渡すと良い。
cabal sandboxとlambdabot
lambdabotは以下の2点の理由でcabal sandboxと相性があまりよくない。
前者はPATH環境変数、後者はGHC_PACKAGE_PATH環境変数を、手元でlambdabotコマンドを実行する時に手動で設定することで凌いでいる*1。
まとめ
よいお年を。