Jul 06, 2011

Net::Twitter::Lite で tweetするよ

twitter を始めた勢いに任せて、

を参考にして、Perl で Net::Twitter::Lite を使った CLI の twitterクライアントアプリケーションを作ってみました。

pochitwi.pl

#!/usr/bin/env perl

use strict;
use warnings;
use utf8;
use Encode;
use Try::Tiny;
use Net::Twitter::Lite;
use Time::Piece;
use YAML;
use File::HomeDir;
use Path::Class;
use HTML::TreeBuilder::XPath;
use Getopt::Std;

my $yaml = file( File::HomeDir->my_home, '.pochitwi.yml' );
my $conf = YAML::LoadFile( $yaml ) or die "$yaml: $!";

my $enc = $conf->{ encoding };

my $nt = Net::Twitter::Lite->new(
    consumer_key    => $conf->{ consumer }{ key },
    consumer_secret => $conf->{ consumer }{ secret },
    ssl             => 1,
   );

$nt->access_token( $conf->{ access }{ token } );
$nt->access_token_secret( $conf->{ access }{ token_secret } );

my %opts;
getopts("n:t:" => \%opts);

if ( defined $opts{ n } ) {
    $opts{ n } =~ /^\d{1,2}$/
        or die encode( $enc, "受け取れない件数ですよ?: $opts{ n }" ); 
}

if ( defined $opts{ t } ) {
    $opts{ t } =~ /^\d{17,}$/
        or die encode( $enc, "受け取れないステータスID ですよ?: $opts{ t }" ); 
}

unless ( $ARGV[0] ) {
    &get_twitter;
}
else {
    my $text = $ARGV[0];
    $text = decode( $enc, $text );
    my $length = length $text; 
    $length <= 140
        or die encode( $enc, "つぶやけるのは 140字以下ですよ?: $length" );
    &post_twitter( $text, $opts{ t } );
}

sub get_twitter {
    my $ht;
    try { 
        $ht = $nt->home_timeline( { count => $opts{ n } } );
    }
    catch {
        warn $_;
    };

    foreach my $line ( @{ $ht } ) {
        print $line->{ user }->{ screen_name }, ' ',
              encode( $enc, $line->{ user }->{ name } ), ' : ',
              '(', $line->{ id }, ')',
              encode( $enc, $line->{ text } ), ' ',
              &to_jst( $line->{ created_at } ), ' ',
              'via ', encode( $enc, &delete_html_tag( $line->{ source } ) ),
              "\n";
    }
}

sub post_twitter {
    my ( $text, $reply_to ) = @_;
    unless ( $reply_to ) {
        try { $nt->update( { status => $text } ); } catch { warn $_; };
    }
    else {
        try { 
             $nt->update( { status                => $text,
                            in_reply_to_status_id => $reply_to,
		          } );
        }
        catch {
            warn $_;
        };
    }
}

sub to_jst {
    my $twitter_dt = shift;
    my $t = Time::Piece->strptime( $twitter_dt, '%a %b %d %T %z %Y' );
    $t += 60 * 60 * 9;
    $t->datetime . '+09:00';
}

sub delete_html_tag {
    my $source = shift;
    my $tree = HTML::TreeBuilder::XPath->new;
    $tree->parse_content( $source );

    if ( my ( $node ) = $tree->findnodes( '//a' ) ) {
        return $node->as_text;
    }
    else { 
        return $source;
    }
    $tree->delete;
}

このコードとは別に .pochitwi.yml というファイル名でホームディレクトリ直下に、こんな設定ファイルを用意します。

encoding: utf8

consumer:
  key: Consumer key
  secret: Consumer secret

access:
  token: Access Token
  token_secret: Access Token Secret

utf8 は、日本語環境の文字コードに合わせて適宜変更します。また、Consumer key、Consumer secret、Access Token、Access Token Secret は、dev.twitter.com で Twitter API を使うアプリケーションの登録を済ませて入手します。

Pure Perl で書かれた YAML を使ってるせいか遅いですけども、そこは移植性を考慮して我慢がまん。

$ ./pochitwi.pl

とすると、下の出力例のような形式で、ホームのタイムラインから最新の 20件のつぶやきを表示します。

inuyamapochimar 犬山ぽち丸 : (87846235523919872)@konafi 壁の穴が心配デス 2011-07-04T20:32:29+09:00 via ぽちつい

出力する件数を指定するには -n オプションを使います。60件表示したい場合はこうします。

$ ./pochitwi.pl -n 60

つぶやくには、

$ ./pochitwi.pl '昨日快晴だったのに今日は大豪雨!?'

誰かのつぶやきに返信するには、-t オプションで返信を付けたい対象のつぶやきの ID を指定してつぶやきます。

$ ./pochitwi.pl -t 87845668449828864 '@konafi 昨日今日と随分涼しくなりましたよ〜?'

コード量のわりにシンプル過ぎる機能しかありませんけども、ぽちもまだ twitter を始めたばかりで凝った使い方が出来るわけじゃありませんので、今のところははこんな感じでも充分間に合っていたりします。

Posted at 18:15 in perl | Comments/Trackbacks ()
Comments/Trackbacks
TrackBack ping me at
http://pochi.usamimi.info/blog/perl/Net-Twitter-Lite.
Post a comment

writeback message: