ChirpUserStreams っていう Twitter API を使ってみた
なんだか自分の TL のイベント等がもりもり取れるらしい
Twitterの新しいStreaming API「ChirpUserStreams」がすごすぎる件 - すぎゃーんメモ が面白そうだったので、自分でも作ってみた。
自動返信とかはしてないのだけど、とりあえず自分のTLの状態をひたすらウォッチするというモノ。
require 'net/http' require 'uri' require 'pp' require 'kconv' require 'rubygems' require 'pit' require 'json' #-------------------------- # 取得した Streamデータを文字列として出力する。 # Parser クラスには parse メソッドが実装されてればおk #-------------------------- class Parser def parse(status) if(status["friends"]) friends status elsif(status["user"]) user status elsif(status["delete"]) delete status elsif(status["event"] == "follow") follow status #elsif(status["target_object"]) elsif(status["event"] == "retweet") retweet status elsif(status["event"] == "favorite") favorite status elsif(status["event"] == "unfavorite") unfavorite status #end else puts "unknown data." pp status end end :private def user(status) output "[Tweet]#{status['user']['screen_name']} : #{status['text']}" end def friends(status) output "[friends] friends(follow count) => #{status['friends'].size}" end def delete(status) output "[delete] userid:#{status['delete']['status']['user_id']} tweet_id:#{status['delete']['status']['id']}" end def follow(status) output "[follow] #{status['source']['screen_name']} => #{status['target']['screen_name']}" end def favorite(status) output "[fav] #{status['source']['screen_name']} => #{status['target']['screen_name']} / #{status['target_object']['user']['screen_name']} : #{status['target_object']['text']}" end def unfavorite(status) output "[unfav] #{status['source']['screen_name']} => #{status['target']['screen_name']} / #{status['target_object']['user']['screen_name']} : #{status['target_object']['text']}" end def retweet(status) output "[RT] #{status['source']['screen_name']} => #{status['target']['screen_name']} / #{status['target_object']['user']['screen_name']} : #{status['target_object']['text']}" end def output(str) puts str.toutf8 end end #-------------------------- # TwitterStream 取得クラス #-------------------------- class TwitterStream def initialize(user, pass) @user = user @pass = pass end def parser=(parser) @parser = parser.new end def parse(status) @parser ||= Parser.new @parser.parse(status) end def twitter_stream(uri) Net::HTTP.start(uri.host, uri.port) do |http| request = Net::HTTP::Get.new(uri.path) request.basic_auth(@user, @pass) http.request(request) do |res| raise Exception, (res.code + " " + res.message) if res.code !~ /2\d\d/ data = "" res.read_body do |chunk| begin status = JSON.parse(chunk) rescue data << chunk status = JSON.parse(data) rescue next data = "" end yield status end end end end end #-------------------------------------- # Twitter Strean 取得開始 #-------------------------------------- URL = 'http://chirpstream.twitter.com/2b/user.json' ts = TwitterStream.new(Pit.get("twitter")["username"], Pit.get("twitter")["password"]) # 出力を変更したかったら、以下のようにクラスを直接ぶっこんで。 #ts.parser = Parser ts.twitter_stream(URI.parse(URL)) do |status| ts.parse(status) end
解説するまでも無いですけど
TwitterStream のクラスがキモで、APIを叩いて chunk で来ているストリームをちまちま読んで、JSONでパースできたら1ターン終了、みたいな流れ。
参考文献
- Page not found | Twitter Developers
- Twitterの新しいStreaming API「ChirpUserStreams」がすごすぎる件 - すぎゃーんメモ
- 屋久島沈没 / User Stream 時代の Twitter の過し方
一番最後のサイトが戻り値の形式であるとか、そもそも仕様自体の是非等に言及されててわかりやすいです。
ちなみに
これを drb で実行して yield で別プロセスからとれれば WebAPPにできるなぁ*1、とか思ったのですが、イマイチ drb で yield のメソッドを実行できなくて挫折中。。。
っていうか、yieldを初めて実用的に使った気がする!