こんにちは、エンジニアの @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 です。お楽しみに!