🕊️

2023年版 Twitter API v2を無料で叩く (OAuth 2.0 with PKCE)

2023/08/04に公開

はじめに

Twitterアイコンが青い鳥からXに変わって諸行無常な今日この頃、今更Twitter APIに入門してみました。意外と手順が複雑だったことと、新しい認可方式を利用していない記事も現状多そうなので、備忘録として詳しめに手順をまとめます。同じような方の参考になれば幸いです。

この記事では、以下の方法でAPIリクエストを行うことをゴールとします。

  • 無料プランを使い、完全無料でAPIリクエストを行います。無料プランでは以下3つのエンドポイントを利用可能で、月1,500ツイートまで投稿できます。
  • OAuth 1.0認証ではなく、2021年12月からサポートされたOAuth 2.0認証を利用します。
    Announcing OAuth 2.0 General Availability - Announcements - Twitter Developers
  • "OAuth 2.0 App-Only (Bearer Token)" ではなく、 "OAuth 2.0 with PKCE" を利用します。これにより開発Appとしてではなく、Twitterユーザーに成り代わってツイートすることが可能になります。詳しくは公式Docをご参照ください。
    OAuth 2.0 | Docs | Twitter Developer Platform

Twitter Developerにサインアップ

こちらの手順通りにTwitter Developerアカウントを作成します。
Developer account support | Twitter Developer Platform

サインアップ時にSubscribeと出てくるのでおや、と思いますが、よく見ると下にある "Sign up for Free Account" をクリックすると無料アカウントにサインアップできます。

agreement & policyの画面では、公式の説明通りビジネス用途なら "business purpose" と含める、個人用途ならどのようなプロジェクトを想定しているかを書く、ツイートするならどのようなコンテンツかを書く、など諸々に従って、Twitter APIの利用用途を250文字以上で書きます。
Developer policy support | Twitter Developer Platform

私は一応しっかり目に書きましたが、特に審査などは無くすぐにAPIを利用できるようになりました。

Twitter APIリクエストを実行する

ここからが本題です。Twitter APIリクエスト実行によりツイート投稿などをできるようにしていきます。

OAuth 2.0 の値取得

Twitter Developers > "Keys and tokens" > "OAuth 2.0 Client ID and Client Secret"
で以下2つの値を発行します。値はどこかに控えておきます。

  • OAuth 2.0 Client ID
  • OAuth 2.0 Client Secret

Twitter API v2 OAuth 2.0 with PKCE

Twitter API v2 を OAuth 2.0 with PKCE 認可で利用します。

以下の各サブセクションでは、公式Doc
OAuth 2.0 Making requests on behalf of users | Docs | Twitter Developer Platform
の各手順に紐付けて、補足や罠をご紹介しながら進めていきます。公式Docと照らし合わせながら使っていただければと思います。

Step 0: Working with confidential clients

The userid and password are separated by a single colon (":") character within a base64 encoded string in the credentials.
To create the basic authorization header you will need to base64 encoding on your Client ID and Client Secret which can be obtained from your App’s “Keys and Tokens” page inside of the developer portal.

"OAuth 2.0 の値取得" で取得した client_idclient_secret の値を、シングルコロンで繋いだ文字列 client_id:client_secret をBase64エンコーディングします。例えば次のコマンドでEncoded文字列を取得できます。

echo -n 'client_id:client_secret' | base64

後のStepで使うheaderは次のようになります。Basic のあとにbase64コマンドで取得したEncoded文字列を入れます。

-header 'Authorization: Basic <base64 encoded string>'

Step 1: Construct an Authorize URL

使いたいAPIエンドポイントに合わせて権限を決めます。

tweet.read%20tweet.write%20users.read%20offline.access

Step 2: GET oauth2/authorize

URLを作ります。https://twitter.com/i/oauth2/authorize?response_type=code& に続けて以下の値を指定します。

  • client_id: "OAuth 2.0 の値取得" で取得した client_id
  • redirect_url: "App info" > "Callback URI / Redirect URL (required)" で設定した値。これを忘れるとエラーになります
  • scope: Step 1で用意した値
https://twitter.com/i/oauth2/authorize?response_type=code&client_id=<cliend_id>&redirect_uri=<redirect_url>&scope=tweet.read%20tweet.write%20users.read%20offline.access&state=state&code_challenge=challenge&code_challenge_method=plain

URLにアクセスすると認可画面が表示されるので、Authorizeボタンを押します。これで、このTwitterユーザーに成り代わってTwitter Appが各操作 (ツイート投稿、削除など) を行えるようになります。

ボタンを押すと飛ばされるURLに code が含まれているので、素早く (大事) コピーします。

https://twitter.com/home?state=state&code=REDACTED

Step 3: POST oauth2/token - Access Token

/2/oauth2/token エンドポイントにリクエストすることで、アクセストークンを取得します。

Request POST /2/oauth2/token
curl --location --request POST 'https://api.twitter.com/2/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic <step 0のbase64 encoded string>' \
--data-urlencode 'code=<step2のcode>' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'redirect_uri=https://twitter.com' \
--data-urlencode 'code_verifier=challenge' \
--data-urlencode 'client_id=<oauth 2.0 client id>'

成功すればレスポンスで access_token, refresh_token が返ってきます。

Response
{
    "token_type":"bearer",
    "expires_in":7200,
    "access_token":"REDACTED",
    "scope":"tweet.write users.read tweet.read offline.access",
    "refresh_token":"REDACTED"
}

このとき、URLから code 取得後に急いでAPIリクエストを実行しないとエラーになります。code の有効期限が30秒のためらしいです。
Value passed for the authorization code was invalid - Security & authorization (OAuth) - Twitter Developers

I wasn’t aware of the 30 second limit for the auth token.

Step 4: Connect to the APIs

ここまで来れば、後はお好みのエンドポイントを選んでAPIリクエストを実行するのみです。無料プランでは以下3つのエンドポイントを利用できます。

  • POST /2/tweets
  • DELETE /2/tweets/:id
  • GET /2/users/me

Authorization: Bearer のあとに続けてStep 3で取得した access_token を入れます。

ツイートを投稿する: POST /2/tweets

POST /2/tweets | Docs | Twitter Developer Platform

Request POST /2/tweets
curl -X POST 'https://api.twitter.com/2/tweets' \
--header 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
-d '{"text": "Hello World!"}'

ツイートを削除する: DELETE /2/tweets/:id

DELETE /2/tweets/:id | Docs | Twitter Developer Platform
id には該当ツイートのURLに含まれているツイートIDを指定します。

Request DELETE /2/tweets/
curl -X DELETE 'https://api.twitter.com/2/tweets/:id' \
--header 'Authorization: Bearer <access_token>'

自分のユーザー情報を取得する: GET /2/users/me

GET /2/users/me | Docs | Twitter Developer Platform

Request GET /2/users/me
curl --location --request GET 'https://api.twitter.com/2/users/me' \
--header 'Authorization: Bearer <access_token>'
Responce
{
  "data": {
    "id": "1686629239049871360",
    "name": "twitter_display_name",
    "username": "twitter_id"
  }
}

Step 5: POST oauth2/token - refresh token

アクセストークンとリフレッシュトークンを再発行することができます。トークンの再発行を行うことで、トークンの有効期限が切れても、再度ユーザー認可をせずにAPIリクエストを実行できます。このコマンドを実行すると元のトークンは無効となります。

A refresh token allows an application to obtain a new access token without prompting the user. You can create a refresh token by making a POST request to the following endpoint: https://api.twitter.com/2/oauth2/token

Request POST /2/oauth2/token
curl --request POST 'https://api.twitter.com/2/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic <step 0のbase64 encoded string>' \
--data-urlencode 'refresh_token=<refresh_token>' \
--data-urlencode 'grant_type=refresh_token'
Response
{
  "token_type": "bearer",
  "expires_in": 7200,
  "access_token": "REDACTED",
  "scope": "users.read tweet.read offline.access",
  "refresh_token": "REDACTED"
}

Step 6: POST oauth2/revoke - Revoke Token

アクセストークンまたはリクエストトークンを無効化できます。

A revoke token invalidates an access token or refresh token. This is used to enable a "log out" feature in clients, allowing you to clean up any security credentials associated with the authorization flow that may no longer be necessary.

公式Docでは言及されていないようですが、 token_type_hintaccess_token または refresh_token を指定する必要があります。

Request POST /2/oauth2/revoke
curl --location --request POST 'https://api.twitter.com/2/oauth2/revoke' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic <base64 encoded string>' \
--data-urlencode 'token=<access_tokenまたはrefresh_tokenの値>' \
--data-urlencode 'token_type_hint=<access_token / refresh_token>'

おわりに

OAuth 2.0に詳しい方なら簡単かも知れないですが、そうでない私には手順が結構複雑に感じられました。各Stepで何をして、どういう流れで認可しているのか、は公式Docのこちらの図が参考になりました。
OAuth 2.0 Authorization Code Flow with PKCE | Docs | Twitter Developer Platform

無料プランでも現状月1,500ツイートまでは可能なので、十分に遊べそうです 🕊️

Discussion