Twitter 媒體下載

一鍵保存視頻/圖片

< 腳本Twitter 媒體下載的回應

評論:正評 - 腳本一切正常

§
發表於: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?

§
發表於:2025-04-26

Flkalas the one who made "TwitterMediaAssist" said this about his extension on GibHub. Should a workaround exist, hopefully it can fix this one too.

發表回覆

登入以回復