2010/12/16

Twitter User Streams APIを「より一層」使ってみる

昨日の続き。

User Streams APIも、基本的には通常のAPIとほぼ同じデータが取得出来ます。そのデータをイベント毎に分岐する方法について@kei_sさんからnotwifemessage.rbをポインタとして教えてもらいました。皆さんnotwife使ってますかー超便利っすよーTwitter+Smartphoneな方は是非使うと良いです。


さて、上記の通りmessage.rbを参考にすると、イベント的には以下の分岐になるようです。
[text]がある→Tweet
[text]+[retweeted_status]がある→ReTweet
[event]="list_member_added"→Listに追加
[event]="list_member_removed"→リストから除外
[event]="follow"→Followされた
[event]="favorite"→Favされた
[event]="unfavorite"→Fav外された
[event]="list_created"→リスト作った
[event]="list_updated"→リストがアップデートされた
[event]="list_destroyed"→リストが削除された
[event]="block"→ブロックされた
[event]="unblock"→ブロック解除された
[friends]→※なんだこれ。
[delete]がある→Delete
[direct_message]がある→Direct Message
なので、GETしてきたJSONデータをParseした結果のHashから上記の値があるかどうかを探せば良い訳ですね。ただし、friendsが何なのかわからなかったのと、block/unblockがうまく取れませんでした。この辺は検討課題だな。
#!/usr/bin/ruby -Ku

require 'rubygems'
require 'oauth'
require 'net/https'
require 'json'


# 自分のアカウント名
myname = "smokeymonkey"

# OAuth 認証データ
CONSUMER_KEY        = "HOGEHOGE"
CONSUMER_SECRET     = "HOGEHOGE"
ACCESS_TOKEN        = "HOGEHOGE"
ACCESS_TOKEN_SECRET = "HOGEHOGE"


consumer = OAuth::Consumer.new(
  CONSUMER_KEY,
  CONSUMER_SECRET,
  :site => 'http://twitter.com'
)

token = OAuth::AccessToken.new(
  consumer,
  ACCESS_TOKEN,
  ACCESS_TOKEN_SECRET
)

# http://dev.twitter.com/pages/user_streams
uri = URI.parse('https://userstream.twitter.com/2/user.json')

begin
  # userstreamにはSSLでアクセスする
  https = Net::HTTP.new(uri.host, uri.port)
  https.use_ssl = true
  https.verify_mode = OpenSSL::SSL::VERIFY_PEER
  https.verify_depth = 5
  # ルートCA証明書をダウンロードしてきて指定
  https.ca_file = './ca.cer'

  https.start do |https|
    req = Net::HTTP::Get.new(uri.request_uri)
    req.oauth!(https, consumer, token)

    https.request(req) do |res|
      res.read_body do |chunk|
        # chunked = falseなら例外を発生
        raise 'Response is not chunked' unless res.chunked?

        # JSONのパースに失敗したらスキップして次へ
        status = JSON.parse(chunk) rescue next

        # イベントによる分岐
        if status['text'] then
          if status['retweeted_status']
            puts "**RTed @#{status['user']['screen_name']}: #{status['text']}"
          else
            puts "@#{status['user']['screen_name']}: #{status['text']}"
          end
        elsif status['direct_message'] then
          puts " ## DM ## @#{status['direct_message']['sender']['screen_name']} sent you!"
        elsif "#{status['event']}" then
          case "#{status['event']}"
          when 'list_member_added'
            puts " ## Added list->@#{status['source']['screen_name']}:[#{status['target_object']['slug']}]"
          when 'list_member_removed'
            puts " ## Removed list->@#{status['source']['screen_name']}:[#{status['target_object']['slug']}]"
          when 'follow'
            if "#{status['target']['screen_name']}" == myname then
              puts " ## Following you by-> " + "@#{status['source']['screen_name']} !"
            end
          when 'favorite'
            puts " ## Fav ## @#{status['source']['screen_name']} faved @#{status['target_object']['user']['screen_name']}: #{status['target_object']['text']}"
          when 'unfavorite'
            puts " ## Unfav ## @#{status['source']['screen_name']} unfaved @#{status['target_object']['user']['screen_name']}: #{status['target_object']['text']}"
          end
        else
          next
        end
      end
    end
  end
rescue
  print "RuntimeError: ", $!, "\n";
end
実行した結果はこんな感じ。
## Fav ## @dabesa faved @smokeymonkey: @tuka 当日盛り上げて!
## Unfav ## @dabesa unfaved @smokeymonkey: @tuka 当日盛り上げて!
## Following you by-> @dabesa !
## Added list->@dabesa:[hoge]
## Removed list->@dabesa:[hoge]
## DM ## @dabesa sent you!
**RTed @dabesa: RT @dabesa: RTのテストー
@dabesa 喋ってみる!
より便利になりました。これデュアルディスプレイに最大化して表示させときたい。