とあるアカウントをtwitter api v2 freeに移行することにしました。
(追記)OAuth 2.0の情報を加筆しました。
X(Twitter)の予約投稿ツールを開発しています。次のリンクから。
GASとTwitter Api(X API)で予約投稿ツールを作った!【PR】

【PR】twitter api v2 freeの機能を最大限、生かしたCraft Twixを開発しました。
画像複数投稿、動画投稿、ツリー投稿はもちろんWordPressの定期投稿、オリジナル機能搭載です。しかもライセンスはゆるく、転売・転載をしないことを条件に改変を自由としました。

興味ある方はこちらの記事をみてください!
経緯。
Craft Twixと他のツール比較記事。
CraftTwix(クラフトツイックス)の販売を開始しました。
Twitter Api v2のfreeの移行方法【X API】
(追記)移行方法が少し変わったため、その変更点を反映させたものをQiitaに寄稿しました。この記事は細かいエラーなどの対応を残しておきます。
Twitterのアカウントを紐づけるものに切り替えておきます。
- 画面上の[ 開発者ポータル ]
- Twitterでログイン
- 画面下の[ Sign up for Free Account ]
- 次の画面の入力をこなして登録完了です。
Describe all of your use cases of Twitter’s data and API:
Twitter APIとデータの使い方をすべて説明してと言っていますね。250字以上らしいです。例文はこちらの記事に記載しています。
次の3つはチェックボックスをチェックするだけです。
You understand that you may not resell anything you receive via the Twitter APIs
Twitter APIで受け取ったものを再販してはダメのようですね。
You understand your Developer account may be terminated if you violate the Developer Agreement or any of the Incorporated Developer Terms
violate(違反)したらterminated(オワコン)だよと言っていますね。
You accept the Terms & Conditions
利用規約に同意する
[Submit] をおします。
既にTwitter Apiを利用している人
既にAPIを使っていた人はここからスタートできます。個人的にv1からの利用者です。まずはTwitter Developersにアクセス。
Add Projectから作るとv2が作れましたね。昔作ったアプリは放置のまま、新規で作成する方法を探しましたが、昔作ったアプリがある場合は新規のアプリは作れません。途中までできます。
アプリが作れない
Standalone Appsは今まで作ったアプリです。
v2のアプリは1つです。どうやらv1のアプリもカウントされているらしく、Standalone Appsがあると新しいアプリが作れません。[Create new]がグレーになっています。
アプリを消して作るしかなさそうです。
古いアプリの削除(必要なら)
次の操作をすると新しいアプリが作れるようになります。free版は1つしかアプリを作れません。
画面左から古いアプリを選択 > Delete APP > アプリ名を入力、[Delete APP]のボタンおす
新しいプロジェクトやアプリの削除(必要なら)
登録時に自動的にプロジェクトやアプリが生成されてしまう場合があるようです。名前なども適当なため、一度削除してやりなおしてもいいかもしれません。
画面左からアプリを選択 > Edit > Delete APP > アプリ名を入力、[Delete APP]のボタンおす
画面左からプロジェクトを選択 > Setting > Edit > [Delete Project]のボタンおす
プロジェクトの作成
Progects & Apps > Overview > + Add Project > Progect nameを設定してNext > Uses caseを設定してNext(botの場合はmake a bot) > Project description、プロジェクトの詳細を書いてNext > Create new
プロジェクトの詳細はWordPress to Tweetなど簡単に書けばいいです。この項目は文字数が少ないとダメはないようです。
引用先の記事を参考にしました。ありがとうございます。画像つきで解説されています。
Under the Elevated Section, click the “+ Add Project” button to add a new project.
https://docs.ultimatemember.com/article/1699-social-login-twitter-api-v2-setup
アプリの作成、apiキーの取得
- + Add App
- Development Staging, Productionのいずれか選択してNext(テスト用だったのでDevelopment を選ぶ)
- アプリ名を入れてNext。同じ名前はダメのようです。サイト名+tweetにしておきましょうか。
- API Key と API Secret Key、Bearer Tokenが表示されます。
keyはそのときしか見れないようなので、忘れずめもします。忘れた場合、キーを再生成しないといけません。
アプリの作成は回数制限があるようです。何度も作成すると24時間待たされることになります。
keyの再生成
なお、keyは次から再生成できるようです。
画面左の[アプリ名] > Regenerate
アクセストクーンの生成
gasなどを使う場合はアクセストクーンも生成します。
画面左からアプリを選択 > Access Token and Secretの[ Generate ] > コピーしてめもる > Yes, I saved them.
読み込みと書き込み設定
画面左の[アプリ名] > Set Up
アプリにより違いますが、botの場合、想定で設定をします。
ツイートは書き込みが必要なのでRead and Writeにします。
- Read and Wirte
- Web App, Automated App or Bot
- Callback URI / Redirect URL 自サイトのurl(Twitterのurlでもよい、開発でcallbackを使用する場合は後ほど書き換えます)
- Website URL 自サイトのurl(Twitterのurlでもよい)
最後に[save]をおします。OAuth 2.0 クライアント ID とクライアント シークレットが表示されます。
Done > Yes, I saved it.
Keys and tokensを確認すると、OAuth 2.0 クライアント ID とクライアント シークレットが増えています。
Twitter API v2のfreeは審査はいる?
TwitterAPI、free planなら審査無し即時で取れるのか(電話番号必須)
— カンバラ | Webエンジニア (@kambara_eg) April 5, 2023
そしてfreeだと月に1500投稿までか〜
🚨 開発者アカウントの申請が過去数か月間審査中だった場合、新しい Twitter API Free または Basic プランへの登録に関心がある場合は、再度申請してください。
— tech特定語句翻訳Bot (@translation_ja) April 4, 2023
新しいセルフサービス プロセスにより、いつでもアクセスできるようになります。 🙏
#api https://t.co/X8WIKIbNqh
Suspendされたら、ダウングレードで回避!?
ログインの件、この通りだったようです。
— teckl (@teckl) April 27, 2023
複数Twitterアプリを持ってると内部的に強制的にBasicプランにさせられる。(が、支払い情報が無いためずにSuspendされる)
このため、Twitter API v2ページから、必要なアプリを一つだけにしてDowngradeしてFreeプランへ変更が必要https://t.co/AF6VZ7lgBf
free版はbotしか作れない!?他人のツイートは取得不可?
TwitterAPIのFreeってエンドポイントが自分のツイートの取得、投稿、削除しかできねぇのか
— 𓆲辺境領主𓆲🌩️ (@glorificatio) March 31, 2023
自動投稿BOTしか作れないじゃん
人口無能的な簡単なアカウントですら月額100ドル払わないといけないの?
うわぁ、個人開発のアプリケーションはもう畳まないとダメだな
TwitterAPI昔ちょっと触ってたけどあの頃作ったアプリもう動かんなこれ
— ろうくろ (@Okaka696) April 3, 2023
freeだと他人のツイートすら取得できないって正気か?そのプラン存在意義ある?最低額プランでもいちまんえんするしよ
他人のアカウントができないっていうのはサービスによっては厳しいですね。
free版でダイレクトメッセージはできる!?
できないようですね。まあ、これは迷惑メールが減るのでいいことかもですけど。
ツイートのリンク先は登録している人しか確認できません。
Twitter API v2のBasic API(有料)の中にDMの処理があって、Freeの方にはないので 3rdパーティー経由の利用だとDM有料化って流れなのかなって思ったんだけどhttps://t.co/Dxoiq0sdd6
— popo🦌 (@po3515) March 30, 2023
v2にメディアのアップロード、画像添付はない?
まだ昔のものしかないようです。。
真面目なのでTwitterAPI v2の公式ドキュメント読んでるけど、いま時点で media/upload がcoming soonなことに気づいてしまった。。。現状同endpointを提供している v1.1 は4/30で停止ってアナウンス出てるのだが?
— 𖡶tana_bataᔦꙬᔨ (@tana_bata) April 13, 2023
実装は後回しですかね…。
また、Twitterのぐだぐだなのでしょうか。。
さてTwitter APIいよいよ止まるか?v2 MediaはいまだにCOMING SOONだし、statuses/oembedも検討中だし、引き続き今後の動きに注視必要。https://t.co/LowANLg0lT
— SiRO@個人開発 (@codemesi) April 29, 2023
この日付でもできていないよう。できていないのに止めるのは破綻なので、延長なのでしょうか。
古いapiはまだ動いていますね。
(後日談)画像アップロードも実装しました。
Twitter Api v2のOAuth 1.0aとOAuth 2.0の違い【X API】
OAuth 2.0でどのアクセストクーンが必要か?
最新の情報はこちらを見た方がよさそうです。
OAuth 2.0に完全移行すると、一部APIキーがいらなくなりますかね。
複数の情報源から次のように読み解きました。
キー名 | 用途・役割 | v1.1 (OAuth 1.0a)での使用 | v2 (OAuth 2.0)での使用 | 備考 |
---|---|---|---|---|
Consumer API Key | アプリケーションの識別。リクエストの署名に利用 | 必須(ユーザー認証やリクエスト署名に使用) | 不要 | v2では Client ID に置き換えられる |
Consumer API Secret | アプリケーション認証用の秘密鍵 | 必須(署名に使用) | 不要 | v2では Client Secret が使用される |
Client ID | OAuth 2.0認証におけるアプリ識別 | ― | 必須 | OAuth 2.0 PKCEフローでユーザーアクセストークン取得に利用 |
Client Secret | OAuth 2.0認証でのアプリ認証用秘密鍵 | ― | 必要(※confidentialクライアントの場合) | パブリッククライアントの場合は不要な場合もある |
Bearer Token | アプリ単独認証用トークン(App-only認証) | 読み取り専用エンドポイントで利用可能 | ユーザー操作には不要 ※読み取り専用の場合は利用可能 | ユーザーの投稿などには、動的に発行されるユーザーアクセストークンを使用 |
Access Token | ユーザー認証の証明(ユーザー操作用) | 必須 | 不要 | OAuth 2.0 PKCEでは動的に取得されるため固定トークンは発行されない |
Access Token Secret | Access Token と対になる秘密鍵 | 必須 | 不要 | OAuth 2.0ではリクエスト署名に秘密鍵が不要 |
Bearer Token(ベアラートークン)は必要か?
Bearer Tokenはリファレンスをみると読み取り専用のことはすぐわかります。
This method is for developers that just need read-only access to public information.
https://docs.x.com/resources/fundamentals/authentication/oauth-2-0/application-only
そして、少し意味が読みとりにくいかもしれませんが、次の文章で補足されています。
Please note that only OAuth 1.0a or OAuth 2.0 Authorization Code Flow with PKCE is required to issues requests on behalf of users. The API reference page describes the authentication method required to use an API. You will need user-authentication, user-context, with an access token to perform the following:
https://docs.x.com/resources/fundamentals/authentication/oauth-2-0/application-only
Post Tweets or other resources
こちらは文脈から判断するとBearer Tokenではなく、OAuth 2.0を使いましょうと案内されています。つまり、OAuth 2.0のClient IDと Client Secretを使いましょうと文章をよみとけます。OAuth 1.0aも触れられていますが、今から採用するのは古いため避けるべきでしょう。
「user-context(ユーザーコンテキスト)」はユーザーの代わりに行動する意味。簡単にいえば「ユーザー操作」と理解でもいいでしょう。
No user-context
When issuing requests using application-only auth, there is no concept of a “current user”. Therefore, endpoints such as POST statuses/update will not function with application-only auth. See using OAuth for more information for issuing requests on behalf of a user.
そしてBearer TokenはNo user-context。「現在のユーザー」という概念はありませんと明示しています。
Bearer Token(ベアラートークン)はApplication-only authentication(アプリケーション専用認証)の一部として使用され、主に公開情報の取得に使われます。たとえば、一般的な検索や公開ツイートの取得などに使用されます。 書き込み専用のアプリにはいらないですが、そのような拡張をする場合や仕様変更に備えてAPIキーは全部いれておく方が安全策という気がします。逆にしばらく使う予定がなければ外せばいいでしょう。
Access TokenとAccess Token Secret
Access TokenとAccess Token Secretは、OAuth 1.0aの認証に必要。V2はいりません。 OAuth 1.0aを使うとTwitter API1.1を利用できて、メディアのアップロードで画像投稿ができます! 今はメディアのアップロード以外で使いません!
OAuth 2.0でいらなくなるコードたち
まずはこれでしょう。
//----------------------------------------------------------------------'
// X API V1の基本処理(画像投稿、ツリー投稿用)
//----------------------------------------------------------------------'
function getService1() {
debugLog('getService1')
const scriptProps = PropertiesService.getScriptProperties();
const TWITTER_CONSUMER_API_KEY = scriptProps.getProperty('TWITTER_CONSUMER_API_KEY');
const TWITTER_CONSUMER_API_SECRET = scriptProps.getProperty('TWITTER_CONSUMER_API_SECRET');
const TWITTER_ACCESS_TOKEN = scriptProps.getProperty('TWITTER_ACCESS_TOKEN');
const TWITTER_ACCESS_TOKEN_SECRET = scriptProps.getProperty('TWITTER_ACCESS_TOKEN_SECRET');
const service = OAuth1.createService('twitter1')
.setAccessTokenUrl('https://api.twitter.com/oauth/access_token')
.setRequestTokenUrl('https://api.twitter.com/oauth/request_token')
.setAuthorizationUrl('https://api.twitter.com/oauth/authorize')
.setConsumerKey( TWITTER_CONSUMER_API_KEY )
.setConsumerSecret( TWITTER_CONSUMER_API_SECRET )
.setAccessToken( TWITTER_ACCESS_TOKEN, TWITTER_ACCESS_TOKEN_SECRET )
.setCallbackFunction('authCallback')
// .setPropertyStore(PropertiesService.getUserProperties());
return service
}
こちらも工夫次第で外せますね。
function pkceChallengeVerifier() {
debugLog('pkceChallengeVerifier')
var userProps = PropertiesService.getUserProperties();
if (!userProps.getProperty('code_verifier')) {
var verifier = '';
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
for (var i = 0; i < 128; i++) {
verifier += possible.charAt(Math.floor(Math.random() * possible.length));
}
var sha256Hash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, verifier)
var challenge = Utilities.base64Encode(sha256Hash)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '')
userProps.setProperty('code_verifier', verifier)
userProps.setProperty('code_challenge', challenge)
}
}
// pkceChallengeVerifier(); // .generateCodeVerifier()を使用するため不要
return OAuth2.createService('twitter')
.setAuthorizationBaseUrl("https://x.com/i/oauth2/authorize")
.setTokenUrl("https://api.x.com/2/oauth2/token")
// .setParam('grant_type','authorization_code') // .generateCodeVerifier()を使用するため不要
// .setParam('code_verifier', userProps.getProperty('code_verifier')) // .generateCodeVerifier()を使用するため不要
.setClientId(TWITTER_CLIENT_ID)
.setClientSecret(TWITTER_CLIENT_SECRET)
.setRedirectUri(REDIRECT_URI)
.setCallbackFunction('auth2Callback')
.setPropertyStore(PropertiesService.getUserProperties())
.setScope("tweet.write tweet.read media.write users.read offline.access")
.generateCodeVerifier() // code_verifierとcode_challengeを自動生成・管理
.setTokenHeaders({
'Authorization': 'Basic ' + Utilities.base64Encode(TWITTER_CLIENT_ID + ':' + TWITTER_CLIENT_SECRET),
'Content-Type': 'application/x-www-form-urlencoded'
})
// .setParam('response_type', 'code')
// .setParam('code_challenge_method', 'S256') // .generateCodeVerifier()を使用するため不要
// .setParam('code_challenge', userProps.getProperty('code_challenge')) // .generateCodeVerifier()を使用するため不要
シンプルにできるはず。
// const twitterKeys = [
// 'TWITTER_CONSUMER_API_KEY',
// 'TWITTER_CONSUMER_API_SECRET',
// 'TWITTER_CLIENT_ID',
// 'TWITTER_CLIENT_SECRET',
// 'TWITTER_BEARER_TOKEN',
// 'TWITTER_ACCESS_TOKEN',
// 'TWITTER_ACCESS_TOKEN_SECRET'
// ];
const twitterKeys = [
'TWITTER_CLIENT_ID',
'TWITTER_CLIENT_SECRET',
];
X(Twitter)の予約投稿ツールを開発しています。次のリンクから。
以下は昔の申請方法です。参考程度に残しておきます。
Twitter APIのエラー【X API】
api.x.com/2/tweetsのエラー
念の為、テストしましたが、今だエンドポイントはapi.twitter.comですね。api.x.com/では動作しません。2025年3月時点。
// const TWITTER_API_ENDPOINT2 = 'https://api.x.com/2/tweets';
const TWITTER_API_ENDPOINT2 = 'https://api.twitter.com/2/tweets';
When authenticating requests to the Twitter API v2 endpoints, you must use keys and tokens from a Twitter developer App that is attached to a Project
先日まで動いていたのに突然動かなくなりました。。
When authenticating requests to the Twitter API v2 endpoints, you must use keys and tokens from a Twitter developer App that is attached to a Project
Twitterで同じような人がいました。
Twitter API 開発者向け情報。
— あもん (@amotarao) June 16, 2023
When authenticating requests to the Twitter API v2 endpoints, you must use keys and tokens from a Twitter developer App that is attached to a Project. You can create a project via the developer portal.
自サービス @yukukuruapp で 6/16 0:00 JST…
Standalone App に変更されているよう。何ゆえ?
Add app > Add an existing App > アプリを選ぶ > next
でなおったけど、ちょっと怖いなあ。ただのTwitter社のミスかなあ。審査をはじめるとか、Twitter APIの仕様の改悪はなしで…お願いしますよ。。
新規作成!電話番号が追加できない
(追記)今は電話番号なしにいけるようです。前に作ったとき、トラブルがありました。だからわかりませんが、辞めたのでしょうか。一応、覚書程度に残しておきます。
新規で作る場合は登録作業がいるようです。
Sign up for Free Account
Sign up for Free Account がクリックできない場合は電話番号の登録が事前に必要です。
しかし、電話番号を追加しようとするとエラーになりますね。普通にTwitterのアカウントからいっても一緒です。
設定サポート > 設定プライバシー > アカウント > アカウント情報 >電話番号
一時のものなのでしょうか。
エラー
問題が発生しました。しばらくしてからやりなおしてください。
しょうがないので、すでにアプリ追加済の既存のアカウントから調整することにしました。プログラミングのテストをしたかっただけなので、どのアカウントでもよかったのです。
コメント