-
Notifications
You must be signed in to change notification settings - Fork 88
[Bug] twitter/search 适配器失效:webpack module ID 和 GraphQL queryId 均已过期 #36
Copy link
Copy link
Open
Description
环境
- bb-browser: v0.10.1
- macOS arm64, Chrome 146
- bb-sites: 最新(
bb-browser site update后仍复现)
问题描述
twitter/search 适配器硬编码了两个 X.com 会定期轮换的值,导致适配器完全不可用。
复现
bb-browser site twitter/search "test" --json
# 错误: TypeError: Cannot read properties of undefined (reading 'call')
# at g (https://x.com/:341:171705)根因
~/.bb-browser/bb-sites/twitter/search.js 中有两个硬编码值已过期:
问题 1: webpack module ID 过期
// 第 26 行
const txMod = __webpack_require__(83914); // ← 已失效
const genTxId = txMod.jJ;当前 X.com 的 main.69383b5a.js 中,jJ 导出所在模块 ID 已变为 938838:
curl -s "https://abs.twimg.com/responsive-web/client-web/main.69383b5a.js" | \
grep -o '.[0-9]\{3,6\}:.\{0,5\}(e,t,n)=>{"use strict";n.d(t,{K4:()=>a,ZP:()=>l,jJ:()=>s})'
# 输出: ,938838:(e,t,n)=>...问题 2: GraphQL queryId 过期
// 第 30 行
const path = '/i/api/graphql/oKkjeoNFNQN7IeK7AHYc0A/SearchTimeline'; // ← 404当前 queryId 为 GcXk9vN_d1jUfHNqLacXQA:
curl -s "https://abs.twimg.com/responsive-web/client-web/main.69383b5a.js" | \
grep -o '.\{0,50\}SearchTimeline.\{0,50\}' | grep queryId
# 输出: queryId:"GcXk9vN_d1jUfHNqLacXQA",operationName:"SearchTimeline"问题 3: 适配器执行上下文与页面上下文不同
手动将 module ID 和 queryId 都更新为最新值后,适配器调用 API 成功但返回 0 条推文(只有 cursor entries)。
同样的代码通过 bb-browser eval 在页面主线程中执行时,能正常返回 19 条推文。
说明适配器的运行环境与页面 JS 主线程上下文存在差异,导致 webpack 模块不可用或 genTxId 生成了无效的 transaction ID。X.com 对无效 x-client-transaction-id 的处理是返回空结果而非 403。
临时解决方案
通过 bb-browser eval 直接在 x.com 页面上下文中执行搜索脚本:
bb-browser open "https://x.com/search?q=test&src=typed_query"
# 等待页面加载后
bb-browser eval "$(cat <<'JSEOF'
var ct0 = document.cookie.split(";").map(function(c){return c.trim()})
.find(function(c){return c.startsWith("ct0=")}).split("=")[1];
var wr;
window.webpackChunk_twitter_responsive_web.push([["__bb"],{},function(r){wr=r}]);
var txMod = wr(938838);
var genTxId = txMod.jJ;
var path = "/i/api/graphql/GcXk9vN_d1jUfHNqLacXQA/SearchTimeline";
genTxId("x.com", path, "GET").then(function(txId) {
var v = JSON.stringify({rawQuery: "test", count: 20, querySource: "typed_query", product: "Top"});
var f = JSON.stringify({rweb_video_screen_enabled:false,
profile_label_improvements_pcf_label_in_post_enabled:true,
responsive_web_graphql_timeline_navigation_enabled:true,
responsive_web_graphql_skip_user_profile_image_extensions_enabled:false,
longform_notetweets_consumption_enabled:true,
view_counts_everywhere_api_enabled:true,
tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled:true,
longform_notetweets_rich_text_read_enabled:true,
responsive_web_enhance_cards_enabled:false});
return fetch(path+"?variables="+encodeURIComponent(v)+"&features="+encodeURIComponent(f), {
headers: {"Authorization":"Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA",
"X-Csrf-Token":ct0,"X-Twitter-Auth-Type":"OAuth2Session",
"X-Twitter-Active-User":"yes","X-Client-Transaction-Id":txId},
credentials:"include"});
}).then(function(r){return r.json()}).then(function(d){
// ... 解析 tweets ...
});
JSEOF
)"
# 成功返回 19 条推文这说明 API 本身可用,问题在于适配器的执行上下文。
建议
改为动态发现
X.com 每 2-4 周轮换这些值,硬编码不可持续。建议改为运行时自动发现:
// 动态发现 genTxId 函数
let __webpack_require__;
window.webpackChunk_twitter_responsive_web.push(
[['__bb_auto'], {}, (req) => { __webpack_require__ = req; }]
);
const cache = __webpack_require__.c || {};
let genTxId;
for (const [id, mod] of Object.entries(cache)) {
if (mod.exports && typeof mod.exports.jJ === 'function') {
genTxId = mod.exports.jJ;
break;
}
}
// 动态发现 queryId
let queryId;
for (const [id, mod] of Object.entries(cache)) {
const exp = mod.exports;
if (exp && exp.operationName === 'SearchTimeline') {
queryId = exp.queryId;
break;
}
}感谢开发这么好用的工具!
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels