ルモーリン
ホーム 更新 Perl Sample サービス 雑談 鉄ゲタ Linux リンク 連絡先

プログラムでツイートする方法

投稿:2022-05-25

ツイッターのアプリケーション開発のライセンスにin-house(自家用)というのができて、 文字通り自分用なので従来の「申請して許可が出る」よりも容易になり、「登録でOK」といった感じで使えるようになりました。 自動ツイートをやりたかったので登録はしてみたものの、ドキュメントが英語という未知な言語の上に、APIが新旧、OAuthも新旧あります。 現段階(2022-05-25)では並行で運用できる状態なので開発者が新旧を取捨選択することになります。 ドキュメントを読む(解読?)していくと新のつもりで読んでいていつの間にか旧を見てたりすることもしばしば。 新APIと新OAuthでツイートできるようにする一本道を残しておきたい。 おまけで、いくつかのブログを拝見すると頻度が少ないからと手作業で済ましている所があり、プログラムで処理する場合にどうするかも記録しておきたい。

あなたのアカウントに代わりプログラムがツイートできるようにするので、アカウントがアプリケーションを認証する作業があります。 その際、ツイッター(ツイッター社のサーバー)がアクセスしてキーワード等をあなたのサイトに報告に来ます。 厳密にはブラウザのリダイレクトですが、とりあえず受付用のURLが必要です。
実際のプログラムを見たほうが早い方は実際のプログラムをご覧ください。
Mojolicious用ツイートモジュール

  1. アプリケーション登録
  2. アカウント承認
  3. リダイレクト受付
  4. リフレッシュトークン取得
  5. ツイート
  6. アクセストークンをリフレッシュ

開発者向けサイトの入口は、おそらくここです。
Use Cases, Tutorials, & Documentation | Twitter Developer Platform
すでにツイッターのアカウントはお持ちでしょうから、そのアカウントを開発者として登録しましょう。 デベロッパーポータルにダッシュボードがあり、無料プランのEssentialになっています。 プロジェクト1個とその中にアプリケーションを1個作成します。 動作するプログラムがまだ用意できなくて構いません。 アプリケーションを作成した際にClient Secretが1度だけ表示されるのでPCに控を残してください。 これでEssentialの上限に到達しました。 1プロジェクト=1アプリケーションです。 Projects & AppsのプロジェクトのOverviewのAppsにある作成したアプリケーションの歯車(⚙)のSettingsのUser authentication settingsに入ってください。 OAuth 2.0を有効、Type of Appを「Automated App or bot」、Callback URI / Redirect URLに<リダイレクト受付URL>を設定します。 歯車(⚙)のKeys and tokensのOAuth 2.0 Client ID and Client SecretのClient IDを控えてください。

手元にこれらがあるはずです。

  1. <リダイレクト受付URL>
  2. Client ID
  3. Client Secret

プログラムがアカウントの名を借りてツイートすることをアカウントに承認してもらいます。 この作業をしている本人は自分のアカウントと自分のプログラムなのであたりまえなのですけれど、ツイッターはアカウントとプログラムの関係がわかりません。 そこで、アカウントから「このプログラムに任せるよ」とツイッターに連絡する訳ですね。 この作業に「これは確かにアカウント本人だ」と判る仕組みが入っています。

ステートというランダム文字列を用意します。 お手軽なBase62で適当に32文字(英小文字+英大文字+数字=26+26+10=Base62)。 以下のBase62も文字種の多い奴にして構いません。 文字種や文字数の範囲はツイッターの開発者向けドキュメントにありますのでよく読みましょう(そして迷子になりました)。 受付予定のURLにアクセスされる際にクエリに差し込まれます。 ステートを検証すると他者からのアクセスを弾けます。

ベリファイアというランダム文字列を用意します。 Base62で適当に64文字。

ベリファイアからチャレンジを生成します。 ベリファイアからハッシュ(SHA256)を作り、Base64形式にしたあと、「+」を「-」に「/」を「_」に置き換え、末尾の連続する「=」を全部削除すると出来上がり。 このアカウント承認でツイッターにチャレンジを渡し、後で登場するトークン取得でベリファイアを渡します。 おそらくベリファイアを渡した際にツイッターもチャレンジを生成、予め渡した方と照合すると思います。

承認URLを作ります。 見た目が合うよう書いたのでコピペは失敗するかもしれません。 クエリのパラメタに空白等あるのでURIエンコードしてください。 (ブラウザのURL覧に入れると自動でURIエンコードしたっけ?)

https://twitter.com/i/oauth2/authorize?response_type=code&client_id=<Client ID>&redirect_uri=<リダイレクト受付URL>&scope=users.read tweet.read tweet.write offline.access&state=<ステート>&code_challenge=<チャレンジ>&code_challenge_method=S256

アカウントでログイン中のブラウザで承認URLにアクセスするとツイッターの画面が表示されます。 プログラムがアカウントの代わりに何をするかの説明、それを承認するかの問い合わせがあります。 承認するかキャンセルするとリダイレクト受付のURLにブラウザからアクセスします。

手元にこれらがあるはずです。

  1. <リダイレクト受付URL>
  2. Client ID
  3. Client Secret
  4. ステート
  5. ベリファイア

アカウント承認(かキャンセル)直後に<リダイレクト受付URL>にブラウザがGETメソッドでアクセスしてきます。 クエリのstateがステートと一致しなければ他者からのアクセスです。 stateが一致したらステートは不要です。 クエリにcodeがなければキャンセルで、errorに説明(英文)があります。 codeがあれば承認されています、しましたよね? codeは承認の証明みたいなものですがその分、有効期限がとても短いです。 codeが手に入ったらリダイレクト受付の延長で処理を続けましょう。

手元にこれらがあるはずです。

  1. <リダイレクト受付URL>
  2. Client ID
  3. Client Secret
  4. ベリファイア
  5. code

codeをツイッターに渡してリフレッシュトークンをもらいます。 おまけでアクセストークンもついてきます。 プログラムがツイートできる肝になりますからツイッターも受付が厳重です。

リクエストヘッダーにAuthorizationヘッダーを入れます。 作り方は<Client ID>と<Client Secret>をコロンで区切り、

<Client ID>:<Client Secret>

これをBase64エンコードしてヘッダーにすると出来上がり。 手軽なBase64エンコード処理をデフォルトのままで使い72文字で自動改行しないようご注意ください(泣)例:Mojo::Utilのb64_encode

Authorization: Basic <今Base64エンコードした奴>

フォームにフィールド名と内容を並べます。

  1. code <code>
  2. grant_type authorization_code
  3. redirect_uri <リダイレクト受付URL>
  4. code_berifier <ベリファイア>

次のURLにPOSTします。

https://api.twitter.com/2/oauth2/token

ツイッターの応答をステータスコードで確認、成功すればJSONで返り、失敗すればHTMLが返ります(これは経験談)。 JSONの中にあるrefresh_token(リフレッシュトークン)とaccess_token(アクセストークン)を取得して完了です。 リフレッシュトークンの取得に成功すればcodeとベリファイアは不要です。 リフレッシュトークンに有効期限はなく1回だけ使えます。 アクセストークンの有効期限は取得後2時間です。

最終的に手元にこれらが残り、使い続けます。 リフレッシュトークンとアクセストークンはリフレッシュで随時更新されます。

  1. <リダイレクト受付URL>
  2. Client ID
  3. Client Secret
  4. リフレッシュトークン
  5. アクセストークン

ツイートをJSONに入れて

{ "text": "<ツイート>" }

リクエストヘッダにアクセストークンを入れて

Authorization: Bearer <アクセストークン>

このURLにPOSTします。

https://api.twitter.com/2/tweets

レスポンスはJSONです。 ステータスコードでツイートの成否が分かります。 成功すればdataのidにツイートIDが入ります。 失敗すればdetailにメッセージが入ります。 アクセストークンが失効していた場合はステータスコードがエラーで返るのでアクセストークンをリフレッシュします。

フォームにフィールドを並べて

  1. refresh_token <リフレッシュトークン>
  2. grant_type refresh_token

リクエストヘッダにリフレッシュトークン取得と同じAuthorizationヘッダーを入れて

Authorization: Basic <リフレッシュトークン取得と同じ>

次のURLにPOSTします。

https://api.twitter.com/2/oauth2/token

ステータスコードで成功と判断した場合はレスポンスがJSONです。 JSONからrefresh_token(リフレッシュトークン)とaccess_token(アクセストークン)を取得します。 フォームに入れたリフレッシュトークンは失効しましたから、JSONに入っているリフレッシュトークンを残しましょう。