From 2dde1834150d8619984bfb5050faaa79609ccf81 Mon Sep 17 00:00:00 2001 From: Jaehoon You <158752+teslamint@users.noreply.github.com> Date: Wed, 10 Jun 2026 18:06:33 +0900 Subject: [PATCH] fix: Fall back to rest_id for user ids in parseTweet X no longer includes legacy user id fields (user_id_str on the tweet, id_str on the user) in some GraphQL responses such as HomeTimeline, while TweetDetail still has them. parseTweet relied on those fields alone, so tweets parsed from the home timeline ended up with user.id_str === undefined, breaking every action that sends the author id (report, block, mute, copy user id) and poisoning the userStorage cache key. Fall back to user_results.result.rest_id, the canonical id that is always present, in all five user id assignments (main tweet, retweeted status, quoted status, and quotes inside retweets). Legacy fields still take precedence when present, matching the user.legacy.id_str = rest_id pattern already used elsewhere in apis.js. Assisted-by: Claude Fable 5 with Claude Code --- scripts/apis.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/scripts/apis.js b/scripts/apis.js index 66ca4ad6..399a2766 100644 --- a/scripts/apis.js +++ b/scripts/apis.js @@ -178,7 +178,8 @@ function parseTweet(res) { let tweet = res.legacy; if (!res.core) return; tweet.user = res.core.user_results.result.legacy; - tweet.user.id_str = tweet.user_id_str; + tweet.user.id_str = + tweet.user_id_str || res.core.user_results.result.rest_id; const ur = res.core.user_results.result; if(ur?.location?.location) tweet.user.location = ur.location.location; if(ur?.avatar?.image_url) tweet.user.profile_image_url_https = ur.avatar.image_url; @@ -255,7 +256,8 @@ function parseTweet(res) { } } result.legacy.quoted_status.user = qu; - result.legacy.quoted_status.user.id_str = qu.id_str; + result.legacy.quoted_status.user.id_str = + qu.id_str || qur.rest_id; tweetStorage[result.legacy.quoted_status.id_str] = result.legacy.quoted_status; tweetStorage[result.legacy.quoted_status.id_str].cacheDate = @@ -300,7 +302,8 @@ function parseTweet(res) { } } result.legacy.quoted_status.user = qu; - result.legacy.quoted_status.user.id_str = qu.id_str; + result.legacy.quoted_status.user.id_str = + qu.id_str || qur.rest_id; tweetStorage[result.legacy.quoted_status.id_str] = result.legacy.quoted_status; tweetStorage[result.legacy.quoted_status.id_str].cacheDate = @@ -337,7 +340,7 @@ function parseTweet(res) { } } tweet.retweeted_status.user = u; - tweet.retweeted_status.user.id_str = u.id_str; + tweet.retweeted_status.user.id_str = u.id_str || ur.rest_id; tweet.retweeted_status.ext = {}; if (result.views) { tweet.retweeted_status.ext.views = { @@ -416,7 +419,7 @@ function parseTweet(res) { } } tweet.quoted_status.user = u; - tweet.quoted_status.user.id_str = u.id_str; + tweet.quoted_status.user.id_str = u.id_str || ur.rest_id; tweet.quoted_status.ext = {}; if (result.views) { tweet.quoted_status.ext.views = {