Twitter Mobile の GraphQL APIのメモ

Twitterのアーカイブをリクエスト( https://twitter.com/okuoku/status/1644011517531258880 )したらめっちゃ品質の良いアーカイブが来てちょっと不味いものを感じたので。。
今回は1日とかで来たけど、twilog亡き今、真面目な検索手法としてコレじつは有望なんではないか。。ただ1GiBとかの転送が各ユーザに掛かる(全mediaとか消したtweet等が含まれる)ので、あんまり酷使するとTwitterが破産しちゃうと思う。

Guest Token(gt) および APIマッピングの取得
Guest Token
非ログイン状態で https://mobile.twitter.com/okuoku のようにユーザ名のページにアクセスすると、Cookieとして払い出される。
Guest Tokenがどのようにexpireするのかは不明。
Bearer Token
これは main
に含まれている。今回は https://abs.twimg.com/responsive-web/client-web-legacy/main.686f535a.js だった。
... Twitterは長年このtokenを使いまわしており、検索すると大量の使用例がみつかる。
APIマッピング
Twitter mobileはWebPackされたPWAアプリなので、分割先のスクリプトの取得が必要。
今回は、 https://abs.twimg.com/responsive-web/client-web/api.1104a7aa.js だった。これの中身は
window.webpackChunk_twitter_responsive_web.filter(e => e[0][0] == "api")
let temp = window.webpackChunk_twitter_responsive_web.filter(e => e[0][0] == "api")[0]
let temp2 = {}
let ops = {}
Object.keys(temp[1]).forEach(k => {temp2[k] = {}; try {temp[1][k](temp2[k])} catch(e){}})
Object.keys(temp2).forEach(k => {if(temp2[k].exports && temp2[k].exports.queryId){ops[temp2[k].exports.operationName] = temp2[k].exports}})
のようにして、動作中のDOMから ops
に抽出できる。今回の場合、必要なのは UserTweetsAndReplies
なので、 ops.UserTweetsAndReplies
の内容:
{
"queryId": "_dEwIMW2hHUTejaIafUiLA",
"operationName": "UserTweetsAndReplies",
"operationType": "query",
"metadata": {
"featureSwitches": ["blue_business_profile_image_shape_enabled",
"responsive_web_graphql_exclude_directive_enabled",
"verified_phone_label_enabled",
"responsive_web_graphql_timeline_navigation_enabled",
"responsive_web_graphql_skip_user_profile_image_extensions_enabled",
"tweetypie_unmention_optimization_enabled", "vibe_api_enabled",
"responsive_web_edit_tweet_api_enabled",
"graphql_is_translatable_rweb_tweet_is_translatable_enabled",
"view_counts_everywhere_api_enabled",
"longform_notetweets_consumption_enabled",
"tweet_awards_web_tipping_enabled",
"freedom_of_speech_not_reach_fetch_enabled",
"standardized_nudges_misinfo",
"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled",
"interactive_text_enabled",
"responsive_web_text_conversations_enabled",
"longform_notetweets_richtext_consumption_enabled",
"responsive_web_enhance_cards_enabled"
]
}
}
が呼出しに必要ということになる。
パラメタとしては更に UserByScreenName
の出力も必要で、こちらは、
{
"queryId": "k26ASEiniqy4eXMdknTSoQ",
"operationName": "UserByScreenName",
"operationType": "query",
"metadata": {
"featureSwitches": ["blue_business_profile_image_shape_enabled",
"responsive_web_graphql_exclude_directive_enabled",
"verified_phone_label_enabled",
"responsive_web_graphql_skip_user_profile_image_extensions_enabled",
"responsive_web_graphql_timeline_navigation_enabled"
]
}
}
となっている。これらの内容も現状では固定されているようだ。