AnyEvent::Twitter::StreamをOAuthに対応させたいなぁ、と思ったので(ついでにChirpUserStreamsにも)
→ GitHub - taiyoh/AnyEvent-Twitter-Stream-OAuth: AnyEvent: :StreamをOAuth対応にする。将来的には名前も変えて、BASIC認証と混在できるようにしておくのがいいかと。
というモジュールを作成してみました。(若干現実逃避気味につき)
ちょっと前から話題になっているChirpUserStreamsにも対応していて、id:sugyanの紹介エントリ(Twitterの新しいStreaming API「ChirpUserStreams」がすごすぎる件 - すぎゃーんメモ)のサンプルスクリプト(上の方)のは、以下のように書き換えが可能。
#!/usr/bin/perl use common::sense; use FindBin; use lib "$FindBin::Bin/../lib"; use AnyEvent::Twitter::Stream::OAuth; use AnyEvent::HTTP 'http_request'; use Encode qw/encode_utf8/; my $oauth = AnyEvent::Twitter::Stream::OAuth->new( type => 'chirpstream', consumer_key => 'CONSUMER_KEY', consumer_secret => 'CONSUMER_SECRET', access_token => 'ACCESS_TOKEN', access_token_secret => 'ACCESS_TOKEN_SECRET', ); my ($method, $url, $args) = $oauth->make_request; http_request( $method, $url, %$args, sub { my $hdl = shift; my $r = sub { my (undef, $json) = @_; if (my $text = $json->{text}) { print encode_utf8 "$json->{user}{screen_name}: $text\n"; } }; $hdl->on_read(sub { $hdl->push_read( json => $r ); }); } ); AE::cv->recv;
AnyEvent::Handleの制御は上位レイヤの方に任せ、HTTPリクエストの生成部分のみを担当しています。
サンプルとして、AnyEvent::Twitter::Streamを書き換えたAETwitterStreamSampleというクラスをテストコードの中に入れていて、それを使って上のスクリプトを更に書き換えると
use strict; use FindBin; use lib "$FindBin::Bin/"; use lib "$FindBin::Bin/../lib"; use AETwitterStreamSample; use Encode qw/encode_utf8/; my $oauth = AETwitterStreamSample->new( type => 'chirpstream', # (type is here).twitter.com consumer_key => 'CONSUMER_KEY', consumer_secret => 'CONSUMER_SECRET', access_token => 'ACCESS_TOKEN', access_token_secret => 'ACCESS_TOKEN_SECRET', on_tweet => sub { my $tweet = shift; if (my $text = $tweet->{text}) { print encode_utf8 "$tweet->{user}{screen_name}: $text\n"; } } ); AE::cv->recv;
となります。
ストリーミングAPIへのOAuthでのアクセスは、今のところ、GETアクセスしか受け付けてないのかな…。filterメソッドのリクエストは、通常の更新APIで使っているリクエスト生成の手順で組み立てても、401のステータスコードが帰ってくるだけなんですね…。ここは、GETでリクエストを生成することで、難を逃れています。
まあ、こういうのを書いたところで、ストリーミングAPI側のBASIC認証は8月以降もまだ続くっぽいですし、あまり意味はないんですけどね。
そういえばどなたか、AnyEvent::Twitter::Streamで、プロセスが殺しきれてないって例に遭遇したことありますかね…。on_errorやon_eofのタイミングでdieするように書かれてはいて、ソケット側は"Broken Pipe"とでてくるのでおそらくちゃんと死んでますが、プロセス自体はちゃんと死んでないので、いわばゾンビのような状態…。