From 2758e4c63a9b82c7ea8eeb18e031eef8f7953002 Mon Sep 17 00:00:00 2001
From: Sou <105340539+kannch8765@users.noreply.github.com>
Date: Sun, 30 Aug 2026 18:23:34 +0900
Subject: [PATCH 1/5] fix(twitter): restore intercepted reader collection
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Align the collect step with AutoCLI’s interceptor buffer, accept current X timeline_v2 user timelines, and use the supported scroll option names for notifications.
---
adapters/twitter/followers.yaml | 40 ++++++++++----------
adapters/twitter/following.yaml | 40 ++++++++++----------
adapters/twitter/notifications.yaml | 4 +-
crates/autocli-pipeline/src/steps/browser.rs | 28 ++++++++++++--
4 files changed, 67 insertions(+), 45 deletions(-)
diff --git a/adapters/twitter/followers.yaml b/adapters/twitter/followers.yaml
index 118ac87..28e3053 100644
--- a/adapters/twitter/followers.yaml
+++ b/adapters/twitter/followers.yaml
@@ -77,26 +77,26 @@ pipeline:
const seen = new Map();
for (const req of requests) {
try {
- let instructions = req.data?.user?.result?.timeline?.timeline?.instructions;
- if (!instructions) continue;
- let addEntries = instructions.find(i => i.type === 'TimelineAddEntries')
- || instructions.find(i => i.entries && Array.isArray(i.entries));
- if (!addEntries) continue;
- for (const entry of addEntries.entries) {
- if (!entry.entryId.startsWith('user-')) continue;
- const item = entry.content?.itemContent?.user_results?.result;
- if (!item || item.__typename !== 'User') continue;
- const core = item.core || {};
- const legacy = item.legacy || {};
- const sn = core.screen_name || legacy.screen_name || 'unknown';
- if (!seen.has(sn)) {
- seen.set(sn, true);
- results.push({
- screen_name: sn,
- name: core.name || legacy.name || 'unknown',
- bio: legacy.description || item.profile_bio?.description || '',
- followers: legacy.followers_count || legacy.normal_followers_count || 0
- });
+ let instructions = req.data?.user?.result?.timeline_v2?.timeline?.instructions
+ || req.data?.user?.result?.timeline?.timeline?.instructions
+ || [];
+ for (const instruction of instructions) {
+ for (const entry of instruction.entries || []) {
+ if (!entry.entryId.startsWith('user-')) continue;
+ const item = entry.content?.itemContent?.user_results?.result;
+ if (!item || item.__typename !== 'User') continue;
+ const core = item.core || {};
+ const legacy = item.legacy || {};
+ const sn = core.screen_name || legacy.screen_name || 'unknown';
+ if (!seen.has(sn)) {
+ seen.set(sn, true);
+ results.push({
+ screen_name: sn,
+ name: core.name || legacy.name || 'unknown',
+ bio: legacy.description || item.profile_bio?.description || '',
+ followers: legacy.followers_count || legacy.normal_followers_count || 0
+ });
+ }
}
}
} catch {}
diff --git a/adapters/twitter/following.yaml b/adapters/twitter/following.yaml
index 9aced8e..589348b 100644
--- a/adapters/twitter/following.yaml
+++ b/adapters/twitter/following.yaml
@@ -71,26 +71,26 @@ pipeline:
const seen = new Map();
for (const req of requests) {
try {
- let instructions = req.data?.user?.result?.timeline?.timeline?.instructions;
- if (!instructions) continue;
- let addEntries = instructions.find(i => i.type === 'TimelineAddEntries')
- || instructions.find(i => i.entries && Array.isArray(i.entries));
- if (!addEntries) continue;
- for (const entry of addEntries.entries) {
- if (!entry.entryId.startsWith('user-')) continue;
- const item = entry.content?.itemContent?.user_results?.result;
- if (!item || item.__typename !== 'User') continue;
- const core = item.core || {};
- const legacy = item.legacy || {};
- const sn = core.screen_name || legacy.screen_name || 'unknown';
- if (!seen.has(sn)) {
- seen.set(sn, true);
- results.push({
- screen_name: sn,
- name: core.name || legacy.name || 'unknown',
- bio: legacy.description || item.profile_bio?.description || '',
- followers: legacy.followers_count || legacy.normal_followers_count || 0
- });
+ let instructions = req.data?.user?.result?.timeline_v2?.timeline?.instructions
+ || req.data?.user?.result?.timeline?.timeline?.instructions
+ || [];
+ for (const instruction of instructions) {
+ for (const entry of instruction.entries || []) {
+ if (!entry.entryId.startsWith('user-')) continue;
+ const item = entry.content?.itemContent?.user_results?.result;
+ if (!item || item.__typename !== 'User') continue;
+ const core = item.core || {};
+ const legacy = item.legacy || {};
+ const sn = core.screen_name || legacy.screen_name || 'unknown';
+ if (!seen.has(sn)) {
+ seen.set(sn, true);
+ results.push({
+ screen_name: sn,
+ name: core.name || legacy.name || 'unknown',
+ bio: legacy.description || item.profile_bio?.description || '',
+ followers: legacy.followers_count || legacy.normal_followers_count || 0
+ });
+ }
}
}
} catch {}
diff --git a/adapters/twitter/notifications.yaml b/adapters/twitter/notifications.yaml
index 6090b05..e5bb8fa 100644
--- a/adapters/twitter/notifications.yaml
+++ b/adapters/twitter/notifications.yaml
@@ -32,8 +32,8 @@ pipeline:
- wait: 5
- scroll:
- times: 2
- delayMs: 2000
+ count: 2
+ delay: 2000
- collect:
parse: |
diff --git a/crates/autocli-pipeline/src/steps/browser.rs b/crates/autocli-pipeline/src/steps/browser.rs
index 89dbf3e..f9e2aba 100644
--- a/crates/autocli-pipeline/src/steps/browser.rs
+++ b/crates/autocli-pipeline/src/steps/browser.rs
@@ -597,8 +597,8 @@ impl StepHandler for CollectStep {
let js = format!(
r#"(() => {{
const args = {args_json};
- const requests = window.__opencli_intercepted || [];
- window.__opencli_intercepted = [];
+ const requests = window.__autocli_intercepted || [];
+ window.__autocli_intercepted = [];
const parseFn = {parse_fn};
return parseFn(requests);
}})()"#
@@ -643,6 +643,7 @@ mod tests {
struct MockPage {
goto_url: std::sync::Mutex