wata.dev

perl で「はてな」、「twitter」、「facebook」のカウントを一括で取得するやつ書いた

元ネタは@satorunetさんのTwitterのURLのつぶやき数の取得方法@perl - satoru.netの自由帳。大抵の場合、欲しいのはこの3つだと思うので、一括で済むように作ってみました。ツッコミ歓迎!

$ plackup app.psgi

ですぐ試せるはず。

使い方

設置した URL にクエリパラメータ url を付与して GET するだけ。

socialcount

のように「はてな」、「twitter」、「facebook」のカウント数をまとめて JSON で返します。

とりあえず

  • JSON のみ
  • 指定できる URL は、一度に一つまで
  • はてな→被ブクマ数、twitter→被tweet数、 facebook→被いいね!数

コード

お好みで JSON のほか、XML や YAML 対応も。あと Cache::FileCache じゃなくて、memcached 使うとかとか。

app.psgi

use strict;
use JSON;
use Plack::Request;
use Plack::Response;
use WebService::Simple;
use Cache::FileCache;

my $cache = Cache::FileCache->new(
    {
        cache_root => 'tmp',
        namespace  => 'socialcount',
    }
);

my $app = sub {
    my $env = shift;
    my $req = Plack::Request->new($env);

    my $data;
    if ( $req->param('url') =~ m|s?https?://[-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#]+| )
    {
        my $url = $req->param('url');
        $data = {
            hatena   => get_hatena->($url),
            twitter  => get_twitter->($url),
            facebook => get_facebook->($url),
        };
    }
    else {
        $data = { error => 'The parameter is invalid' };
    }

    [
        200,
        [
            'Content-Type' => 'application/json; charset=UTF-8',
            'Access-Control-Allow-Origin' => '*'
        ],
        [ encode_json($data) ]
    ];
};

sub get_hatena {
    my $url = shift;
    my $key = "hatena:$url";

    if ( $cache->get($key) ) {
        return $cache->get($key);
    }
    else {
        my $service =
          WebService::Simple->new(
            base_url => 'http://api.b.st-hatena.com/entry.count', );
        my $res = $service->get( { url => $url } );
        my $count = $res->is_success && $res->content || "0";
        $cache->set( $key, $count, 60 * 60 * 20 );
        return $count;
    }
}

sub get_twitter {
    my $url = shift;
    my $key = "twitter:$url";

    if ( $cache->get($key) ) {
        return $cache->get($key);
    }
    else {
        my $service = WebService::Simple->new(
            base_url        => 'http://urls.api.twitter.com/1/urls/count.json',
            response_parser => 'JSON'
        );
        my $res = $service->get( { url => $url } );
        my $count =
          $res->is_success && eval { $res->parse_response->{count} } || "0";
        $cache->set( $key, $count, 60 * 60 * 20 );
        return $count;
    }
}

sub get_facebook {
    my $url = shift;
    my $key = "facebook:$url";

    if ( $cache->get($key) ) {
        return $cache->get($key);
    }
    else {
        my $service = WebService::Simple->new(
            base_url        => 'http://api.facebook.com/restserver.php',
            response_parser => 'JSON'
        );
        my $res = $service->get(
            {
                method => 'links.getStats',
                urls   => $url,
                format => 'json',
            }
        );
        my $count =
          $res->is_success && eval { $res->parse_response->[0]->{like_count} }
          || "0";
        $cache->set( $key, $count, 60 * 60 * 20 );
        return $count;
    }
}

ブログの記事一覧