Twitter::RESTError エラー
http://twitter4r.rubyforge.org/rdoc/を元に、
twitter4r API サンプルの動作確認していたら Twitter::RESTError のエラーが発生。
具体的には、
require 'rubygems' gem 'twitter4r', '>=0.3.0' require 'twitter' require 'twitter/console' require 'kconv' # Create Twitter::Client Instance client = Twitter::Client.from_config('twitter.yaml', 'envname') # Get Twitter::User Instance user = client.user('username') # Print Twitter::User Attributes Twitter::User::attributes.each do |attribute| puts "#{attribute} : #{Kconv.kconv(user.send(attribute).to_s, Kconv::UTF8)}" end
のようなユーザ情報を表示するようなコードを実行させたら、
user メソッドで以下のようなエラーが発生した。
/opt/local/lib/ruby/gems/1.8/gems/twitter4r-0.3.1/lib/twitter/client/base.rb:39:in `raise_rest_error': Not Found (Twitter::RESTError)
from /opt/local/lib/ruby/gems/1.8/gems/twitter4r-0.3.1/lib/twitter/client/base.rb:44:in `handle_rest_response'
from /opt/local/lib/ruby/gems/1.8/gems/twitter4r-0.3.1/lib/twitter/client/base.rb:18:in `http_connect'
from /opt/local/lib/ruby/1.8/net/http.rb:543:in `start'
from /opt/local/lib/ruby/gems/1.8/gems/twitter4r-0.3.1/lib/twitter/client/base.rb:14:in `http_connect'
from /opt/local/lib/ruby/gems/1.8/gems/twitter4r-0.3.1/lib/twitter/client/user.rb:37:in `user'
from user_print.rb:11
Not Found という吐き出されたエラー内容から twitter4r が
twitter REST API で URL を正しく設定できていないんではないかと
疑いのもとスタックトレース情報を元に twitter4r のソースをたどっていくと、
user.rb 内で定義されている :info の定数が間違っているのが原因っぽいのが判明。
# twitter4r-0.3.1/lib/twitter/client/user.rb:2 class Twitter::Client @@USER_URIS = { :info => '/users/show', :friends => '/statuses/friends.json', :followers => '/statuses/followers.json', }
:info だけフォーマットが指定されてない。。。。
:info が '/users/show' となっているので、
user.rb の user メソッドにユーザIDもしくはスクリーン名が指定されると、
user メソッド内で呼び出される、 create_http_get_request メソッドに
'/users/show'(@@USER_URIS[action]) と {id=>'username'}(params)
が指定されてしまいます。
# twitter4r-0.3.1/lib/twitter/client/user.rb:37 def user(id, action = :info, options = {}) raise ArgumentError, "Invalid user action: #{action}" unless @@USER_URIS.keys.member?(action) id = id.to_i if id.is_a?(Twitter::User) params = options.merge(:id => id) response = http_connect {|conn| create_http_get_request(@@USER_URIS[action], params) } bless_models(Twitter::User.unmarshal(response.body)) end
create_http_get_request メソッドでは
twitter に HTTP の GET でアクセスするための
Net::HTTP::Get のインスタンスを作成して呼び出し元に返しています。
その際に、path を指定しているが path は create_http_get_request メソッド
に指定されたパラメータにより '/users/show?id=username' となり、
その path が指定された Net::HTTP::Get のインスタンスが呼び出し元に返されてしまっています。
# twitter4r-0.3.1/lib/twitter/client/base.rb:79 def create_http_get_request(uri, params = {}) path = (params.size > 0) ? "#{uri}?#{params.to_http_str}" : uri Net::HTTP::Get.new(path, http_header) end
そんでもって、 そのインスタンスを利用して http_connect メソッドで
twitter にアクセスしてユーザー情報を得ようするみたいですが、
そんな指定された場所はありませんと怒られてしまってエラーとなり、
user メソッドでユーザー情報が取得できないという状況のようです。
というわけで、 @@USER_URIS の :info を '/users/show.json' にしてみたら動きました。
こうすることで、create_http_get_request メソッドで
path に '/users/show.json?id=username' となるおかげで、
twitter にアクセスできるようです。
以下は、その実行結果。
id : 17755912
name : kazuya kawaguchi
description : かずぽんです。仕事はソフト開発してます。よろしく。
location : iPhone: 35.689976,139.697830
screen_name : kazu_pon
url : http://d.hatena.ne.jp/kazu_pon/
protected : false
profile_image_url : http://a1.twimg.com/profile_images/274655366/profile_normal.jpg
profile_background_color : 0099B9
profile_text_color : 3C3940
profile_link_color : 0099B9
profile_sidebar_fill_color : 95E8EC
profile_sidebar_border_color : 5ED4DC
profile_background_image_url : http://s.twimg.com/a/1250809294/images/themes/theme4/bg.gif
profile_background_tile : false
utc_offset : 32400
time_zone : Tokyo
following : false
notifications : false
favourites_count : 123
followers_count : 114
friends_count : 168
statuses_count : 1340
created_at : Sun Nov 30 15:33:02 +0000 2008
ちなみに、 my メソッドもこれで動くようになります。
そんなわけで、とりあえず動作するようになったけでなんですが、
'/users/show.json?id=username' でユーザー情報を取得する方法って、
Twitter API 仕様書 第二十版 (2009年4月16日版) や本家の http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-users%C2%A0show
の例をみるとないんですよね。。。
それとも実はある?というより、自分が知らないだけ?。
もし、この方法が正式な方法ではない場合、twitter4r の作者に
なんとかしてもらいたなぁと思います。
自分がパッチを作るという案もありますが。