Twitter Media Downloader

Save Video/Photo by One-Click.

< Feedback on Twitter Media Downloader

Review: قالتىس - قوليازما ئىشلەيدۇ

§
يوللانغان ۋاقتى: 2025-04-26

seems like the tweetdetail api is gone after checking the error messages in console, could mean total death of this Userscript which is sad.
Downloaded more than 1700 media files with it.
o7 R.I.P.

§
يوللانغان ۋاقتى: 2025-04-26

Does this API problem mean that even the author can’t fix it?

§
يوللانغان ۋاقتى: 2025-04-26

It still exists. But looks like the url and/or parameters changed a bit.

§
يوللانغان ۋاقتى: 2025-04-26

I've tried to edit the script to have the exact same parameters as the valid query the front end does when navigating to a Tweet, but no success, the requests gets bounced. It's not exactly my area of expertise but if anyone wants to finish or know what's missing, here it is: Starting from the fetchJson function:

        fetchJson: async function (status_id) {
            let base_url = `https://${host}/i/api/graphql/_8aYOgEDz35BrBcBal1-_w/TweetDetail`;
            let variables = {
                "focalTweetId": status_id,
                "with_rux_injections": false,
                "rankingMode": "Relevance",
                "includePromotedContent": true,
                "withCommunity": true,
                "withQuickPromoteEligibilityTweetFields": true,
                "withBirdwatchNotes": true,
                "withVoice": true
            };
            let features = {
                "rweb_video_screen_enabled": false,
                "profile_label_improvements_pcf_label_in_post_enabled": true,
                "rweb_tipjar_consumption_enabled": true,
                "verified_phone_label_enabled": false,
                "creator_subscriptions_tweet_preview_api_enabled": true,
                "responsive_web_graphql_timeline_navigation_enabled": true,
                "responsive_web_graphql_skip_user_profile_image_extensions_enabled": false,
                "premium_content_api_read_enabled": false,
                "communities_web_enable_tweet_community_results_fetch": true,
                "c9s_tweet_anatomy_moderator_badge_enabled": true,
                "responsive_web_grok_analyze_button_fetch_trends_enabled": false,
                "responsive_web_grok_analyze_post_followups_enabled": true,
                "responsive_web_jetfuel_frame": false,
                "responsive_web_grok_share_attachment_enabled": true,
                "articles_preview_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,
                "responsive_web_twitter_article_tweet_consumption_enabled": true,
                "tweet_awards_web_tipping_enabled": false,
                "responsive_web_grok_show_grok_translated_post": false,
                "responsive_web_grok_analysis_button_from_backend": false,
                "creator_subscriptions_quote_tweet_preview_enabled": false,
                "freedom_of_speech_not_reach_fetch_enabled": true,
                "standardized_nudges_misinfo": true,
                "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": true,
                "longform_notetweets_rich_text_read_enabled": true,
                "longform_notetweets_inline_media_enabled": true,
                "responsive_web_grok_image_annotation_enabled": true,
                "responsive_web_enhance_cards_enabled": false
            };
            let fieldToggles = {
                "withArticleRichContentState": true,
                "withArticlePlainText": false,
                "withGrokAnalyze": false,
                "withDisallowedReplyControls": false
            };

            // Custom encoding function to ensure specials chars becomes their %XX versions
            const customEncode = (obj) => {
                return JSON.stringify(obj)
                    .replace(/:/g, '%3A')
                    .replace(/,/g, '%2C')
                    .replace(/{/g, '%7B')
                    .replace(/}/g, '%7D');
            };

            let url = `${base_url}?variables=${customEncode(variables)}&features=${customEncode(features)}&fieldToggles=${customEncode(fieldToggles)}`;

            let cookies = this.getCookie();
            let headers = {
                'authorization': 'Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA',
                'x-twitter-active-user': 'yes',
                'x-twitter-client-language': cookies.lang,
                'x-csrf-token': cookies.ct0
            };

            // Add guest token if ct0 has length of 32
            if (cookies.ct0.length == 32) headers['x-guest-token'] = cookies.gt;

            // Fetch and process the tweet
            let tweet_detail = await fetch(url, {headers: headers}).then(result => {
                console.log(result);
                return result.json()
            });

            let tweet_entrie = tweet_detail.data.threaded_conversation_with_injections_v2.instructions[0].entries.find(n => n.entryId == `tweet-${status_id}`);
            let tweet_result = tweet_entrie.content.itemContent.tweet_results.result;
            return tweet_result.tweet || tweet_result;
        },
§
يوللانغان ۋاقتى: 2025-04-26

yea i went a bit on a search and totally forgot that gallery-dl also used the same old entry
it requires a transaction-id now but instead of using it right now they're using another work around with something called "restid"
link to github issue > https://github.com/mikf/gallery-dl/issues/7382 <
im not smarty pants with that stuff, so even the 10min of me trying to figure it out i gave up lmao

§
يوللانغان ۋاقتى: 2025-04-26
تەھرىرلەنگەن ۋاقتى: 2025-04-26

Has anyone been able to crack down a hotfix?

جاۋاب قايتۇرۇش

جاۋاب قايتۇرۇش ئۈچۈن كىرىش.