Twitter User Stream API でタイムラインを表示するサンプル

2012年11月1日追記

Twitter APIの仕様変更により、本記事内のソースコードは多分正しく動作しません。
ソースコードを見たい場合は、以下の記事及びリポジトリをご覧ください。
Twitter UserStreamから高速ダジャレ返信するbotのソースコードを公開しました - でぶぬる日記
https://github.com/aquarla/twitter_dajare_bot

以下、本記事の内容

http://dev.twitter.com/pages/user_streams

に書いてある通り、Twitter の User Stream API が正式版として公開されているようなので、タイムラインを表示するサンプルプログラムを作ってみました。

参考にさせて頂いたのは以下のサイトです。

Twitter Streaming APIをRubyで試してみる - しばそんノート

但し、今回のAPIは正式版ということもあり、以下の点を考慮しました。

  • 正式版の認証方式に合わせてOAuth認証に対応。
  • 正式版のAPIだと、chunkを連結しないとまともにJSONが取得出来なかった為、真面目にchunkをバッファリングして繋ぎあわせる実装に変更。
  • 正式版のAPIに合わせて、httpsでの呼び出しに対応。

本プログラムは、Ruby 1.8.7/1.9.2の両方で動作することを確認済みです。

# -*- coding: utf-8 -*-

require 'rubygems'
require 'net/https'
require 'oauth'
require 'cgi'
require 'json' if RUBY_VERSION < '1.9.0' # 1.9以降ではRuby本体に組み込まれている為

# 適当なものを定義すること。
CONSUMER_KEY        = "xxxxxxxx"
CONSUMER_SECRET     = "xxxxxxxx"
ACCESS_TOKEN        = "xxxxxxxx"
ACCESS_TOKEN_SECRET = "xxxxxxxx"

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

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

uri = URI.parse('https://userstream.twitter.com/2/user.json')

https = Net::HTTP.new(uri.host, uri.port)
https.use_ssl = true
https.ca_file = './verisign.cer' # SSL証明書のパスを書く
https.verify_mode = OpenSSL::SSL::VERIFY_PEER
https.verify_depth = 5

https.start do |https|
  request = Net::HTTP::Get.new(uri.request_uri)
  request.oauth!(https, consumer, access_token) # OAuthで認証

  buf = ""
  https.request(request) do |response|
    response.read_body do |chunk|
      buf << chunk
      while (line = buf[/.+?(\r\n)+/m]) != nil # 改行コードで区切って一行ずつ読み込み
        begin
          buf.sub!(line,"") # 読み込み済みの行を削除
          line.strip!
          status = JSON.parse(line)
        rescue
          break # parseに失敗したら、次のループでchunkをもう1個読み込む
        end
        if status['text']
          user = status['user']
          puts "#{user['screen_name']}: #{CGI.unescapeHTML(status['text'])}"
        end
      end
    end
  end
end