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"とでてくるのでおそらくちゃんと死んでますが、プロセス自体はちゃんと死んでないので、いわばゾンビのような状態…。