Compare commits

...

1 Commits

Author SHA1 Message Date
jackwener 0416c294b5 fix(twitter): resolve article ID to tweet ID for article URLs
Article URLs (x.com/i/article/{articleId}) use a different ID than
tweet status URLs. The GraphQL TweetResultByRestId endpoint requires
the parent tweet ID, not the article ID.

Fix: detect article URLs upfront, navigate to the article page to
extract the parent tweet ID from DOM links, then use the resolved
tweet ID for GraphQL. Status URLs continue to work as before.

Closes #688 (supersedes PR from gucasbrg — fixes the bug where all
inputs were routed through article page, breaking status URL flow).
2026-04-02 18:27:01 +08:00
+31 -1
View File
@@ -16,11 +16,41 @@ cli({
],
columns: ['title', 'author', 'content', 'url'],
func: async (page, kwargs) => {
// Extract tweet ID from URL if needed
// Extract tweet ID from URL if needed.
// Article URLs (x.com/i/article/{articleId}) use a different ID than
// tweet status URLs — the GraphQL endpoint needs the parent tweet ID.
let tweetId = kwargs['tweet-id'];
const isArticleUrl = /\/article\/\d+/.test(tweetId);
const urlMatch = tweetId.match(/\/(?:status|article)\/(\d+)/);
if (urlMatch) tweetId = urlMatch[1];
if (isArticleUrl) {
// Navigate to the article page and resolve the parent tweet ID from DOM
await page.goto(`https://x.com/i/article/${tweetId}`);
await page.wait(3);
const resolvedId = await page.evaluate(`
(function() {
var links = document.querySelectorAll('a[href*="/status/"]');
for (var i = 0; i < links.length; i++) {
var m = links[i].href.match(/\\/status\\/(\\d+)/);
if (m) return m[1];
}
var og = document.querySelector('meta[property="og:url"]');
if (og && og.content) {
var m2 = og.content.match(/\\/status\\/(\\d+)/);
if (m2) return m2[1];
}
return null;
})()
`);
if (!resolvedId || typeof resolvedId !== 'string') {
throw new CommandExecutionError(
`Could not resolve article ${tweetId} to a tweet ID. The article page may not contain a linked tweet.`,
);
}
tweetId = resolvedId;
}
// Navigate to the tweet page for cookie context
await page.goto(`https://x.com/i/status/${tweetId}`);
await page.wait(3);