From 552db11479adc8445848c6f215d33555e6c4c9de Mon Sep 17 00:00:00 2001 From: root Date: Sat, 9 May 2026 16:17:55 -0400 Subject: [PATCH 1/4] fix(twitter): handle TweetPreviewDisplay for subscriber-only posts --- lib/routes/twitter/api/mobile-api/api.ts | 29 +++++++++++++++++++++++- lib/routes/twitter/api/web-api/utils.ts | 27 ++++++++++++++++++++-- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/lib/routes/twitter/api/mobile-api/api.ts b/lib/routes/twitter/api/mobile-api/api.ts index 4f3e12ce554a..d805128f0db6 100644 --- a/lib/routes/twitter/api/mobile-api/api.ts +++ b/lib/routes/twitter/api/mobile-api/api.ts @@ -145,7 +145,34 @@ function gatherLegacyFromData(entries, filterNested, userId) { for (const entry of filteredEntries) { if (entry.entryId) { const content = entry.content || entry.item; - let tweet = content?.content?.tweetResult?.result || content?.itemContent?.tweet_results?.result; +let tweet = content?.content?.tweetResult?.result || content?.itemContent?.tweet_results?.result; + // 处理订阅者专属预览帖子(必须在 tweet.tweet 替换之前判断) + if (tweet?.__typename === 'TweetPreviewDisplay') { + const preview = tweet.tweet; + if (preview?.rest_id) { + const userResult = preview.core?.user_results?.result; + const screenName = userResult?.core?.screen_name ?? ''; + const fakeLegacy = { + id_str: preview.rest_id, + full_text: `🔒 [Subscribers Only] ${preview.text ?? ''}`, + created_at: preview.created_at ?? '', + entities: { urls: [], hashtags: [], symbols: [], user_mentions: [] }, + user_id_str: userResult?.rest_id ?? '', + user: { + name: userResult?.core?.name ?? screenName, + screen_name: screenName, + profile_image_url_https: userResult?.avatar?.image_url ?? '', + }, + favorite_count: preview.favorite_count ?? 0, + reply_count: preview.reply_count ?? 0, + retweet_count: preview.retweet_count ?? 0, + }; + if (userId === undefined || fakeLegacy.user_id_str === userId + '') { + tweets.push(fakeLegacy); + } + } + continue; + } if (tweet && tweet.tweet) { tweet = tweet.tweet; } diff --git a/lib/routes/twitter/api/web-api/utils.ts b/lib/routes/twitter/api/web-api/utils.ts index 522cdb147d13..73b45f1b34d1 100644 --- a/lib/routes/twitter/api/web-api/utils.ts +++ b/lib/routes/twitter/api/web-api/utils.ts @@ -337,11 +337,34 @@ export function gatherLegacyFromData(entries: any[], filterNested?: string[], us for (const entry of filteredEntries) { if (entry.entryId) { const content = entry.content || entry.item; - let tweet = content?.content?.tweetResult?.result || content?.itemContent?.tweet_results?.result; +let tweet = content?.content?.tweetResult?.result || content?.itemContent?.tweet_results?.result; + // 处理订阅者专属预览帖子(必须在 tweet.tweet 替换之前判断) + if (tweet?.__typename === 'TweetPreviewDisplay') { + const preview = tweet.tweet; + if (preview?.rest_id) { + const userResult = preview.core?.user_results?.result; + const screenName = userResult?.core?.screen_name ?? ''; + const fakeLegacy: any = { + id_str: preview.rest_id, + full_text: `🔒 [Subscribers Only] ${preview.text ?? ''}`, + created_at: preview.created_at ?? '', + entities: { urls: [], hashtags: [], symbols: [], user_mentions: [] }, + user_id_str: userResult?.rest_id ?? '', + favorite_count: preview.favorite_count ?? 0, + reply_count: preview.reply_count ?? 0, + retweet_count: preview.retweet_count ?? 0, + }; + hydrateLegacyUser(fakeLegacy, { core: preview.core, rest_id: preview.rest_id }); + if (userId === undefined || fakeLegacy.user_id_str === userId + '') { + tweets.push(fakeLegacy); + } + } + continue; + } if (tweet && tweet.tweet) { tweet = tweet.tweet; } - if (tweet) { +if (tweet) { const retweet = tweet.legacy?.retweeted_status_result?.result; for (const t of [tweet, retweet]) { if (!t?.legacy) { From 9a8866344687516d1585cc6d9623634fc948a137 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 9 May 2026 16:43:42 -0400 Subject: [PATCH 2/4] fix(twitter): remove unused screenName variable --- lib/routes/twitter/api/web-api/utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/routes/twitter/api/web-api/utils.ts b/lib/routes/twitter/api/web-api/utils.ts index 73b45f1b34d1..b03f724f365e 100644 --- a/lib/routes/twitter/api/web-api/utils.ts +++ b/lib/routes/twitter/api/web-api/utils.ts @@ -343,7 +343,6 @@ let tweet = content?.content?.tweetResult?.result || content?.itemContent?.tweet const preview = tweet.tweet; if (preview?.rest_id) { const userResult = preview.core?.user_results?.result; - const screenName = userResult?.core?.screen_name ?? ''; const fakeLegacy: any = { id_str: preview.rest_id, full_text: `🔒 [Subscribers Only] ${preview.text ?? ''}`, From 3343c318589362e8ad24bd7287df7944c7717d45 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 10 May 2026 12:57:56 -0400 Subject: [PATCH 3/4] fix(twitter): fix indentation and use English comments --- lib/routes/twitter/api/mobile-api/api.ts | 2 +- lib/routes/twitter/api/web-api/utils.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/routes/twitter/api/mobile-api/api.ts b/lib/routes/twitter/api/mobile-api/api.ts index d805128f0db6..b16e295419fe 100644 --- a/lib/routes/twitter/api/mobile-api/api.ts +++ b/lib/routes/twitter/api/mobile-api/api.ts @@ -146,7 +146,7 @@ function gatherLegacyFromData(entries, filterNested, userId) { if (entry.entryId) { const content = entry.content || entry.item; let tweet = content?.content?.tweetResult?.result || content?.itemContent?.tweet_results?.result; - // 处理订阅者专属预览帖子(必须在 tweet.tweet 替换之前判断) + // Handle subscriber-only preview posts (must check before tweet.tweet reassignment) if (tweet?.__typename === 'TweetPreviewDisplay') { const preview = tweet.tweet; if (preview?.rest_id) { diff --git a/lib/routes/twitter/api/web-api/utils.ts b/lib/routes/twitter/api/web-api/utils.ts index b03f724f365e..6b361e4de058 100644 --- a/lib/routes/twitter/api/web-api/utils.ts +++ b/lib/routes/twitter/api/web-api/utils.ts @@ -337,8 +337,8 @@ export function gatherLegacyFromData(entries: any[], filterNested?: string[], us for (const entry of filteredEntries) { if (entry.entryId) { const content = entry.content || entry.item; -let tweet = content?.content?.tweetResult?.result || content?.itemContent?.tweet_results?.result; - // 处理订阅者专属预览帖子(必须在 tweet.tweet 替换之前判断) + let tweet = content?.content?.tweetResult?.result || content?.itemContent?.tweet_results?.result; + // Handle subscriber-only preview posts (must check before tweet.tweet reassignment) if (tweet?.__typename === 'TweetPreviewDisplay') { const preview = tweet.tweet; if (preview?.rest_id) { @@ -363,7 +363,7 @@ let tweet = content?.content?.tweetResult?.result || content?.itemContent?.tweet if (tweet && tweet.tweet) { tweet = tweet.tweet; } -if (tweet) { + if (tweet) { const retweet = tweet.legacy?.retweeted_status_result?.result; for (const t of [tweet, retweet]) { if (!t?.legacy) { From 5c75a4ddbf795e83d4f40b16f592de68ff583106 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 13 May 2026 11:01:26 -0400 Subject: [PATCH 4/4] fix(twitter): fix indentation and remove unused variables --- lib/routes/twitter/api/mobile-api/api.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/routes/twitter/api/mobile-api/api.ts b/lib/routes/twitter/api/mobile-api/api.ts index b16e295419fe..6e513c1e6e40 100644 --- a/lib/routes/twitter/api/mobile-api/api.ts +++ b/lib/routes/twitter/api/mobile-api/api.ts @@ -145,13 +145,12 @@ function gatherLegacyFromData(entries, filterNested, userId) { for (const entry of filteredEntries) { if (entry.entryId) { const content = entry.content || entry.item; -let tweet = content?.content?.tweetResult?.result || content?.itemContent?.tweet_results?.result; + let tweet = content?.content?.tweetResult?.result || content?.itemContent?.tweet_results?.result; // Handle subscriber-only preview posts (must check before tweet.tweet reassignment) if (tweet?.__typename === 'TweetPreviewDisplay') { const preview = tweet.tweet; if (preview?.rest_id) { const userResult = preview.core?.user_results?.result; - const screenName = userResult?.core?.screen_name ?? ''; const fakeLegacy = { id_str: preview.rest_id, full_text: `🔒 [Subscribers Only] ${preview.text ?? ''}`, @@ -159,8 +158,8 @@ let tweet = content?.content?.tweetResult?.result || content?.itemContent?.tweet entities: { urls: [], hashtags: [], symbols: [], user_mentions: [] }, user_id_str: userResult?.rest_id ?? '', user: { - name: userResult?.core?.name ?? screenName, - screen_name: screenName, + name: userResult?.core?.name ?? userResult?.core?.screen_name ?? '', + screen_name: userResult?.core?.screen_name ?? '', profile_image_url_https: userResult?.avatar?.image_url ?? '', }, favorite_count: preview.favorite_count ?? 0,