Lingr APIで何か作る日記

Lingr APIを使って何か面白いものが作れないかと試行錯誤する日記です。
 | 

2007-02-09

API ClientRuby 1.8.2 (Debian Sarge) で動かす API ClientをRuby 1.8.2 (Debian Sarge) で動かす - Lingr APIで何か作る日記 を含むブックマーク はてなブックマーク - API ClientをRuby 1.8.2 (Debian Sarge) で動かす - Lingr APIで何か作る日記 API ClientをRuby 1.8.2 (Debian Sarge) で動かす - Lingr APIで何か作る日記 のブックマークコメント

Ruby 1.8.2だとAPI Clientが動かなかったのですが、回り道して原因を調べることにしました。

sample_chat_client.rb を編集して、API Clientを詳細デバッグモードで動くようにします。

@c = ApiClient.new(key, 0, hostname)

第二引数を0から2にすると、詳細なデバッグログが出るようになります。

@c = ApiClient.new(key, 2, hostname)

詳細デバッグモードでsample_chat_client.rbを動かすと、Net::HTTPのpost_formメソッドが無いというエラーがでました。Rubyリファレンスマニュアルを読むと、このメソッドはRuby1.8.3で追加されたようです。

Rubyごと1.8.5にするのが面倒だったので、少し安易ですがNetライブラリだけを新しくします。Ruby1.8.5のソースから、Netライブラリ一式 (ruby-1.8.5/lib/net/) を /usr/local/lib/site_ruby/1.8/ にコピーしました。

これでsample_chat_client.rbを動かします。

$ ruby sample_chat_client.rb <APIキー>
session/create succeeded

こんどはちゃんとセッションが作れました。ようやく先に進めます。

Ruby on RailsからLingr APIを使う Ruby on RailsからLingr APIを使う - Lingr APIで何か作る日記 を含むブックマーク はてなブックマーク - Ruby on RailsからLingr APIを使う - Lingr APIで何か作る日記 Ruby on RailsからLingr APIを使う - Lingr APIで何か作る日記 のブックマークコメント

API Clientも動くようになったので、いよいよLingr APIを使います。まずはAPI Clientの習熟を兼ねて、RailsからLingr APIを操作できるようにします。

APIチュートリアルによると、Lingr APIを使って発言するまでの流れは以下のようになります。

  1. session.createセッションを作る
  2. セッションを使ってroom.enterでルームに入る(チケットが発行される)
  3. セッションチケットを使ってroom.sayで発言するかroom.getMessagesroom.observeで発言を取得する。

Railsでは以下のモデルを作ってデータを管理します。

さて、APIチュートリアルの流れに沿って、ルームに入ってみましょう。

session.createセッションを作る  session.createでセッションを作る - Lingr APIで何か作る日記 を含むブックマーク はてなブックマーク -  session.createでセッションを作る - Lingr APIで何か作る日記  session.createでセッションを作る - Lingr APIで何か作る日記 のブックマークコメント

まずはセッションからです。セッションが無いと何もできません。Railsのgenerateを使ってSessionモデルを作ります。Railsバージョンは1.2.1です。

$ script/generate model Session name:string readonly:boolean created_on:date

Sessionが持つ属性は以下の通りです。

readonlyは、そのセッションを使って発言できるかどうかです。発言できるかどうかは、session.create時に指定するAPIキーで決まります。APIキーを作るときに、Permissionをobserve and speakとすれば発言可、observe onlyとすれば発言不可です(まだ試していませんが、きっとそうでしょう)。

2種類のAPIキーを取得し、config/environment.rbに書いておきます。

module Lingr
  API_KEY = 'observe and speakのAPIキー'
  API_KEY_READONLY = 'observe onlyのAPIキー'
end

Sessionモデルはこう書きました。Rails暦が浅いのでもっといい書き方があるかもしれません。

class Session < ActiveRecord::Base
  has_many :occupants, :dependent=>:destroy
  validates_presence_of :name

  def before_validation_on_create
    api_key = self.readonly ? Lingr::API_KEY_READONLY : Lingr::API_KEY
    api = Lingr::ApiClient.new(api_key)
    response = api.create_session
    unless response[:succeeded]
      error = response[:response]['error']
      message = "#{error['message']} (#{error['code']})"
      raise StandardError.new(message)
    end
    self.name = response[:response]['session']
  end
end

has_manyで複数のOccupantモデルと関連付けています。一つのセッションで複数のRoomに入ることを想定しています。

Lingr APIを使ってセッションIDを取得するのは、Sessionモデルを保存する直前 (before_validation_on_create) です。readonlyかどうかで、使用するAPIキーを切り替えています。無事にセッションIDを取得できたら、self.nameに代入します。エラーが起きれば例外を投げます。

試しに使ってみます。

$ script/console
Loading development environment.
>> Session.create    # セッションを生成
>> session = Session.new
>> session.readonly = true
>> session.save      # readonly のセッションを生成
>> puts session.name
"8kymI9MU5fZ"

無事にセッションIDが取得できたようです。

本当はsession.destroyにも対応させた方がいいのですが、とりあえず先に進みます。

セッションを使ってroom.enterでルームに入る (その1) セッションを使ってroom.enterでルームに入る (その1) - Lingr APIで何か作る日記 を含むブックマーク はてなブックマーク - セッションを使ってroom.enterでルームに入る (その1) - Lingr APIで何か作る日記 セッションを使ってroom.enterでルームに入る (その1) - Lingr APIで何か作る日記 のブックマークコメント

セッションを作ったので、次は部屋に入室します。room.enterの呼び出しパラメータを調べると、「入室するルームID」や「ルームのパスワード」が必要みたいです。これらは毎回の入室とは関係なく固定なので、部屋を管理するRoomモデルを作ります。

$ script/generate model Room name:string link:string password:string

Roomが持つ属性は以下の通りです。

Roomモデルデータを管理するだけなので、シンプルです。

Sessionモデルと同じく、has_manyで複数のOccupantモデルと関連付けています(一つの部屋に複数のセッションで入室することを想定)。

また、最低限必要なルームIDがないと、データベースに保存できないようにしています。

class Room < ActiveRecord::Base
  has_many :occupants
  validates_presence_of :link
end

試しにno titleのルームを登録してみました。

$ script/console
Loading development environment.
Room.create(:link => 'lingr_group_on_hatena')

セッションを使ってroom.enterでルームに入る (その2) セッションを使ってroom.enterでルームに入る (その2)  - Lingr APIで何か作る日記 を含むブックマーク はてなブックマーク - セッションを使ってroom.enterでルームに入る (その2)  - Lingr APIで何か作る日記 セッションを使ってroom.enterでルームに入る (その2)  - Lingr APIで何か作る日記 のブックマークコメント

セッションと部屋が出来たので、Occupantモデルを作って入室できるようにします。

$ script/generate model Occupant session_id:integer \
room_id:integer name:string nickname:string ticket:string

Occupantモデルには以下の属性を作りました。

ソースコードはこんな感じです。

class Occupant < ActiveRecord::Base
  belongs_to :session
  belongs_to :room
  validates_presence_of :name
  validates_presence_of :session
  validates_presence_of :room

  def before_validation_on_create
    return unless session && room
    api = Lingr::ApiClient.new(nil)
    api.session = session.name
    response = api.enter_room(self.room.link, self.nickname, self.room.password)
    unless response[:succeeded]
      error = response[:response]['error']
      message = "#{error['message']} (#{error['code']})"
      raise StandardError.new(message)
    end
    self.ticket = response[:response]['ticket']
    self.name = response[:response]['occupant_id']
    self.room.name = response[:response]['room']['name']
    self.room.save
  end
end                                                                                  

Sessionモデルと同じく、データベースに保存する直前にLingr APIを使って入室します。使い方の例です。

$ script/console
Loading development environment.
>> occupant = Occupant.create(:session => Session.create, :room => Room.find(1))
>> occupant.name
=> "krP8HBJumjA"
>> occupant.ticket
=> "a-r-fwjry8ziju8-2xpbRozJWb1"

新しいセッションを作って、先ほど登録したRoomに入室します。もちろん、以前のセッションを使いまわすこともできます。

occupant.nameでoccupant_idが、occupant.ticketで発言のためのチケットが取得できました。(微妙属性名が分かりにくい気がしますが…)

 |