本文へジャンプ

Twitter API プラン比較とv2.0のトークン認証(2023年7月時点)

Posted by mio.satoh

2023年2月、世界中のWeb開発チームが震撼するニュースが駆け巡ったーーー

今まで多くの開発者がお世話になっていた無償のTwitter Free API、そしてほとんどのTwitter関係の商用サービスで使用されていたStandard APIおよびPremium API、これらすべての提供終了。

そして新たに提供されるEnterpriseプランの価格発表です。

$5,000 / month。
約710万円/月。

TweetVision(ツイートビジョン)を開発・運用する我々MONSTER DIVE/SERVICEプロダクション事業部からしても、衝撃・戦慄でありました。

その後、ほぼ投稿しかできないFreeプラン、締め忘れた蛇口のしたたり程度の量のツイート取得ができるBasicプランが発表されたものの、商用サービスに利用するにはあまりに非力。

希望を失いかけていた我々にようやく福音がもたらされたのは5月のことでした。
かつてのPremiumAPIの代替になりうる、Proプランの提供開始です。

というわけで、まずはご案内させてください。

SNSキュレーション・ライブ・システム『TweetVision』、受付再開しました!

SNSキュレーション・ライブ・システム『TweetVision』

今までと提供形態が変わっておりますので、TweetVisionの最新情報はこちらのサービス紹介サイトにてご確認ください。


そして今回は、タイムリーでホットな情報として、Twitter APIのプラン契約についてや技術的な情報をご紹介したいと思います。

今ここをお読みのあなたは 「Twitter」 「API」 「認証」 とかで検索してたどり着きましたか?
この記事にはそんなあなたの求める情報があるかもしれません。


なお、下記のすべての情報は2023年7月10日時点の情報です。
確実な最新情報は公式のTwitter Developer Portalでご確認ください。

現在提供されているTwitterAPI

まず前提として、かつて存在していた「Twitter API v1.1」は完全廃止になり、APIのバージョンとしては「Twitter API v2」のみになりました。
認証方法がOAuth1.0aからOAuth2.0に変わったのが最も大きな違いですが、レスポンスの形式にもかなり差異があります。
以下のプランは全てv2として提供されます。

簡易比較表

Free Basic Pro
位置づけ 個人のお遊び 個人開発・テスト プロユース
できること 投稿・ユーザー情報取得のみ すべてのエンドポイントの利用 すべてのエンドポイントの利用
リクエスト数上限 1,500投稿/月 10,000ツイート/月 1,000,000ツイート/月
持てる環境数 1 2 3
価格 無料/月 $100/月 $5,000/月

各プランの説明

Free

ツイートの投稿、削除、ユーザー情報の取得のみができる無償API。
ツイート投稿上限は1,500ツイート/月。
環境数の上限は1つ。

Basic

ほとんどのエンドポイントを使用可能だが、取得できるツイート数が少ない有償API。
ツイート取得上限は10,000/月。
環境数の上限は2つ。
金額は$100/月。

Pro

ほとんどのエンドポイントを使用可能かつ、取得できるツイート数がかつてのPremiumAPIの最上位契約と同等まで引き上げられた有償API。
ツイート取得上限は100,000/月。
環境数の上限は3つ。
金額は$5,000/月。

プラン間の切り替えについて

Free/Basic/Proの間の切り替えは、Developer Portalでいつでもワンクリックで可能です。
ただし、各プランには環境数の上限があるため、例えばProで3つの環境を作成していた場合、一つ環境を削除してからでないとダウングレードできない、といった縛りがあります。

なお、いずれの有償APIも、初めての契約日から毎月1か月分を先払いする形で自動引き落としが始まります。
もしその1か月の半ばでアップグレードしたとしたら、アップグレードしたタイミングで残りの日数分アップグレードの差額が追加で引き落とされます。
逆に半ばでダウングレードしたら、すでに前払いしている上位プランは次回の引き落とし日まで継続となり、引き落とし日になったら下位プランに切り替わります。

Twitter API v2.0の認証

上にも書いた通り、Twitter API v2.0より、認証形式がOAuth2.0準拠となりました。
仮にWebアプリ・サービスでサーバサイドからTwitter APIにアクセスする場合、Bearerトークンが必要です。
v1.1では一度払い出したBearerトークンを半永久的に使えましたが、v2.0では以下のような面倒な手続きが必要です。

Bearerトークン取得手順

プロジェクト登録

Twitter Developerでプロジェクトを登録後、Environment(環境)を作成します。
サービスのURLやアクセスレベルなどの入力が求められるので、アプリの内容に合わせて入力してください。
途中で「Callback URI / Redirect URL」という項目があるので、ここには以下に出てくる「アクセスコード取得」で戻ってくる際のコールバックURLを入力しておきます。(あとから追加修正可能)
最後にClient IDとClient Secretが発行されるので、これらを控えておきます。

Basic認証コードの取得

Linux環境(opensslコマンドが使える環境)で、以下のコードを実行します。

echo -n "[client_id]:[client_secret]" | \
openssl enc -e -base64 | \
tr -d '\r\n'

[client_id]と[client_secret]の部分には、控えておいた文字列を入れます。
成功すると、以降の認証に使うBasic認証を暗号化した文字列が以下のように返ってきます。

nczaS7xHjb9B3BedRH5PacPZtUuy4WMt9mVz3PxZvR4as9TxxUa7irhaqfB55hqrfV8pXM8Xa3DDFPdYFEzJvvSjK6pWqm5pgjKFZtTzX6r7XZxvTR==

これをまた[basic]として控えておきます。

アクセスコードを取得

ブラウザで、以下のURLにアクセスします。

https://twitter.com/i/oauth2/authorize?response_type=code&client_id=[client_id]&redirect_uri=[redirect_uri]&scope=tweet.read%20users.read%20offline.access&state=[state]&code_challenge=[code_challenge]&code_challenge_method=plain

URLのうち [ 〜 ]の部分は適宜書き換えてください。
一つ一つ説明しますと、


client_id

上にも出てきたClient ID

redirect_uri

プロジェクト登録時に入力したリダイレクトURL。認証後にこのURLに戻ってくる

state

好きな文字列その1

code_challenge

好きな文字列その2

scope

tweet.read%20users.read%20offline.accessの部分は、サービスが求めるアクセス権限に合わせて設定する


上記URLにアクセスすると、Twitterのドメイン配下に飛ばされます。

Twitter アクセス権限 許可の画面

ここで「アプリにアクセスを許可」をクリックすると、以下のようなURLにコールバックされます。

[redirect_uri]?state=[state]&code=[code]

重要なのは返ってきた"code"パラメータの中身です。
このcodeを元として、最終的にアクセストークンとリフレッシュトークンを得るところがゴールです。
つまりredirect_uriにはこの"code"パラメータを受け取ってDB等に保存しておくプログラムを用意しておく必要があります。
とはいえ、そこまでいきなり作ろうとすると大変なので、ひとまずは返ってきたURLの"code"パラメータを[code]として手元に控えておいて、手作業で最後まで進んでみましょう。

アクセストークンを取得

取得した情報を元に、以下のようなcurlのコマンドを作成し、実行します。

curl --request POST "https://api.twitter.com/2/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Authorization: Basic [basic]" \
--data-urlencode "code=[code]" \
--data-urlencode "grant_type=authorization_code" \
--data-urlencode "client_id=[client_id]" \
--data-urlencode "redirect_uri=[redirect_uri]" \
--data-urlencode "code_verifier=[code_challenge]"

ここに出てくる書き換えポイントは今まで登場したものばかりなので、間違えないように入力すればOKです。 成功すると、以下のようなレスポンスが得られます。

{
"token_type":"bearer",
"expires_in":7200,
"access_token":"q24YcJ7KSmk7drxDARWRqr2ZyNpR7tJfW6
JNwUvTAZ9qvTbfYsju3TP72JmWMkay6g3jdMjs3nCu9YpnfZ5zuwnRAqc",
"scope":"users.read tweet.read offline.access",
"refresh_token":"iRZSDLfpSCZ2mBcSa9aQbVDQSrhdCvHb3
RNJw4CbGMnsLA4jXqBDEZqLKrRTWUarfYenEQLMR2Psx8ZayWRznjwrw7N"}

ついにアクセストークンとリフレッシュトークンを入手できました。
ひとまずはこのアクセストークンをBearerトークンとして、Twitter APIに接続することが可能です。
なお、[code]の有効期限は30秒なので、期限が切れていたらもう一度「アクセスコード取得」からやりなおす必要があります。

が、苦労して得られたこのアクセストークンの有効期限はわずか2時間。
アプリとしていつでもAPIに繋がるようにするには、適宜リフレッシュをかけてやる必要があります。

アクセストークンのリフレッシュ

アクセストークンの期限が切れていた場合、Twitter APIから403エラーが返ってくるはずです。
このエラーを受け取ったら期限切れの合図ということで、以下のコマンドでリフレッシュします。

curl --request POST "https://api.twitter.com/2/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Authorization: Basic [basic]" \
--data-urlencode "refresh_token=[refresh_token]" \
--data-urlencode "grant_type=refresh_token" \
--data-urlencode "client_id=[client_id]" \

[refresh_token]には、「アクセストークンを取得」で最後に返ってきたrefresh_tokenの中身を入れます。
成功すると、「アクセストークンを取得」と同様の新しいaccess_tokenとrefresh_tokenを取得できます。
(リフレッシュを行うと、古いアクセストークンとリフレッシュトークンは無効となります)

このアクセストークンの期限も切れたら、
またこのリフレッシュトークンを元にリフレッシュして、
という処理を繰り返すことで、
実質半永久的にTwitter APIにアクセスし続けることが可能になるのです。

ここまで手作業かつコマンドライン前提で一通りの認証の流れを説明しましたが、「アクセスコードを取得」の項目で書いたように、サーバサイドアプリケーションとして動作させるには自動化が必要です。
curlで実行した内容を適宜PHPなどに翻訳して、一連の流れがプログラマブルに実行されるようにするところが、Twitter API v2.0対応アプリ開発の第一歩となります。

Twitter API v2.0のレスポンス形式

Twitter API v2.0には多くのエンドポイントが存在するので、当然すべて紹介するわけにはいかないのですが、Search Tweetsエンドポイントを例に少しレスポンス仕様を解説します。

Search Tweets エンドポイント

v1.1では、レスポンスの各tweetの中に単純にid,text,user,mediaなどのデータが詰め込まれており、簡単にアクセスすることができました。
が、v2.0のレスポンスは少しクセがあります。

例として、"monsterdive"というキーワードでツイート検索する場合。

https://api.twitter.com/2/tweets/search/recent?query=monsterdive

これだけでも最低限の情報は取得できるのですが、レスポンスを見るとツイート主の情報やツイート日時などが存在しないスカスカの状態です。
必要な追加情報があれば、パラメータとして一つ一つ付与する必要があります。

https://api.twitter.com/2/tweets/search/recent?query=monsterdive&tweet.fields=created_at&expansions=author_id&user.fields=created_at

こんな風に、tweet.fieldsやuser.fieldsといったパラメータを追加することで、レスポンスの中身を拡充することが可能です。

なお、レスポンスの中でtweetとuserは分かれた形になっているので、例えば「あるツイートのユーザーのアカウント表示名を取得する」といった処理をしたいのであれば、tweetのuser.idとuserのidを照合してデータをマージする、といったひと手間が求められます。
面倒な仕様ですが、検索の負荷対策なのだろうと推測しています。

さいごに

Twitter API v1.1からv2.0への移行は、仕様の違いが大きく最初は戸惑うところもあるかもしれません。
が、APIとしての機能はもともとv2.0の方が充実しているし、一度作ってしまえばこちらの方が便利な部分もあります。
まずはFreeやBasicから、新しいTwitter APIに触ってみませんか?


なお、全く関係ない私事ですが、MONSTER DIVE最初の女性社員である私は、今週途中からMONSTER DIVE初の産休取得者になります。
どんな風に仕事を引き継いで、どんな風に過ごして、どんな風に復帰できるのか...今はまだ五里霧中ですが、来年にはそんなネタのブログ記事も書けるかもしれません。

それはまた、別の話。

Recent Entries
MD EVENT REPORT
What's Hot?