Google WaveのRobotをRubyで作る
昨日の夜にGoogleオフィスでWave Hackathon(?)があった。そのときにWave RobotをGAE/J上でJRuby使ってSinatra上で動かしてみたので、以下にやったことのメモなど。
と言っても実はWave-Robot-Sinatra-Templateって言うのがすでに存在するのでほとんどやることはないんだけど。ただ少し問題があって、このテンプレートとそれが使ってるSDKのJRubyラッパーは古いAPI用に作られているみたいで、そのままじゃ動かない。必要な修正は次の2つ。
1. Waveクライアントから送られてくるJSONを保持する環境変数が変わってるみたいなのでwar/WEB-INF/app.rbを以下のように修正。
修正前
post '/_wave/robot/jsonrpc' do logger.info "Input: " + request.env['rack.request.form_vars'] json = JSON(request.env['rack.request.form_vars']) context = robot.execute_json_rpc!(json) output = AbstractRobot.serialize_context(context) output end
修正後
post '/_wave/robot/jsonrpc' do input = request.env['rack.input'].read logger.info "Input: " + input json = JSON(input) context = robot.execute_json_rpc!(json) output = AbstractRobot.serialize_context(context) output end
2. 新しいAPIではロボットにバージョンが設定できるんだけど、JRubyラッパーはまだバージョンが設定できないので/waveapi/lib/abstract_robot.rbに処理を追加
追加1(AbstractRobotクラス宣言直後)
@@version = "" def self.set_version(version) @@version = version end
追加2(AbstractRobot#capabilities内)
def capabilities() """Return this robot's capabilities as an XML string.""" lines = ['<w:capabilities>'] lines+= events_handled.map{|e| ' <w:capability name="'+e+'"/>'} lines.push('</w:capabilities>') unless @@crons.empty? lines.push('<w:crons>') lines += @@crons.map{|job, timer| ' <w:cron path="/_wave/robot/' + job.to_s + '" timerinseconds="' + timer.to_s + '"/>' } lines.push('</w:crons>') end # この行を追加 lines.push("<w:version>#{@@version}</w:version>") unless @@version.empty? # ...snip...
以上の修正が終わったら/war/WEB-INF/robot.rbに好きなように処理を記述する。ちなみに私がやったことは入力をevalして返すだけ。週末はAPE移植やってて時間なかったもんで・・・。
require 'lib/waveapi/init' class Robot < AbstractRobot set_name "WaveScriptTutor Bot" set_version "1.1.15" def BLIP_SUBMITTED(properties, context) wavelet = context.GetWavelets[0] blip = context.GetBlipById(wavelet.GetRootBlipId()) script = blip.GetDocument.GetText logger.info "Script: #{script}" blip.GetDocument.SetText("#{script}\nResult:\n#{eval(script)}") end end
実際に試してみるには普通のGAEアプリと同じように/war/WEB-INF/appengine-web.xmlを編集して
$ appcfg.sh update war
するだけ。
結果はこんな感じ。前半を入力してDoneするとResult:以下が追加された。
Robot APIのJRubyラッパーは(Java版とは比較するまでもないとして)Python版と比べてもずっと楽だと思うのでRubyユーザーなら使ってみてもいいと思う。