From 53b96effe6ddf6480effc02bc2047f61fd3f99fa Mon Sep 17 00:00:00 2001 From: trevorhobenshield Date: Sat, 11 Mar 2023 10:48:57 -0800 Subject: [PATCH] update --- readme.md | 53 + src/config/__init__.py | 0 src/config/operations.py | 3159 +++++++++++++++++++++++++++++++ src/config/update_operations.py | 75 + src/log/__init__.py | 0 src/log/config.py | 40 + src/login.py | 89 + src/main.py | 590 ++++++ src/utils.py | 26 + 9 files changed, 4032 insertions(+) create mode 100644 readme.md create mode 100644 src/config/__init__.py create mode 100644 src/config/operations.py create mode 100644 src/config/update_operations.py create mode 100644 src/log/__init__.py create mode 100644 src/log/config.py create mode 100644 src/login.py create mode 100644 src/main.py create mode 100644 src/utils.py diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..6769a5a --- /dev/null +++ b/readme.md @@ -0,0 +1,53 @@ +**(Work in Progress)** Complete implementation of the undocumented Twitter API + +- Written very quickly, crude, needs refactoring/redesign + + +```bash +pip install twitter-api-client +``` + +### Usage +```python +from src.main import * + +usr, pwd = ..., ... +session = login(usr, pwd) + +# create tweet with images, videos, gifs, and tagged users +r = create_tweet('test 123', session, media=[{'file': 'image.jpeg', 'tagged_users': [123234345456], 'alt': 'some image'}]) +r = create_tweet('test 123', session, media=['test.jpg', 'test.png']) +r = create_tweet('test 123', session, media=['test.mp4']) +r = create_tweet('test 123', session) + +r = delete_tweet(123, session) + +# delete all tweets in account +r = delete_all_tweets(456, session) + +r = retweet(1633609779745820675, session) +r = unretweet(1633609779745820675, session) + +r = quote('test 123', 'elonmusk', 1633609779745820675, session) +r = comment('test 123', 1633609779745820675, session) + +r = unlike_tweet(1633609779745820675, session) +r = like_tweet(1633609779745820675, session) + +r = follow(50393960, session) +r = unfollow(50393960, session) + +r = mute(50393960, session) +r = unmute(50393960, session) + +r = enable_notifications(50393960, session) +r = disable_notifications(50393960, session) + +r = block(50393960, session) +r = unblock(50393960, session) + +# some hidden user attribute? +r = stats(50393960, session) + +``` + diff --git a/src/config/__init__.py b/src/config/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/config/operations.py b/src/config/operations.py new file mode 100644 index 0000000..da3e781 --- /dev/null +++ b/src/config/operations.py @@ -0,0 +1,3159 @@ +operations = { + "adFreeArticleDomains": { + "queryId": "zwTrX9CtnMvWlBXjsx95RQ", + "variables": {}, + "features": {} + }, + "articleNudgeDomains": { + "queryId": "88Bu08U2ddaVVjKmmXjVYg", + "variables": {}, + "features": {} + }, + "ArticleTimeline": { + "queryId": "W1z1htHs9h4ru8SakhgqYw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "ArticleTweetsTimeline": { + "queryId": "iVzorsgswtr8J7g6JJqTIQ", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "AudioSpaceById": { + "queryId": "LteLU4uHTpSNobexxKBO6g", + "variables": {}, + "features": { + "spaces_2022_h2_clipping": True, + "spaces_2022_h2_spaces_communities": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "AudioSpaceSearch": { + "queryId": "NTq79TuSz6fHj8lQaferJw", + "variables": {}, + "features": {} + }, + "getAltTextPromptPreference": { + "queryId": "PFIxTk8owMoZgiMccP0r4g", + "variables": {}, + "features": {} + }, + "updateAltTextPromptPreference": { + "queryId": "aQKrduk_DA46XfOQDkcEng", + "variables": {}, + "features": {} + }, + "getCaptionsAlwaysDisplayPreference": { + "queryId": "BwgMOGpOViDS0ri7VUgglg", + "variables": {}, + "features": {} + }, + "updateCaptionsAlwaysDisplayPreference": { + "queryId": "uCUQhvZ5sJ9qHinRp6CFlQ", + "variables": {}, + "features": {} + }, + "AuthenticatedUserTFLists": { + "queryId": "QjN8ZdavFDqxUjNn3r9cig", + "variables": {}, + "features": {} + }, + "BirdwatchAliasSelect": { + "queryId": "3ss48WFwGokBH_gj8t_8aQ", + "variables": {}, + "features": {} + }, + "BirdwatchFetchContributorNotesSlice": { + "queryId": "mIXxHndBm97VfcNYccuukw", + "variables": {}, + "features": { + "responsive_web_graphql_timeline_navigation_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "BirdwatchCreateAppeal": { + "queryId": "TKdL0YFsX4DMOpMKeneLvA", + "variables": {}, + "features": {} + }, + "BirdwatchCreateNote": { + "queryId": "0fOzFT_8za8AUyJv3pERkA", + "variables": {}, + "features": { + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True + } + }, + "BirdwatchCreateRating": { + "queryId": "xWLuzZoATvfEIEGxnsLt7w", + "variables": {}, + "features": {} + }, + "BirdwatchDeleteNote": { + "queryId": "IKS_qrShkDyor6Ri1ahd9g", + "variables": {}, + "features": {} + }, + "BirdwatchDeleteRating": { + "queryId": "OpvCOyOoQClUND66zDzrnA", + "variables": {}, + "features": {} + }, + "BirdwatchEditNotificationSettings": { + "queryId": "FLgLReVIssXjB_ui3wcrRQ", + "variables": {}, + "features": {} + }, + "BirdwatchFetchAliasSelfSelectOptions": { + "queryId": "szoXMke8AZOErso908iglw", + "variables": {}, + "features": {} + }, + "BirdwatchFetchAliasSelfSelectStatus": { + "queryId": "LUEdtkcpBlGktUtms4BvwA", + "variables": {}, + "features": {} + }, + "BirdwatchFetchAuthenticatedUserProfile": { + "queryId": "pMbW6Y4LuS5MzlSOEqERJQ", + "variables": {}, + "features": {} + }, + "BirdwatchFetchBirdwatchProfile": { + "queryId": "btgGtchypc3D491MJ7XXWA", + "variables": {}, + "features": {} + }, + "BirdwatchFetchGlobalTimeline": { + "queryId": "SQfYgFHuQlKtVeLz1NkaqA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "BirdwatchFetchNotes": { + "queryId": "-pJbOdvuR19SngusywIjRA", + "variables": {}, + "features": { + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True + } + }, + "BirdwatchFetchOneNote": { + "queryId": "LT8P2AoBObbK2tQL75vwPA", + "variables": {}, + "features": { + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True + } + }, + "BirdwatchFetchPublicData": { + "queryId": "9bDdJ6AL26RLkcUShEcF-A", + "variables": {}, + "features": {} + }, + "BirdwatchProfileAcknowledgeEarnOut": { + "queryId": "cED9wJy8Nd1kZCCYuIq9zQ", + "variables": {}, + "features": {} + }, + "BizProfileFetchUser": { + "queryId": "6OFpJ3TH3p8JpwOSgfgyhg", + "variables": {}, + "features": {} + }, + "BlockedAccountsAll": { + "queryId": "HbDY9-1fVikEj9wOirxyxA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "BlockedAccountsAutoBlock": { + "queryId": "T4QVCFXTSKXAX8wBkBK-ag", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "BlockedAccountsImported": { + "queryId": "BpHrU2AZLU-fgy0pqHWjng", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "BookmarkFolderTimeline": { + "queryId": "a2wY9S9Ez1VE6_2KVKAIDA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "BookmarkFoldersSlice": { + "queryId": "i78YDd0Tza-dV4SYs58kRg", + "variables": {}, + "features": {} + }, + "bookmarkTweetToFolder": { + "queryId": "4KHZvvNbHNf07bsgnL9gWA", + "variables": {}, + "features": {} + }, + "Bookmarks": { + "queryId": "HnZOTwULzK8gojG2upOHOA", + "variables": {}, + "features": { + "graphql_timeline_v2_bookmark_timeline": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "CardPreviewByTweetText": { + "queryId": "mDT5pi--P4qMjgtOPDN1Fw", + "variables": {}, + "features": { + "responsive_web_enhance_cards_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CheckTweetForNudge": { + "queryId": "C2dcvh7H69JALtomErxWlA", + "variables": {}, + "features": { + "standardized_nudges_toxicity": True + } + }, + "CombinedLists": { + "queryId": "SUxXZi0bXEkOOyVNfy-PWw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "CommunitiesMainDiscoveryModule": { + "queryId": "jNPyfv5EX_uQeaMonzsQjw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "CommunitiesMainPageTimeline": { + "queryId": "9NSoMSUeACwllJ12VG4yJQ", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "CommunitiesMembershipsSlice": { + "queryId": "oGlWHAR0sUlzCexh6AuAiw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CommunitiesMembershipsTimeline": { + "queryId": "OOJY08fdmM1M37NUwYy58g", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "CommunityAboutTimeline": { + "queryId": "BMongINo1Q1WVusV2WfOFA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "CreateCommunity": { + "queryId": "FRwKGFOc5TketEaA8am7pA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CommunityCreateRule": { + "queryId": "oP6AkKK7cj6f2DcKNxoRlQ", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CommunityDiscoveryTimeline": { + "queryId": "dnJxTUqEYiBYmHnEeiQgYQ", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "CommunityEditBannerMedia": { + "queryId": "PZNCgKSCnONh2jsgN-k0_A", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CommunityEditName": { + "queryId": "kn6YYszpnCudapuWHGxnkg", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CommunityEditPurpose": { + "queryId": "uuOoZHAHPWv1_V8k998eZg", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CommunityEditRule": { + "queryId": "5V5kR0PJpOSlo1IZHHC4CQ", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CommunityEditTheme": { + "queryId": "tFy6WYNhA-KWvlF29JN3ZA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CommunityByRestId": { + "queryId": "RTazUCzfsW4JAAho85cyFA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CommunityHashtagsTimeline": { + "queryId": "fACvkGDZbhOlpmpgsxnLfA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "JoinCommunity": { + "queryId": "n7b-wm-4reLhE-pA0W_PMQ", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "LeaveCommunity": { + "queryId": "zZT5owXUfqlc-bBDulvUcA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CommunityMemberRelationshipTypeahead": { + "queryId": "npEFiYc3sCX-YDHZ1B69nw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True + } + }, + "CommunityModerationKeepTweet": { + "queryId": "rQAQ-rOuZ5Rco0BX_04PvQ", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CommunityModerationTweetCasesSlice": { + "queryId": "UZX0jK5-lu00iwnhKW0UNQ", + "variables": {}, + "features": { + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "CommunityRemoveBannerMedia": { + "queryId": "wntlkO39ggnplYowqbbSvw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CommunityRemoveRule": { + "queryId": "SmX6I1rX0PyvsEcE-8Y-LA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CommunityReorderRules": { + "queryId": "SlND0s8g7vaWfR5bomaWiQ", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "RequestToJoinCommunity": { + "queryId": "fxoBRimnPBZde7Jy7oX8Vg", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CommunityTweetsRankedTimeline": { + "queryId": "um0FTQcrthAVr6X_50O5Qw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "CommunityTweetsTimeline": { + "queryId": "pJHAToy6j1znp36NntvwDA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "CommunityUpdateRole": { + "queryId": "--KsROq_U4xbD_wd0ILuzg", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CommunityUserInvite": { + "queryId": "el2xSrgrXBxyWvbz193qaA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True + } + }, + "CommunityUserRelationshipTypeahead": { + "queryId": "C9CUCfAvlaMEhJBmM2hZkg", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True + } + }, + "ConnectTabTimeline": { + "queryId": "vtzw9bIas-AhHgJTnYih-A", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "ConversationControlChange": { + "queryId": "hb1elGcj6769uT8qVYqtjw", + "variables": {}, + "features": {} + }, + "ConversationControlDelete": { + "queryId": "OoMO_aSZ1ZXjegeamF9QmA", + "variables": {}, + "features": {} + }, + "ConvertRitoSuggestedActions": { + "queryId": "2njnYoE69O2jdUM7KMEnDw", + "variables": {}, + "features": {} + }, + "CreateBookmark": { + "queryId": "aoDbu3RHznuiSkQ9aNM67Q", + "variables": {}, + "features": {} + }, + "createBookmarkFolder": { + "queryId": "6Xxqpq8TM_CREYiuof_h5w", + "variables": {}, + "features": {} + }, + "CreateCustomerPortalSession": { + "queryId": "2LHXrd1uYeaMWhciZgPZFw", + "variables": {}, + "features": {} + }, + "CreateDraftTweet": { + "queryId": "cH9HZWz_EW9gnswvA4ZRiQ", + "variables": {}, + "features": {} + }, + "CreateNoteTweet": { + "queryId": "Pyx6nga4XtTVhfTh1gtX1A", + "variables": {}, + "features": { + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "CreateRetweet": { + "queryId": "ojPdsZsimiJrUGLR1sjUtA", + "variables": { + "tweet_id": None, + "dark_request": False + }, + "features": {} + }, + "CreateScheduledTweet": { + "queryId": "LCVzRQGxOaGnOnYH01NQXg", + "variables": { + "post_tweet_request": { + "auto_populate_reply_metadata": False, + "status": None, + "exclude_reply_user_ids": [], + "media_ids": [ + None + ] + }, + "execute_at": None + }, + "features": {} + }, + "CreateTrustedFriendsList": { + "queryId": "2tP8XUYeLHKjq5RHvuvpZw", + "variables": {}, + "features": {} + }, + "CreateTweet": { + "queryId": "t16L8hse5wgpc4iKx4p3zw", + "variables": { + "tweet_text": None, + "dark_request": False, + "media": { + "media_entities": [], + "possibly_sensitive": False + }, + "withDownvotePerspective": False, + "withReactionsMetadata": False, + "withReactionsPerspective": False, + "withSuperFollowsTweetFields": True, + "withSuperFollowsUserFields": True, + "semantic_annotation_ids": [] + }, + "features": { + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": False, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": False, + "longform_notetweets_richtext_consumption_enabled": False, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": False, + "freedom_of_speech_not_reach_fetch_enabled": False, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": False, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": False, + "responsive_web_enhance_cards_enabled": False + } + }, + "CreateTweetDownvote": { + "queryId": "Eo65jl-gww30avDgrXvhUA", + "variables": {}, + "features": {} + }, + "CreateTweetReaction": { + "queryId": "D7M6X3h4-mJE8UB1Ap3_dQ", + "variables": {}, + "features": {} + }, + "DataSaverMode": { + "queryId": "xF6sXnKJfS2AOylzxRjf6A", + "variables": { + "device_id": "Linux/Chrome" + }, + "features": {} + }, + "WriteDataSaverPreferences": { + "queryId": "H03etWvZGz41YASxAU2YPg", + "variables": {}, + "features": {} + }, + "SetDefault": { + "queryId": "QEMLEzEMzoPNbeauKCCLbg", + "variables": {}, + "features": {} + }, + "BookmarksAllDelete": { + "queryId": "skiACZKC1GDYli-M8RzEPQ", + "variables": {}, + "features": {} + }, + "DeleteBookmark": { + "queryId": "Wlmlj2-xzyS1GN3a6cj-mQ", + "variables": {}, + "features": {} + }, + "DeleteBookmarkFolder": { + "queryId": "2UTTsO-6zs93XqlEUZPsSg", + "variables": {}, + "features": {} + }, + "DeleteDraftTweet": { + "queryId": "bkh9G3FGgTldS9iTKWWYYw", + "variables": {}, + "features": {} + }, + "DeletePaymentMethod": { + "queryId": "VaaLGwK5KNLoc7wsOmp4uw", + "variables": {}, + "features": {} + }, + "DeleteRetweet": { + "queryId": "iQtK4dl5hBmXewYZuEOKVw", + "variables": { + "source_tweet_id": None, + "dark_request": False + }, + "features": {} + }, + "DeleteScheduledTweet": { + "queryId": "CTOVqej0JBXAZSwkp1US0g", + "variables": {}, + "features": {} + }, + "DeleteTweet": { + "variables": { + "tweet_id": "1633699974079983616", + "dark_request": False + }, + "queryId": "VaenaVgh5q5ih7kvyVjgtg", + "features": {} + }, + "DeleteTweetDownvote": { + "queryId": "VNEvEGXaUAMfiExP8Tbezw", + "variables": {}, + "features": {} + }, + "DeleteTweetReaction": { + "queryId": "GKwK0Rj4EdkfwdHQMZTpuw", + "variables": {}, + "features": {} + }, + "DisableUserAccountLabel": { + "queryId": "_ckHEj05gan2VfNHG6thBA", + "variables": {}, + "features": {} + }, + "DisableVerifiedPhoneLabel": { + "queryId": "g2m0pAOamawNtVIfjXNMJg", + "variables": {}, + "features": {} + }, + "DismissRitoSuggestedAction": { + "queryId": "jYvwa61cv3NwNP24iUru6g", + "variables": {}, + "features": {} + }, + "DmAllSearchSlice": { + "queryId": "O9Sqb8IjJhtK7gzfUs5eyw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "DmGroupSearchSlice": { + "queryId": "5zpY1dCR-8NyxQJS_CFJoQ", + "variables": {}, + "features": {} + }, + "DmMutedTimeline": { + "queryId": "L7tN_77Tk950tMAy7sFCkA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "DmNsfwMediaFilterUpdate": { + "queryId": "of_N6O33zfyD4qsFJMYFxA", + "variables": {}, + "features": {} + }, + "DmPeopleSearchSlice": { + "queryId": "xYSm8m5kJnzm_gFCn5GH-w", + "variables": {}, + "features": {} + }, + "EditBookmarkFolder": { + "queryId": "a6kPp1cS1Dgbsjhapz1PNw", + "variables": {}, + "features": {} + }, + "EditDraftTweet": { + "queryId": "JIeXE-I6BZXHfxsgOkyHYQ", + "variables": {}, + "features": {} + }, + "EditScheduledTweet": { + "queryId": "_mHkQ5LHpRRjSXKOcG6eZw", + "variables": {}, + "features": {} + }, + "WriteEmailNotificationSettings": { + "queryId": "2qKKYFQift8p5-J1k6kqxQ", + "variables": {}, + "features": {} + }, + "EnableLoggedOutWebNotifications": { + "queryId": "BqIHKmwZKtiUBPi07jKctg", + "variables": {}, + "features": {} + }, + "EnableVerifiedPhoneLabel": { + "queryId": "C3RJFfMsb_KcEytpKmRRkw", + "variables": {}, + "features": {} + }, + "FavoriteTweet": { + "queryId": "lI07N6Otwv1PhnEgXILM7A", + "variables": { + "tweet_id": None + }, + "features": {} + }, + "Favoriters": { + "queryId": "XRRjv1-uj1HZn3o324etOQ", + "variables": { + "tweetId": None, + "count": 1000, + "includePromotedContent": True, + "withSuperFollowsUserFields": True, + "withDownvotePerspective": False, + "withReactionsMetadata": False, + "withReactionsPerspective": False, + "withSuperFollowsTweetFields": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "FeatureSettingsUpdate": { + "queryId": "-btar_vkBwWA7s3YWfp_9g", + "variables": {}, + "features": {} + }, + "Followers": { + "queryId": "pd8Tt1qUz1YWrICegqZ8cw", + "variables": { + "userId": None, + "count": 1000, + "includePromotedContent": True, + "withDownvotePerspective": False, + "withReactionsMetadata": False, + "withReactionsPerspective": False, + "withSuperFollowsTweetFields": True, + "withSuperFollowsUserFields": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "FollowersYouKnow": { + "queryId": "95iQJXlI0_dFs_Ni6Ann9Q", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "Following": { + "queryId": "wjvx62Hye2dGVvnvVco0xA", + "variables": { + "userId": None, + "count": 1000, + "includePromotedContent": True, + "withDownvotePerspective": False, + "withReactionsMetadata": False, + "withReactionsPerspective": False, + "withSuperFollowsTweetFields": True, + "withSuperFollowsUserFields": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "ForYouExplore": { + "queryId": "wVEXnyTWzQlEsIuLq_D3tw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "GenericTimelineById": { + "queryId": "K3sJPgCxVJWZSc9jyJJXsA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "GraphQLError": { + "queryId": "2V2W3HIBuMW83vEMtfo_Rg", + "variables": {}, + "features": {} + }, + "HomeLatestTimeline": { + "queryId": "mBo3f9s6XlntJE3nLv09iQ", + "variables": { + "count": 1000, + "includePromotedContent": True, + "latestControlAvailable": True, + "requestContext": "launch", + "withSuperFollowsUserFields": True, + "withDownvotePerspective": False, + "withReactionsMetadata": False, + "withReactionsPerspective": False, + "withSuperFollowsTweetFields": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "HomeTimeline": { + "queryId": "u5XGoPEa9-Hb30zpGz3Yrg", + "variables": { + "count": 1000, + "includePromotedContent": True, + "latestControlAvailable": True, + "requestContext": "launch", + "withCommunity": True, + "withSuperFollowsUserFields": True, + "withDownvotePerspective": False, + "withReactionsMetadata": False, + "withReactionsPerspective": False, + "withSuperFollowsTweetFields": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "ImmersiveMedia": { + "queryId": "7P_Y2m7_NkEnge7eCeW-cw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "Likes": { + "queryId": "nYrjBgnUWQFt_tRyCGatZA", + "variables": { + "userId": None, + "count": 1000, + "includePromotedContent": True, + "withSuperFollowsUserFields": True, + "withDownvotePerspective": False, + "withReactionsMetadata": False, + "withReactionsPerspective": False, + "withSuperFollowsTweetFields": True, + "withClientEventToken": False, + "withBirdwatchNotes": False, + "withVoice": True, + "withV2Timeline": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "ListAddMember": { + "queryId": "P8tyfv2_0HzofrB5f6_ugw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "DeleteListBanner": { + "queryId": "-bOKetDVCMl20qXn7YDXIA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "EditListBanner": { + "queryId": "Uk0ZwKSMYng56aQdeJD1yw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "ListBySlug": { + "queryId": "i08_qAU5nG5EkjnbcCeg0g", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "CreateList": { + "queryId": "hQAsnViq2BrMLbPuQ9umDA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "ListCreationRecommendedUsers": { + "queryId": "v8nSx_ZtU14Q4VK4Ag4aZA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "DeleteList": { + "queryId": "UnN9Th1BDbeLjpgjGSpL3Q", + "variables": {}, + "features": {} + }, + "FetchDraftTweets": { + "queryId": "ZkqIq_xRhiUme0PBJNpRtg", + "variables": {}, + "features": {} + }, + "ListEditRecommendedUsers": { + "queryId": "0kj42oKYT7gL-SBLoxJH6w", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "ListLatestTweetsTimeline": { + "queryId": "1KstFrRPSljOFXpcQVgplQ", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "ListMembers": { + "queryId": "FSzYZVLhaaQYkrY7XXHN4g", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "ListMemberships": { + "queryId": "yTAHAtT8Ez4EDcG3I4Uzew", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "MuteList": { + "queryId": "ZYyanJsskNUcltu9bliMLA", + "variables": {}, + "features": {} + }, + "ListOwnerships": { + "queryId": "L2Mni5sKnWUbNHcbdndscQ", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "ListPinOne": { + "queryId": "PdFLmbN9FAT3kxuYphbO6A", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "ListPins": { + "queryId": "KwDtNPZP8xL57bCxHCIvOg", + "variables": { + "withSuperFollowsUserFields": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "ListProductSubscriptions": { + "queryId": "wwdBYgScze0_Jnan79jEUw", + "variables": {}, + "features": {} + }, + "ListByRestId": { + "queryId": "Bc-6GPUtWnyr3PN0fNffyA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "ListRankedTweetsTimeline": { + "queryId": "8L7Yat0LpxTWYLPMKDkiEg", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "ListRemoveMember": { + "queryId": "DBZowzFN492FFkBPBptCwg", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "ListSubscribe": { + "queryId": "JZ_OVzM4b32pPufdXa5vgw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "ListSubscribers": { + "queryId": "fCOx7ELrPOcZAK_qZuiHYQ", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "UnmuteList": { + "queryId": "pMZrHRNsmEkXgbn3tOyr7Q", + "variables": {}, + "features": {} + }, + "ListUnpinOne": { + "queryId": "oVn3dJ4Q1HDvq-UYT8AUdg", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "ListUnsubscribe": { + "queryId": "AhfcWLFMXGaFMpzeUYtayA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "UpdateList": { + "queryId": "4dCEFWtxEbhnSLcJdJ6PNg", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "ListsDiscovery": { + "queryId": "MyeubSVb94xuClV0kXSQiw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "ListsManagementPageTimeline": { + "queryId": "-xpH2IARz6JqT0nMkHt3KA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "ListsPinMany": { + "queryId": "2X4Vqu6XLneR-XZnGK5MAw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "LiveCommerceItemsSlice": { + "queryId": "-lnNX56S2YrZYrLzbccFAQ", + "variables": {}, + "features": {} + }, + "ModerateTweet": { + "queryId": "pjFnHGVqCjTcZol0xcBJjw", + "variables": {}, + "features": {} + }, + "ModeratedTimeline": { + "queryId": "mhzbOvVnFCa8UG8w2bg7BA", + "variables": { + "rootTweetId": None, + "count": 1000, + "includePromotedContent": True, + "withDownvotePerspective": False, + "withReactionsMetadata": False, + "withReactionsPerspective": False, + "withSuperFollowsTweetFields": True, + "withSuperFollowsUserFields": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "MutedAccounts": { + "queryId": "joFE7-leV60iydenIDnpew", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "NoteworthyAccountsPage": { + "queryId": "HmxIM_uy0brqVUYXm2OSxA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "PaymentMethods": { + "queryId": "mPF_G9okpbZuLcD6mN8K9g", + "variables": {}, + "features": {} + }, + "PinReply": { + "queryId": "GA2_1uKP9b_GyR4MVAQXAw", + "variables": {}, + "features": {} + }, + "UnpinReply": { + "queryId": "iRe6ig5OV1EzOtldNIuGDQ", + "variables": {}, + "features": {} + }, + "ProfileUserPhoneState": { + "queryId": "5kUWP8C1hcd6omvg6HXXTQ", + "variables": {}, + "features": {} + }, + "PutClientEducationFlag": { + "queryId": "IjQ-egg0uPkY11NyPMfRMQ", + "variables": {}, + "features": {} + }, + "AdAccounts": { + "queryId": "a8KxGfFQAmm3WxqemuqSRA", + "variables": {}, + "features": {} + }, + "AudienceEstimate": { + "queryId": "1LYVUabJBYkPlUAWRabB3g", + "variables": {}, + "features": {} + }, + "Budgets": { + "queryId": "mbK3oSQotwcJXyQIBE3uYw", + "variables": {}, + "features": {} + }, + "Coupons": { + "queryId": "R1h43jnAl2bsDoUkgZb7NQ", + "variables": {}, + "features": {} + }, + "CreateQuickPromotion": { + "queryId": "oDSoVgHhJxnd5IkckgPZdg", + "variables": {}, + "features": {} + }, + "QuickPromoteEligibility": { + "queryId": "LtpCXh66W-uXh7u7XSRA8Q", + "variables": {}, + "features": {} + }, + "EnrollCoupon": { + "queryId": "SOyGmNGaEXcvk15s5bqDrA", + "variables": {}, + "features": {} + }, + "RemoveFollower": { + "queryId": "QpNfg0kpPRfjROQ_9eOLXA", + "variables": {}, + "features": {} + }, + "RemoveTweetFromBookmarkFolder": { + "queryId": "2Qbj9XZvtUvyJB4gFwWfaA", + "variables": {}, + "features": {} + }, + "Retweeters": { + "queryId": "0BoJlKAxoNPQUHRftlwZ2w", + "variables": { + "tweetId": None, + "count": 1000, + "includePromotedContent": True, + "withSuperFollowsUserFields": True, + "withDownvotePerspective": False, + "withReactionsMetadata": False, + "withReactionsPerspective": False, + "withSuperFollowsTweetFields": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "RitoActionedTweetsTimeline": { + "queryId": "8iqIOQT0x4SQvgULbu9D_g", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "RitoFlaggedAccountsTimeline": { + "queryId": "9bnCGPHDI_yk7vJDlToKkw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "RitoFlaggedTweetsTimeline": { + "queryId": "_XNqSModnKoclHMD6oDmNw", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "RitoSuggestedActionsFacePile": { + "queryId": "GnQKeEdL1LyeK3dTQCS1yw", + "variables": {}, + "features": {} + }, + "GetSafetyModeSettings": { + "queryId": "AhxTX0lkbIos4WG53xwzSA", + "variables": {}, + "features": {} + }, + "SetSafetyModeSettings": { + "queryId": "qSJIPIpf4gA7Wn21bT3D4w", + "variables": {}, + "features": {} + }, + "FetchScheduledTweets": { + "queryId": "ITtjAzvlZni2wWXwf295Qg", + "variables": {}, + "features": {} + }, + "SharingAudiospacesListeningDataWithFollowersUpdate": { + "queryId": "5h0kNbk3ii97rmfY6CdgAA", + "variables": {}, + "features": {} + }, + "SubscribeToScheduledSpace": { + "queryId": "Sxn4YOlaAwEKjnjWV0h7Mw", + "variables": {}, + "features": {} + }, + "SubscriptionCheckoutUrlWithEligibility": { + "queryId": "hKfOOObQr5JmfmxW0YtPvg", + "variables": {}, + "features": {} + }, + "SubscriptionProductDetails": { + "queryId": "GZF6Vha91bWrZjDmZZ-VNA", + "variables": {}, + "features": {} + }, + "SubscriptionProductFeaturesFetch": { + "queryId": "Me2CVcAXxvK2WMr-Nh_Qqg", + "variables": {}, + "features": {} + }, + "SuperFollowers": { + "queryId": "BQIYNSwMPfKmT-fqGbxkaA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "timelinesFeedback": { + "queryId": "vfVbgvTPTQ-dF_PQ5lD1WQ", + "variables": {}, + "features": {} + }, + "TopicFollow": { + "queryId": "ElqSLWFmsPL4NlZI5e1Grg", + "variables": {}, + "features": {} + }, + "TopicLandingPage": { + "queryId": "QqvCpKOp5tbk09ZQ4Ay-IQ", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "TopicNotInterested": { + "queryId": "cPCFdDAaqRjlMRYInZzoDA", + "variables": {}, + "features": {} + }, + "TopicByRestId": { + "queryId": "4OUZZOonV2h60I0wdlQb_w", + "variables": {}, + "features": {} + }, + "TopicToFollowSidebar": { + "queryId": "O-tnGnESFUk_Y7HvI6QvAQ", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "TopicUndoNotInterested": { + "queryId": "4tVnt6FoSxaX8L-mDDJo4Q", + "variables": {}, + "features": {} + }, + "TopicUnfollow": { + "queryId": "srwjU6JM_ZKTj_QMfUGNcw", + "variables": {}, + "features": {} + }, + "TopicsManagementPage": { + "queryId": "wCDJjeosMB7Hk7_fzjJzhg", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "TopicsPickerPage": { + "queryId": "TOu480G65VAXfGLnJiqdng", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "TopicsPickerPageById": { + "queryId": "K_M3YAag4oBcqIaUyy9eUA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "TrustedFriendsTypeahead": { + "queryId": "_vUIWq3vpyL0amiNTjrM-w", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "TweetDetail": { + "queryId": "zXaXQgfyR4GxE21uwYQSyA", + "variables": { + "focalTweetId": None, + "with_rux_injections": False, + "includePromotedContent": True, + "withCommunity": True, + "withQuickPromoteEligibilityTweetFields": True, + "withBirdwatchNotes": True, + "withSuperFollowsUserFields": True, + "withDownvotePerspective": False, + "withReactionsMetadata": False, + "withReactionsPerspective": False, + "withSuperFollowsTweetFields": True, + "withVoice": True, + "withV2Timeline": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "TweetEditHistory": { + "queryId": "coQ70Jlk_NSi3lB3OFdmCQ", + "variables": {}, + "features": { + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "GetTweetReactionTimeline": { + "queryId": "ihIcULrtrtPGlCuprduRrA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "TweetResultByRestId": { + "queryId": "D_jNhjWZeRZT5NURzfJZSQ", + "variables": { + "tweetId": None, + "includePromotedContent": True, + "withBirdwatchNotes": True, + "withVoice": True, + "withCommunity": True, + "withSuperFollowsUserFields": True, + "withDownvotePerspective": False, + "withReactionsMetadata": False, + "withReactionsPerspective": False, + "withSuperFollowsTweetFields": True + }, + "features": { + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "TweetStats": { + "queryId": "EvbTkPDT-xQCfupPu0rWMA", + "variables": { + "rest_id": None + }, + "features": { + "profile_foundations_tweet_stats_enabled": True, + "profile_foundations_tweet_stats_tweet_frequency": True + } + }, + "TwitterArticleCreate": { + "queryId": "sGXhodE6Dltxhlbialo5iA", + "variables": {}, + "features": { + "responsive_web_twitter_article_data_v2_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "TwitterArticleDelete": { + "queryId": "6st-stMDc7KBqLT8KvWhHg", + "variables": {}, + "features": {} + }, + "TwitterArticleByRestId": { + "queryId": "mVoL1eoSf2OlGuBGpkryfg", + "variables": {}, + "features": { + "responsive_web_twitter_article_data_v2_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "TwitterArticleUpdateCoverImage": { + "queryId": "0mp-rT_Rx_cG6U8W3k-fRQ", + "variables": {}, + "features": { + "responsive_web_twitter_article_data_v2_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "TwitterArticleUpdateData": { + "queryId": "r__zSVe8KW9qbUYX_-uLFQ", + "variables": {}, + "features": { + "responsive_web_twitter_article_data_v2_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "TwitterArticleUpdateMedia": { + "queryId": "YI_ZepiIMqNNt4p5RLDTQw", + "variables": {}, + "features": { + "responsive_web_twitter_article_data_v2_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "TwitterArticleUpdateTitle": { + "queryId": "6ovmzBFIwaFx01qSCOcbgQ", + "variables": {}, + "features": { + "responsive_web_twitter_article_data_v2_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "TwitterArticleUpdateVisibility": { + "queryId": "Hm_3BGv0gAkSsZUIIbcoeA", + "variables": {}, + "features": { + "responsive_web_twitter_article_data_v2_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "TwitterArticlesSlice": { + "queryId": "AmzI_uIjc7u7tqqEqnVCcw", + "variables": {}, + "features": { + "responsive_web_twitter_article_data_v2_enabled": True, + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "UnfavoriteTweet": { + "queryId": "ZYKSe-w7KEslx3JhSIk5LA", + "variables": { + "tweet_id": None + }, + "features": {} + }, + "UnmentionUserFromConversation": { + "queryId": "xVW9j3OqoBRY9d6_2OONEg", + "variables": {}, + "features": {} + }, + "UnmoderateTweet": { + "queryId": "pVSyu6PA57TLvIE4nN2tsA", + "variables": {}, + "features": {} + }, + "UnsubscribeFromScheduledSpace": { + "queryId": "Zevhh76Msw574ZSs2NQHGQ", + "variables": {}, + "features": {} + }, + "UrtFixtures": { + "queryId": "FZSojQVZVb-r7NWAk1tU1w", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "UserAboutTimeline": { + "queryId": "Oica4bXjJsZIr09aEl6BaQ", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "UserAccountLabel": { + "queryId": "rD5gLxVmMvtdtYU1UHWlFQ", + "variables": {}, + "features": {} + }, + "UserBusinessProfileTeamTimeline": { + "queryId": "o6dy2QT9-gZTpi-j45r1kA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "UserByRestId": { + "queryId": "gUIQEk2xDGzQTX8Ii0Yesw", + "variables": { + "userId": None, + "withSafetyModeUserFields": True, + "withSuperFollowsUserFields": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "UserByScreenName": { + "queryId": "rePnxwe9LZ51nQ7Sn_xN_A", + "variables": { + "screen_name": None, + "withSafetyModeUserFields": True, + "withSuperFollowsUserFields": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "GetUserClaims": { + "queryId": "lFi3xnx0auUUnyG4YwpCNw", + "variables": {}, + "features": {} + }, + "UserMedia": { + "queryId": "YcKL-v9RI2t42QCEDfv-9g", + "variables": { + "userId": None, + "count": 1000, + "includePromotedContent": False, + "withSuperFollowsUserFields": True, + "withDownvotePerspective": False, + "withReactionsMetadata": False, + "withReactionsPerspective": False, + "withSuperFollowsTweetFields": True, + "withClientEventToken": False, + "withBirdwatchNotes": False, + "withVoice": True, + "withV2Timeline": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "UserPromotableTweets": { + "queryId": "Gk8GbzTt57LhitFR_zGhLA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "UserSessionsList": { + "queryId": "vJ-XatpmQSG8bDch8-t9Jw", + "variables": {}, + "features": {} + }, + "UserSuperFollowTweets": { + "queryId": "80-X1jA2-5dZX4mHC-sivQ", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "UserTweets": { + "queryId": "CkON7wJrKLwEVV59ClcmjA", + "variables": { + "userId": None, + "count": 1000, + "includePromotedContent": True, + "withDownvotePerspective": False, + "withQuickPromoteEligibilityTweetFields": True, + "withReactionsMetadata": False, + "withReactionsPerspective": False, + "withSuperFollowsTweetFields": True, + "withSuperFollowsUserFields": True, + "withV2Timeline": True, + "withVoice": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "UserTweetsAndReplies": { + "queryId": "WASDBdxt4mOxtWMwlyg_0Q", + "variables": { + "userId": None, + "count": 1000, + "includePromotedContent": True, + "withCommunity": True, + "withDownvotePerspective": False, + "withReactionsMetadata": False, + "withReactionsPerspective": False, + "withSuperFollowsTweetFields": True, + "withSuperFollowsUserFields": True, + "withV2Timeline": True, + "withVoice": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "tweetypie_unmention_optimization_enabled": True, + "vibe_api_enabled": True, + "responsive_web_edit_tweet_api_enabled": True, + "graphql_is_translatable_rweb_tweet_is_translatable_enabled": True, + "view_counts_everywhere_api_enabled": True, + "longform_notetweets_consumption_enabled": True, + "tweet_awards_web_tipping_enabled": True, + "freedom_of_speech_not_reach_fetch_enabled": True, + "standardized_nudges_misinfo": True, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": True, + "interactive_text_enabled": True, + "responsive_web_text_conversations_enabled": True, + "longform_notetweets_richtext_consumption_enabled": True, + "responsive_web_enhance_cards_enabled": True + } + }, + "UsersByRestIds": { + "queryId": "zaTqxMKJ1kzpOxhVbYr1YQ", + "variables": { + "userIds": [], + "withSafetyModeUserFields": True, + "withSuperFollowsUserFields": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "ViewerEmailSettings": { + "queryId": "JpjlNgn4sLGvS6tgpTzYBg", + "variables": {}, + "features": {} + }, + "Viewer": { + "queryId": "QXO9SjUJXid3NNEovZXydw", + "variables": { + "withCommunitiesMemberships": True, + "withCommunitiesCreation": True, + "withSuperFollowsUserFields": True + }, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + }, + "ViewerTeams": { + "queryId": "jqQV7d1CMJ4El2nGSit6aA", + "variables": {}, + "features": { + "responsive_web_twitter_blue_verified_badge_is_enabled": True, + "responsive_web_graphql_exclude_directive_enabled": True, + "verified_phone_label_enabled": True, + "responsive_web_graphql_skip_user_profile_image_extensions_enabled": True, + "responsive_web_graphql_timeline_navigation_enabled": True + } + } +} \ No newline at end of file diff --git a/src/config/update_operations.py b/src/config/update_operations.py new file mode 100644 index 0000000..c2bb747 --- /dev/null +++ b/src/config/update_operations.py @@ -0,0 +1,75 @@ +import re +import json +import requests +import bs4 +from pathlib import Path + + +def find_api_script(res: requests.Response) -> str: + """ + Find api script + @param res: response from homepage: https://twitter.com + @return: url to api script + """ + for s in bs4.BeautifulSoup(res.text, 'html.parser').select('script'): + if x := re.search('(?<=api:")\w+(?=")', s.text): + key = x.group() + 'a' # wtf? + return f'https://abs.twimg.com/responsive-web/client-web/api.{key}.js' + + +def get_operations() -> list[dict]: + """ + Get operations and their respective queryId and feature definitions + @return: list of operations + """ + session = requests.Session() + headers = { + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36' + } + script = find_api_script(session.get('https://twitter.com', headers=headers)) + r = session.get(script, headers=headers) + res = '' + # find operations and their respective queryId and feature definitions + for x in re.split(r'\d+:e=>{e.exports=', r.text)[1:]: + res = res.replace('}}},{', '}},{') + if x.startswith('{queryId:') and '"use strict"' not in x: + for k in ['queryId', 'operationName', 'operationType', 'metadata', 'featureSwitches']: + x = x.replace(k, f'"{k}"') + res += x + return json.loads(f'[{res[:-2]}]') + + +def update_operations(path=Path('operations.json')): + """ + Update operations.json with queryId and feature definitions + @param path: path to operations operations file + @return: updated operations + """ + operations = get_operations() + # update operations file + if path.stat().st_size == 0: + # empty file, add all operations + config = {} + for o in operations: + config[o['operationName']] = { + 'queryId': o['queryId'], + 'variables': {}, + 'features': {k: True for k in o['metadata']['featureSwitches']} + } + else: + config = json.loads(path.read_text()) + # update queryId and features for all operations + for o in operations: + config[o['operationName']]['queryId'] = o['queryId'] + config[o['operationName']]['features'] = {k: True for k in o['metadata']['featureSwitches']} + path.write_text(json.dumps(config, indent=2)) + return config + + +def main() -> int: + update_operations() + return 0 + + +if __name__ == '__main__': + exit(main()) \ No newline at end of file diff --git a/src/log/__init__.py b/src/log/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/log/config.py b/src/log/config.py new file mode 100644 index 0000000..466ceba --- /dev/null +++ b/src/log/config.py @@ -0,0 +1,40 @@ +log_config = { + "version": 1, + "formatters": { + "simple": { + "format": "%(asctime)s.%(msecs)03d %(levelname)s: %(message)s" + } + }, + "handlers": { + "console": { + "class": "logging.StreamHandler", + "level": "DEBUG", + "formatter": "simple", + "stream": "ext://sys.stdout" + }, + "file": { + "class": "logging.FileHandler", + "level": "DEBUG", + "formatter": "simple", + "filename": "log/debug.log", + "encoding": "utf8", + "mode": "a" + } + }, + "loggers": { + "myLogger": { + "level": "DEBUG", + "handlers": [ + "console" + ], + "propagate": "no" + } + }, + "root": { + "level": "DEBUG", + "handlers": [ + "console", + "file" + ] + } +} diff --git a/src/login.py b/src/login.py new file mode 100644 index 0000000..2324cfa --- /dev/null +++ b/src/login.py @@ -0,0 +1,89 @@ +import sys +from requests import Session + + +def update_token(session: Session, key: str, url: str, payload: dict) -> Session: + headers = { + "authorization": 'Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA', + "content-type": "application/json", + "user-agent": 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36', + "x-guest-token": session.tokens['guest_token'], + "x-csrf-token": session.cookies.get("ct0"), + "x-twitter-auth-type": "OAuth2Session" if session.cookies.get("auth_token") else '', + "x-twitter-active-user": "yes", + "x-twitter-client-language": 'en', + } + r = session.post(url, headers=headers, json=payload).json() + status = f'\u001b[32mSUCCESS' if r.get('guest_token') or r.get('flow_token') else f'\u001b[31mFAILED' + print(f'{status}\u001b[0m {sys._getframe(1).f_code.co_name}') # check response data + session.tokens[key] = r[key] + return session + + +def init_guest_token(session: Session) -> Session: + return update_token(session, 'guest_token', 'https://api.twitter.com/1.1/guest/activate.json', {}) + + +def flow_start(session: Session) -> Session: + return update_token(session, 'flow_token', 'https://api.twitter.com/1.1/onboarding/task.json?flow_name=login', { + "input_flow_data": { + "flow_context": {"debug_overrides": {}, "start_location": {"location": "splash_screen"}} + }, "subtask_versions": {} + }) + + +def flow_instrumentation(session: Session) -> Session: + return update_token(session, 'flow_token', 'https://api.twitter.com/1.1/onboarding/task.json', { + "flow_token": session.tokens['flow_token'], + "subtask_inputs": [{ + "subtask_id": "LoginJsInstrumentationSubtask", + "js_instrumentation": {"response": "{}", "link": "next_link"} + }], + }) + + +def flow_username(session: Session) -> Session: + return update_token(session, 'flow_token', 'https://api.twitter.com/1.1/onboarding/task.json', { + "flow_token": session.tokens['flow_token'], + "subtask_inputs": [{ + "subtask_id": "LoginEnterUserIdentifierSSO", + "settings_list": { + "setting_responses": [{ + "key": "user_identifier", + "response_data": {"text_data": {"result": session.username}} + }], "link": "next_link"}}], + }) + + +def flow_password(session: Session) -> Session: + return update_token(session, 'flow_token', 'https://api.twitter.com/1.1/onboarding/task.json', { + "flow_token": session.tokens['flow_token'], + "subtask_inputs": [{ + "subtask_id": "LoginEnterPassword", + "enter_password": {"password": session.password, "link": "next_link"}}] + }) + + +def flow_duplication_check(session: Session) -> Session: + return update_token(session, 'flow_token', 'https://api.twitter.com/1.1/onboarding/task.json', { + "flow_token": session.tokens['flow_token'], + "subtask_inputs": [{ + "subtask_id": "AccountDuplicationCheck", + "check_logged_in_account": {"link": "AccountDuplicationCheck_false"}, + }], + }) + + +def execute_login_flow(session: Session) -> Session: + session = init_guest_token(session) + for fn in [flow_start, flow_instrumentation, flow_username, flow_password, flow_duplication_check]: + session = fn(session) + return session + + +def login(username: str, password: str) -> Session: + session = Session() + session.username = username + session.password = password + session.tokens = {'guest_token': None, 'flow_token': None} + return execute_login_flow(session) \ No newline at end of file diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..6471fa8 --- /dev/null +++ b/src/main.py @@ -0,0 +1,590 @@ +import sys +import asyncio +import logging.config +from pathlib import Path +from urllib.parse import urlencode +from enum import Enum, auto +from functools import wraps, partial + +import aiohttp +import ujson + +from .login import login, Session +from .utils import find_key +from .log.config import log_config +from .config.operations import operations + +logging.config.dictConfig(log_config) +logger = logging.getLogger(__name__) + +MAX_IMAGE_FILE_SIZE = 5_242_880 +CHUNK_SIZE = 8192 + +BOLD = '\u001b[1m' +SUCCESS = '\u001b[32m' +WARN = '\u001b[31m' +RESET = '\u001b[0m' + +MEDIA = { + '.mp4': { + 'type': 'video/mp4', + 'category': 'tweet_video' + }, + '.mov': { + 'type': 'video/quicktime', + 'category': 'tweet_video' + }, + '.png': { + 'type': 'image/png', + 'category': 'tweet_image' + }, + '.jpg': { + 'type': 'image/jpeg', + 'category': 'tweet_image' + }, + '.jpeg': { + 'type': 'image/jpeg', + 'category': 'tweet_image' + }, +} + + +class Operation(Enum): + CreateTweet = auto() + CreateScheduledTweet = auto() + DeleteTweet = auto() + UserTweets = auto() + FavoriteTweet = auto() + UnfavoriteTweet = auto() + CreateRetweet = auto() + DeleteRetweet = auto() + + TweetStats = auto() + + +def log(fn=None, *, level: int = logging.DEBUG, info: list = None): + if fn is None: + return partial(log, level=level, info=info) + + @wraps(fn) + def wrapper(*args, **kwargs): + r = fn(*args, **kwargs) + try: + if 200 <= r.status_code < 300: + message = f'[{SUCCESS}SUCCESS{RESET}] ({BOLD}{fn.__name__}{RESET})' + for k in info: + if callable(k): + logger.log(level, f'{message}: {k(r)}') + else: + attr = getattr(r, k) + v = attr() if callable(attr) else attr + d = {f"{k}": v} + logger.log(level, f'{message}: {d}') + else: + logger.log(level, f'[{WARN}ERROR{RESET}] ({fn.__name__}) {r.status_code} {r.text}') + except Exception as e: + logger.log(level, f'[{WARN}FAILED{RESET}] ({fn.__name__}) {e}') + return r + + return wrapper + + +def _get_headers(session: Session) -> dict: + return { + 'authorization': 'Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA', + 'accept-encoding': 'gzip, deflate, br', + 'cookie': '; '.join(f'{k}={v}' for k, v in session.cookies.items()), + 'referer': 'https://twitter.com/', + 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36', + 'x-csrf-token': session.cookies.get('ct0'), + } + + +async def get_status(media_id: str, auth_session: Session, check_after_secs: int = 1): + url = 'https://upload.twitter.com/i/media/upload.json' + headers = _get_headers(auth_session) + params = {'command': 'STATUS', 'media_id': media_id} + while 1: + await asyncio.sleep(check_after_secs) + async with aiohttp.ClientSession(headers=headers) as s: + async with s.get(url, params=params) as r: + data = await r.json() + info = data['processing_info'] + state = info['state'] + if state == 'succeeded': + logger.debug(f'{media_id}: {SUCCESS}processing complete{RESET}') + return data + if state == 'in_progress': + progress = info["progress_percent"] + check_after_secs = info.get('check_after_secs', check_after_secs) + logger.debug(f'{media_id}: upload {progress = }%') + else: + logger.debug(f'{media_id}: upload {state = }') + + +async def upload_media(fname: str, auth_session: Session): + url = 'https://upload.twitter.com/i/media/upload.json' + headers = _get_headers(auth_session) + conn = aiohttp.TCPConnector(limit=0, ssl=False, ttl_dns_cache=69) + async with aiohttp.ClientSession(headers=headers, connector=conn) as s: + file = Path(fname) + total_bytes = file.stat().st_size + params = { + 'command': 'INIT', + 'total_bytes': total_bytes, + 'media_type': MEDIA[file.suffix]['type'], + 'media_category': MEDIA[file.suffix]['category'] + } + async with s.post(url, headers=headers, params=params) as r: + info = await r.json() + logger.debug(f'{info = }') + media_id = info['media_id'] + + with open(fname, 'rb') as f: + i = 0 + while chunk := f.read(MAX_IMAGE_FILE_SIZE): # todo: arbitrary max size for now + with aiohttp.MultipartWriter('form-data') as mpw: + part = mpw.append(chunk) + part.set_content_disposition('form-data', name='media', filename='blob') + s.cookie_jar.update_cookies(auth_session.cookies) # csrf cookie/header update + r = await s.post( + url, + data=mpw, + headers=headers, + params={'command': 'APPEND', 'media_id': media_id, 'segment_index': i} + ) + logger.debug(f'{r.status = }') + i += 1 + + async with s.post(url, headers=headers, + params={'command': 'FINALIZE', 'media_id': media_id, 'allow_async': 'true'}) as r: + res = await r.json() + logger.debug(f'{res = }') + + if processing_info := res.get('processing_info', {}): + state = processing_info.get('state') + if state == 'pending': + logger.debug(f'{media_id}: {state}') + return await get_status(media_id, auth_session, processing_info.get('check_after_secs', 1)) + logger.debug(f'{media_id}: {SUCCESS}upload complete{RESET}') + return res + + +@log(level=logging.DEBUG, info=['status_code']) +def add_alt_text(text: str, media_id: int, session: Session): + params = {"media_id": media_id, "alt_text": {"text": text}} + url = 'https://api.twitter.com/1.1/media/metadata/create.json' + r = session.post(url, headers=_get_headers(session), json=params) + return r + + +@log(level=logging.DEBUG, info=['status_code', 'json']) +def like_tweet(tweet_id: int, session: Session): + operation = Operation.FavoriteTweet.name + qid = operations[operation]['queryId'] + params = operations[operation] + params['variables']['tweet_id'] = tweet_id + url = f"https://api.twitter.com/graphql/{qid}/{operation}" + r = session.post(url, headers=_get_headers(session), json=params) + logger.debug(f'{tweet_id = }') + return r + + +@log(level=logging.DEBUG, info=['status_code', 'json']) +def unlike_tweet(tweet_id: int, session: Session): + operation = Operation.UnfavoriteTweet.name + qid = operations[operation]['queryId'] + params = operations[operation] + params['variables']['tweet_id'] = tweet_id + url = f"https://api.twitter.com/graphql/{qid}/{operation}" + r = session.post(url, headers=_get_headers(session), json=params) + logger.debug(f'{tweet_id = }') + return r + + +@log(level=logging.DEBUG, info=['status_code', 'json']) +def create_tweet(text: str, session: Session, media: list[dict | str] = None, **kwargs): + operation = Operation.CreateTweet.name + qid = operations[operation]['queryId'] + params = operations[operation] + params['variables']['tweet_text'] = text + if media: + for m in media: + if isinstance(m, dict): + media_info = asyncio.run(upload_media(m['file'], session)) + params['variables']['media']['media_entities'].append({ + 'media_id': media_info['media_id'], + 'tagged_users': m.get('tagged_users', []) + }) + if alt := m.get('alt'): + add_alt_text(alt, media_info['media_id'], session) + # for convenience, so we can just pass list of strings + elif isinstance(m, str): + media_info = asyncio.run(upload_media(m, session)) + params['variables']['media']['media_entities'].append({ + 'media_id': media_info['media_id'], + 'tagged_users': [] + }) + + if reply_params := kwargs.get('reply_params', {}): + params['variables'] |= reply_params + if quote_params := kwargs.get('quote_params', {}): + params['variables'] |= quote_params + if poll_params := kwargs.get('poll_params', {}): + params['variables'] |= poll_params + + url = f"https://api.twitter.com/graphql/{qid}/{operation}" + r = session.post(url, headers=_get_headers(session), json=params) + return r + + +def comment(text: str, tweet_id: int, session: Session, media: list[dict | str] = None): + params = {"reply": {"in_reply_to_tweet_id": tweet_id, "exclude_reply_user_ids": []}} + return create_tweet(text, session, media, reply_params=params) + + +def quote(text: str, screen_name: str, tweet_id: int, session: Session, media: list[dict | str] = None): + """ no unquote operation, just DeleteTweet""" + params = {"attachment_url": f"https://twitter.com/{screen_name}/status/{tweet_id}"} + return create_tweet(text, session, media, quote_params=params) + + +def delete_tweet(tweet_id: int, session: Session): + operation = Operation.DeleteTweet.name + qid = operations[operation]['queryId'] + params = operations[operation] + params['variables']['tweet_id'] = tweet_id + url = f"https://api.twitter.com/graphql/{qid}/{operation}" + r = session.post(url, headers=_get_headers(session), json=params) + if 200 <= r.status_code < 300: + logger.debug(f'{WARN}DELETE{RESET} tweet: {tweet_id}') + return r.json() + + +def delete_all_tweets(user_id: int, session: Session): + tweets = get_tweets(user_id, session) + ids = set(map(int, find_key(find_key(tweets, 'tweet_results'), 'rest_id'))) - {user_id} + [delete_tweet(_id, session) for _id in ids] + + +def retweet(tweet_id: int, session: Session): + operation = Operation.CreateRetweet.name + qid = operations[operation]['queryId'] + params = operations[operation] + params['variables']['tweet_id'] = tweet_id + url = f"https://api.twitter.com/graphql/{qid}/{operation}" + r = session.post(url, headers=_get_headers(session), json=params) + if 200 <= r.status_code < 300: + logger.debug(f'{SUCCESS}RETWEET{RESET} tweet: {tweet_id}') + return r.json() + + +def unretweet(tweet_id: int, session: Session): + operation = Operation.DeleteRetweet.name + qid = operations[operation]['queryId'] + params = operations[operation] + params['variables']['source_tweet_id'] = tweet_id + url = f"https://api.twitter.com/graphql/{qid}/{operation}" + r = session.post(url, headers=_get_headers(session), json=params) + if 200 <= r.status_code < 300: + logger.debug(f'{SUCCESS}UNRETWEET{RESET} tweet: {tweet_id}') + return r.json() + + +def get_tweets(user_id: int, session: Session): + operation = Operation.UserTweets.name + qid = operations[operation]['queryId'] + params = operations[operation] + params['variables']['userId'] = user_id + query = build_query(params) + url = f"https://api.twitter.com/graphql/{qid}/{operation}?{query}" + r = session.get(url, headers=_get_headers(session)) + return r.json() + + +@log(level=logging.DEBUG, info=['status_code', lambda r: r.json()['id']]) +def follow(user_id: int, session: Session): + settings = { + "user_id": user_id, + "include_profile_interstitial_type": "1", + "include_blocking": "1", + "include_blocked_by": "1", + "include_followed_by": "1", + "include_want_retweets": "1", + "include_mute_edge": "1", + "include_can_dm": "1", + "include_can_media_tag": "1", + "include_ext_has_nft_avatar": "1", + "include_ext_is_blue_verified": "1", + "include_ext_verified_type": "1", + "skip_status": "1", + } + headers = _get_headers(session) + headers['content-type'] = 'application/x-www-form-urlencoded' + url = 'https://api.twitter.com/1.1/friendships/create.json' + r = session.post(url, headers=headers, data=urlencode(settings)) + return r + + +@log(level=logging.DEBUG, info=['status_code', lambda r: r.json()['id']]) +def unfollow(user_id: int, session: Session): + _name = sys._getframe().f_code.co_name + settings = { + "user_id": user_id, + "include_profile_interstitial_type": "1", + "include_blocking": "1", + "include_blocked_by": "1", + "include_followed_by": "1", + "include_want_retweets": "1", + "include_mute_edge": "1", + "include_can_dm": "1", + "include_can_media_tag": "1", + "include_ext_has_nft_avatar": "1", + "include_ext_is_blue_verified": "1", + "include_ext_verified_type": "1", + "skip_status": "1", + } + headers = _get_headers(session) + headers['content-type'] = 'application/x-www-form-urlencoded' + url = 'https://api.twitter.com/1.1/friendships/destroy.json' + r = session.post(url, headers=headers, data=urlencode(settings)) + return r + + +def mute(user_id: int, session: Session): + _name = sys._getframe().f_code.co_name + settings = { + 'user_id': user_id + } + try: + headers = _get_headers(session) + headers['content-type'] = 'application/x-www-form-urlencoded' + url = 'https://api.twitter.com/1.1/mutes/users/create.json' + r = session.post(url, headers=headers, data=urlencode(settings)) + if 200 <= r.status_code < 300: + data = r.json() + logger.debug(f'{SUCCESS}MUTE{RESET}: {data["id"]}') + return data + except Exception as e: + logger.debug(f'[FAILED] {_name}: {e}') + + +def unmute(user_id: int, session: Session): + _name = sys._getframe().f_code.co_name + settings = { + 'user_id': user_id + } + try: + headers = _get_headers(session) + headers['content-type'] = 'application/x-www-form-urlencoded' + url = 'https://api.twitter.com/1.1/mutes/users/destroy.json' + r = session.post(url, headers=headers, data=urlencode(settings)) + if 200 <= r.status_code < 300: + data = r.json() + logger.debug(f'{WARN}UNMUTE{RESET}: {data["id"]}') + return data + except Exception as e: + logger.debug(f'[FAILED] {_name}: {e}') + + +def enable_notifications(user_id: int, session: Session): + _name = sys._getframe().f_code.co_name + settings = { + "id": user_id, + "device": "true", + "cursor": "-1", + "include_profile_interstitial_type": "1", + "include_blocking": "1", + "include_blocked_by": "1", + "include_followed_by": "1", + "include_want_retweets": "1", + "include_mute_edge": "1", + "include_can_dm": "1", + "include_can_media_tag": "1", + "include_ext_has_nft_avatar": "1", + "include_ext_is_blue_verified": "1", + "include_ext_verified_type": "1", + "skip_status": "1", + } + try: + headers = _get_headers(session) + headers['content-type'] = 'application/x-www-form-urlencoded' + url = 'https://api.twitter.com/1.1/friendships/update.json' + r = session.post(url, headers=headers, data=urlencode(settings)) + if 200 <= r.status_code < 300: + data = r.json() + twid = data["relationship"]["target"]["id"] + logger.debug(f'{SUCCESS}ENABLE NOTIFICATIONS{RESET}: {twid}') + return data + except Exception as e: + logger.debug(f'[FAILED] {_name}: {e}') + + +def disable_notifications(user_id: int, session: Session): + _name = sys._getframe().f_code.co_name + settings = { + "id": user_id, + "device": "false", + "cursor": "-1", + "include_profile_interstitial_type": "1", + "include_blocking": "1", + "include_blocked_by": "1", + "include_followed_by": "1", + "include_want_retweets": "1", + "include_mute_edge": "1", + "include_can_dm": "1", + "include_can_media_tag": "1", + "include_ext_has_nft_avatar": "1", + "include_ext_is_blue_verified": "1", + "include_ext_verified_type": "1", + "skip_status": "1", + } + try: + headers = _get_headers(session) + headers['content-type'] = 'application/x-www-form-urlencoded' + url = 'https://api.twitter.com/1.1/friendships/update.json' + r = session.post(url, headers=headers, data=urlencode(settings)) + if 200 <= r.status_code < 300: + data = r.json() + twid = data["relationship"]["target"]["id"] + logger.debug(f'{WARN}DISABLE NOTIFICATIONS{RESET}: {twid}') + return data + except Exception as e: + logger.debug(f'[FAILED] {_name}: {e}') + + +def block(user_id: int, session: Session): + _name = sys._getframe().f_code.co_name + settings = { + 'user_id': user_id + } + try: + headers = _get_headers(session) + headers['content-type'] = 'application/x-www-form-urlencoded' + url = 'https://api.twitter.com/1.1/blocks/create.json' + r = session.post(url, headers=headers, data=urlencode(settings)) + if 200 <= r.status_code < 300: + data = r.json() + logger.debug(f'{SUCCESS}BLOCK{RESET}: {data["id"]}') + return data + except Exception as e: + logger.debug(f'[FAILED] {_name}: {e}') + + +def unblock(user_id: int, session: Session): + _name = sys._getframe().f_code.co_name + settings = { + 'user_id': user_id + } + try: + headers = _get_headers(session) + headers['content-type'] = 'application/x-www-form-urlencoded' + url = 'https://api.twitter.com/1.1/blocks/destroy.json' + r = session.post(url, headers=headers, data=urlencode(settings)) + if 200 <= r.status_code < 300: + data = r.json() + logger.debug(f'{WARN}UNBLOCK{RESET}: {data["id"]}') + return data + except Exception as e: + logger.debug(f'[FAILED] {_name}: {e}') + + +def update_search_settings(session: Session, **kwargs): + _name = sys._getframe().f_code.co_name + try: + if kwargs.get('incognito'): + kwargs.pop('incognito') + settings = { + "optInFiltering": False, + "optInBlocking": True, + } + else: + settings = {} + settings |= kwargs + twid = int(session.cookies.get_dict()['twid'].split('=')[-1].strip('"')) + headers = _get_headers(session=session) + r = session.post( + url=f'https://api.twitter.com/1.1/strato/column/User/{twid}/search/searchSafety', + headers=headers, + json=settings, + ) + if r.status_code == 200: + logger.debug(f'[SUCCESS] {_name}: {settings}') + return settings + except Exception as e: + logger.debug(f'[FAILED] {_name}: {e}') + + +def update_content_settings(session: Session, **kwargs): + """ + Update content settings + + @param session: authenticated session + @param kwargs: settings to enable/disable + @return: updated settings + """ + _name = sys._getframe().f_code.co_name + try: + if kwargs.get('incognito'): + kwargs.pop('incognito') + settings = { + 'include_mention_filter': True, + 'include_nsfw_user_flag': True, + 'include_nsfw_admin_flag': True, + 'include_ranked_timeline': True, + 'include_alt_text_compose': True, + 'display_sensitive_media': True, + 'protected': True, + 'discoverable_by_email': False, + 'discoverable_by_mobile_phone': False, + 'allow_dms_from': 'following', ## {'all'} + 'dm_quality_filter': 'enabled', ## {'disabled'} + 'dm_receipt_setting': 'all_disabled', ## {'all_enabled'} + 'allow_media_tagging': 'none', ## {'all', 'following'} + 'nsfw_user': False, + 'geo_enabled': False, ## add location information to your tweets + 'allow_ads_personalization': False, + 'allow_logged_out_device_personalization': False, + 'allow_sharing_data_for_third_party_personalization': False, + 'allow_location_history_personalization': False, + } + else: + settings = {} + settings |= kwargs + headers = _get_headers(session=session) + headers['content-type'] = 'application/x-www-form-urlencoded' + r = session.post( + url='https://api.twitter.com/1.1/account/settings.json', + headers=headers, + data=urlencode(settings), # case-insensitive, E.g. can be 'TRUE', True, 'true', etc. + ) + if r.status_code == 200: + logger.debug(f'[SUCCESS] {_name}: {settings}') + return settings + except Exception as e: + logger.debug(f'[FAILED] {_name}: {e}') + + +def build_query(params): + return '&'.join(f'{k}={ujson.dumps(v)}' for k, v in params.items()) + + +def stats(rest_id: int, session: Session): + """private endpoint?""" + operation = Operation.TweetStats.name + qid = operations[operation]['queryId'] + params = operations[operation] + params['variables']['rest_id'] = rest_id + query = build_query(params) + url = f"https://api.twitter.com/graphql/{qid}/{operation}?{query}" + r = session.get(url, headers=_get_headers(session)) + return r.json() + + +def main() -> int: + ... + return 0 + + +if __name__ == '__main__': + exit(main()) diff --git a/src/utils.py b/src/utils.py new file mode 100644 index 0000000..bd4ffc7 --- /dev/null +++ b/src/utils.py @@ -0,0 +1,26 @@ +def find_key(obj: dict | list[dict], key: str) -> list: + """ + Find all values of a given key within a nested dict or list of dicts + + @param obj: dictionary or list of dictionaries + @param key: key to search for + @return: list of values + """ + def helper(obj: any, key: str, L: list) -> list: + if not obj: + return L + + if isinstance(obj, list): + for e in obj: + L.extend(helper(e, key, [])) + return L + + if isinstance(obj, dict) and obj.get(key): + L.append(obj[key]) + + if isinstance(obj, dict) and obj: + for k in obj: + L.extend(helper(obj[k], key, [])) + return L + + return helper(obj, key, []) \ No newline at end of file