Subscribed unsubscribe Subscribe Subscribe

AnyEvent::Twitter::StreamでDesktop Notify

Perl Twitter Mac

Twitterクライアントアプリでよくある「デスクトップ通知機能」。Macの場合はGrowlでアイコンと発言が出たりしますよね。
先日TwitterのUser streams APIがついに一般公開されたそうで、それに伴ってCPANモジュール"AnyEvent::Twitter::Stream"もアップデートされました。
Tatsuhiko Miyagawa / AnyEvent-Twitter-Stream-0.20 - search.cpan.org
せっかくなのでちょっと使ってみました。
参考:Twitterの新しいStreaming API「ChirpUserStreams」がすごすぎる件 - すぎゃーんメモ

#!/usr/bin/perl
use strict;
use warnings;

use AnyEvent::HTTP;
use AnyEvent::Twitter::Stream;
use Config::Pit;
use File::Temp;
use Encode qw/encode_utf8 from_to/;
use Log::Dispatch::DesktopNotification;

my $config  = pit_get('twitter.com', require => {
    consumer_key    => 'consumer key',
    consumer_secret => 'consumer secret',
    token           => 'access token',
    token_secret    => 'access token secret',
});
my $notify = Log::Dispatch::DesktopNotification->new(
    min_level => 'info',
    sticky    => 0,
);

my $cv = AE::cv;
my $listener = AnyEvent::Twitter::Stream->new(
    %$config,
    method   => 'userstream',
    on_tweet => sub {
        my ($tweet) = @_;

        my $user = $tweet->{user}{screen_name};
        my $text = encode_utf8($tweet->{text} || '');
        return unless $user && $text;

        my $image_url = $tweet->{user}{profile_image_url};
        http_get $image_url, sub {
            my ($data, $headers) = @_;

            my ($suffix) = $image_url =~ /(\.[^\.]+)$/;
            my $fh = File::Temp->new(
                SUFFIX => $suffix,
                UNLINK => 1,
            );
            print $fh $data;
            $notify->{title}     = $user;
            $notify->{icon_file} = $fh->filename;
            from_to($text, 'MacRoman', 'utf8');
            $notify->log(
                level   => 'info',
                message => $text,
            );
        };
    },
);
$cv->recv;


streamingで自分のfollowerたちの発言を取得し、デスクトップに通知します。バックグラウンドで実行させておけばいいんじゃないでしょうか。MacGrowlでは確認済み、Linuxでは動くかどうかわかりません*1Windowsでは何も起こらないんじゃないかな。
OAuth認証に必要な情報はConfig::Pitで読み込んでます。"on_tweet"で次々と取得される発言をハッシュリファレンスで受け取るので、ここから通知へ。せっかくなのでGrowlにアイコンを表示させたい、と思ったのだけどURLを指定してもダメなようなのでAnyEvent::HTTPでダウンロードしてきてtempfileに書き込んでパスを渡すようにした(しかも拡張子がついてないとダメらしい)。$notifyのtitleやicon_fileを直接代入で書き換えるのは行儀悪いかもしれない。MacGrowlを使って日本語を渡す場合はエンコードがなんだかめんどくさいかんじ。もっとうまくできるのかな。

*1:追記:動くらしいです。id:punitanさんありがとうございます。 http://d.hatena.ne.jp/punitan/20101002/1286048130