--- title: Tumblr の引用だけを Twitter に通知する Perl スクリプト author: kazu634 date: 2010-03-29 url: /2010/03/29/_1499/ wordtwit_post_info: - 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:5199;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}' categories: - Perl ---

書いてみました。

何が問題だったの?

Tumblr に付属の Twitter 連携だと、画像とかも Twitter に通知されてしまうので、タイムラインが流れてしまいます(どうしても画像がメインになってしまいますよね。。。)。個人的にこれはあまりいい状況ではないと思っていました。そのために、 Tumblr の Twitter 連携機能をオフにしていました。ですが、個人的には引用だけを Twitter に通知したかったので、 Tumblr と Twitter の API を活用して、連携させました。

ソース

Perl で書きました。そのうち gauche に移植する!

# === Libraries ===
use strict;
use warnings;
use Perl6::Say;
use YAML::Syck;
use WebService::Simple;
use XML::Simple;
use utf8;
use Encode;
use Config::Auto;
use Net::Twitter;
# === Until what ID number do I get from my favorites ===
my $recent_id = ;    # variant for storing the recent-obtained ID number
# Read the ID number from the configuration file, .get_tumblr,
# if it exists.
if ( -f ".get_tumblr" ) {
my $config = Config::Auto::parse(".get_tumblr");
$recent_id = $config->{recent_id};
}
# === Tumblr から引用を取得する ===
my $tumblr =
WebService::Simple->new( base_url => "http://tumblrのユーザー名.tumblr.com/api/read", );
my $response = $tumblr->get( { type => 'quote', num => '50' } );
my $data = XMLin( $response->content );
my @ids = sort keys %{ $data->{posts}->{post} };
# === 取得した XML データを操作する処理 ===
foreach my $id (@ids) {
next if ($id <= $recent_id);
my $text = encode( 'utf-8', $data->{posts}->{post}->{$id}->{"quote-text"} );
my $url  = encode( 'utf-8', $data->{posts}->{post}->{$id}->{"quote-source"} );
# URLの処理
if ($url =~ /<a href="([^"]+)"/) {
        $url = $1;
    } else {
        $url  = encode( 'utf-8', $data->{posts}->{post}->{$id}->{"url"} );
    }
    # HTMLを除去する処理
    $text =~ s/<a.*>.+<\/a>://g;
    $text =~ s/<.*?>//g;
    $text =~ s/\(via?[^\)]+\)//g;
    $text =~ s/\n//g;
    $text =~ s/^\s+//g;
    chomp($text);
    # shorten URLs
    my $bitly = WebService::Simple->new(
        base_url => "http://api.bit.ly/shorten",
        param    => {
            login   => "bit.lyのユーザー名",
            apiKey  => "bit.lyのAPIキー",
            version => "2.0.1",
            format  => "xml",
        }
    );
    my $bitly_result = $bitly->get( { longUrl => $url } );
    my $short =
      XMLin( $bitly_result->content )->{results}->{nodeKeyVal}->{shortUrl};
    $url = $short;
    # 文字数のカウント
    # UTFの場合注意が必要!
    # http://weeeblog.net/blog/2007/12/01_1445.php
    my $count_text = length( decode( 'utf-8', $text ) );
    my $count_url  = length( decode( 'utf-8', $url ) );
    next if $text eq "";
    my $twitter =
        Net::Twitter->new( { username => 'Twitterのユーザー名', password => 'Twitterのパスワード' } );
    if ( ( $count_text + $count_url + 16 ) <= 140 ) {
        my $result = $twitter->update({status => "[quote] $text $url"});
    }
    else {
        # 投稿するスクリプトの整形処理
        my $display_text =
          substr( decode( 'utf-8', $text ), 0, ( 140 - ( $count_url + 12 ) ) );
        $text = decode( 'utf-8', $text);
        my $result = $twitter->update({status => "[quote] $display_text... $url"});
    }
    $recent_id = $id;
    last;
}
# === update the recent_id ===
open( FILE, '> .get_tumblr' ) or die "$!";
say FILE "recent_id=$recent_id";
close(FILE);

とりあえず

自宅サーバで0時~8時の間で cron で回してみて結果を見てみます。