Mobile Factory Tech Blog

技術好きな方へ!モバイルファクトリーのエンジニアたちが楽しい技術話をお届けします!

PerlでTwitterのPremium Search APIを叩く

こんにちは、エンジニアの @return520 です。

これは 2018年モバイルファクトリーアドベントカレンダー 12日目の記事です。前日は @toricor_で「headless Chromeでお手軽にWebページのE2Eテスト」でした。


はじめに

本記事では、Twitter のツイート検索APIのPremium Search APIを、Perlで利用する方法を紹介します。

Twitterは、ツイートの検索APIを複数提供しており、Premium Search APIでは、30日前まで遡れる30-dayと、全ての期間を遡れるFull-archiveでツイートを検索することができます。

※通常のStandard Search API では7日間までのツイートしか遡れません。

Overview | Docs | Twitter Developer Platform

There are two premium search API endpoints:

  • Search Tweets: 30-day endpoint → provides Tweets posted within the last 30 days.

  • Search Tweets: Full-archive endpoint → provides Tweets from as early as 2006, starting with the first Tweet posted in March 2006.

今回はOAuth::Liteを使用してTwitterのPremium Search APIを叩いてみようと思います。

※Premium Search APIの登録方法などは説明しません。

APIを叩く前に

エンドポイントの確認方法

Premium Search APIでツイートを取得したい場合は、Standard Search APIとは異る、以下のエンドポイントを使用します。

GET https://api.twitter.com/1.1/tweets/search/:product/:label.json

:product には、30dayもしくはfullarchiveのどちらかを入れます。

今回は fullarchive で試してみようと思います。

:label には https://developer.twitter.com/en/account/environments で setupする際に自身でつけた Dev environment label をそのまま入れます。

今回は dev とい名前にしましたので、 dev.json になります。

結果、エンドポイントはGET https://api.twitter.com/1.1/tweets/search/fullarchive/dev.json になりました。

エンドポイントポイントを叩く前の注意

Search API | Twitter API | Docs | Twitter Developer Platform

Premium Search APIには、Sandbox と Premium が存在します。

Sandboxは無料で利用することができますが、Premiumは有料です。

ちなみに、Sandboxでは一ヶ月間でAPIを叩ける回数に制限があります。

  • 30day 250回まで
  • fullarchive 50回まで

Premium もプランによって制限があります。ダッシュボード残り回数を確認することができるので注意しましょう。

https://developer.twitter.com/en/dashboard

OAuth::LiteでPremium Search APIを叩く

OAuth::Lite::Consumerを作成する

まずは、OAuth::Lite::Consumerを作成します。

  • consumer_key
  • consumer_secret
  • access_token
  • access_token_secret

については、Twitter Applicationを作成して取得をしてください。

use OAuth::Lite::Consumer;

sub create_consumer {
    my $consumer_key        = 'hoge';
    my $consumer_secret     = 'hoge';
    my $access_token        = 'hoge';
    my $access_token_secret = 'hoge';

    return OAuth::Lite::Consumer->new(
        consumer_key        => $consumer_key,
        consumer_secret     => $consumer_secret,
        access_token        => $access_token,
        access_token_secret => $access_token_secret,
    );
}

APIのエンドポイントを叩く

次に、作成したconsumerでAPIを叩くことができます。

公式ドキュメントにparamsの説明はありますが、以下のようなものが扱えます。

  • query
  • fromDate
  • toDate
  • next

fromDateとtoDateはUTCになりますので、注意してください。 nextは後に説明します。

以下のコードでは、2018 10/26 00:00〜2018 10/27 00:00に投稿された#Perlというハッシュタグがついたツイートを を検索しています。

use Encode;
use OAuth::Lite::Consumer;

sub create_consumer {
    my $consumer_key        = 'hoge';
    my $consumer_secret     = 'hoge';
    my $access_token        = 'hoge';
    my $access_token_secret = 'hoge';

    return OAuth::Lite::Consumer->new(
        consumer_key        => $consumer_key,
        consumer_secret     => $consumer_secret,
        access_token        => $access_token,
        access_token_secret => $access_token_secret,
    );
}

sub request {
    my $consumer = create_consumer();

    my $query = '#Perl';

    # UTC
    my $from_date = '2018102515:00'; # 2018 10/26 00:00
    my $to_date = '2018102615:00';   # 2018 10/27 00:00

    return $consumer->request(
        method  => "GET",
        url     => "https://api.twitter.com/1.1/tweets/search/fullarchive/dev.json",
        params => +{
            query    => encode('utf-8', $query),
            fromDate => encode('utf-8', $from_date),
            toDate   => encode('utf-8', $to_date),
        },
    );
}

レスポンスをjsonに変換する

取得したレスポンス($res)は HTTP::Response のObjectになります。$res->contentで生のcontent、もしくは、$res-> decoded_contentでデコードした後のcontentを取得することができます。

また、正常にリクエストできたかどうか$res->is_success で判定することもできます。

そして今回は、取得したJSON stringをJSON::XSを用いてdecodeしました。リクエストに失敗した場合はそのmessageを表示させています。

use Encode;
use OAuth::Lite::Consumer;
use JSON::XS;

sub create_consumer {
    my $consumer_key        = 'hoge';
    my $consumer_secret     = 'hoge';
    my $access_token        = 'hoge';
    my $access_token_secret = 'hoge';

    return OAuth::Lite::Consumer->new(
        consumer_key        => $consumer_key,
        consumer_secret     => $consumer_secret,
        access_token        => $access_token,
        access_token_secret => $access_token_secret,
    );
}

sub request {
    my $consumer = create_consumer();

    my $query = '#Perl';

    # UTC
    my $from_date = '2018102515:00'; # 2018 10/26 00:00
    my $to_date = '2018102615:00';   # 2018 10/27 00:00

    return $consumer->request(
        method  => "GET",
        url     => "https://api.twitter.com/1.1/tweets/search/fullarchive/dev.json",
        params => +{
            query    => encode('utf-8', $query),
            fromDate => encode('utf-8', $from_date),
            toDate   => encode('utf-8', $to_date),
        },
    );
}

sub get_tweets {
    my $res = request()

    if ($res->is_success) {
        my $content = $res->decoded_content || $res->content;
        return decode_json($content);
    }
    else {
        warn $res->message;
        warn $res->decoded_content;
        return +{};
    }
}

my $tweets = get_tweets()

これで $tweetsには以下のようなデータが入ってきます。

{
      "results":
      [
           {--Tweet 501--},
           {--Tweet 502--},
           ...
           {--Tweet 1000--}
      ],
      "next":"R2hCDbpBFR6eLXGwiRF1cQ",
      "requestParameters":
      {
        "maxResults":500,
        "fromDate":"201101010000",
        "toDate":"201201010000"
      }
 }

nextについて

次の検索結果を取得したい場合は、nextを渡すことで取得することができます。 nextの値はAPIのリクエスト結果の nextで取得することができます。

sub get_tweets {
    ...
}

my $tweets = get_tweets()
my $next = $tweets->{next};

my $consumer = create_consumer();
my $res2 = $consumer->request(
    method  => "GET",
    url     => "https://api.twitter.com/1.1/tweets/search/fullarchive/dev.json",
    params => +{
        query    => encode('utf-8', $query),
        fromDate => encode('utf-8', $from_date),
        toDate   => encode('utf-8', $to_date),
        next     => encode('utf-8', $next)
    },
);

さいごに

今回はPerlでTwitterのPremium Search APIを叩いてみました。

OAuth::Liteの使い方を知っていると、Twitter以外にもdiscordなど他のAPIも簡単に叩けるようになるので、知っていて損はないかと思います。


明日は htk291 です。お楽しみに!