@antcoder/birdxtwittercli 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/CHANGELOG.md +176 -0
  2. package/LICENSE +21 -0
  3. package/README.md +388 -0
  4. package/dist/cli/pagination.d.ts +35 -0
  5. package/dist/cli/pagination.d.ts.map +1 -0
  6. package/dist/cli/pagination.js +43 -0
  7. package/dist/cli/pagination.js.map +1 -0
  8. package/dist/cli/program.d.ts +5 -0
  9. package/dist/cli/program.d.ts.map +1 -0
  10. package/dist/cli/program.js +113 -0
  11. package/dist/cli/program.js.map +1 -0
  12. package/dist/cli/shared.d.ts +77 -0
  13. package/dist/cli/shared.d.ts.map +1 -0
  14. package/dist/cli/shared.js +327 -0
  15. package/dist/cli/shared.js.map +1 -0
  16. package/dist/cli.d.ts +12 -0
  17. package/dist/cli.d.ts.map +1 -0
  18. package/dist/cli.js +29 -0
  19. package/dist/cli.js.map +1 -0
  20. package/dist/commands/bookmarks.d.ts +4 -0
  21. package/dist/commands/bookmarks.d.ts.map +1 -0
  22. package/dist/commands/bookmarks.js +189 -0
  23. package/dist/commands/bookmarks.js.map +1 -0
  24. package/dist/commands/check.d.ts +4 -0
  25. package/dist/commands/check.d.ts.map +1 -0
  26. package/dist/commands/check.js +43 -0
  27. package/dist/commands/check.js.map +1 -0
  28. package/dist/commands/follow.d.ts +4 -0
  29. package/dist/commands/follow.d.ts.map +1 -0
  30. package/dist/commands/follow.js +91 -0
  31. package/dist/commands/follow.js.map +1 -0
  32. package/dist/commands/help.d.ts +4 -0
  33. package/dist/commands/help.d.ts.map +1 -0
  34. package/dist/commands/help.js +19 -0
  35. package/dist/commands/help.js.map +1 -0
  36. package/dist/commands/home.d.ts +4 -0
  37. package/dist/commands/home.d.ts.map +1 -0
  38. package/dist/commands/home.js +43 -0
  39. package/dist/commands/home.js.map +1 -0
  40. package/dist/commands/lists.d.ts +4 -0
  41. package/dist/commands/lists.d.ts.map +1 -0
  42. package/dist/commands/lists.js +213 -0
  43. package/dist/commands/lists.js.map +1 -0
  44. package/dist/commands/news.d.ts +4 -0
  45. package/dist/commands/news.d.ts.map +1 -0
  46. package/dist/commands/news.js +131 -0
  47. package/dist/commands/news.js.map +1 -0
  48. package/dist/commands/post.d.ts +4 -0
  49. package/dist/commands/post.d.ts.map +1 -0
  50. package/dist/commands/post.js +101 -0
  51. package/dist/commands/post.js.map +1 -0
  52. package/dist/commands/query-ids.d.ts +4 -0
  53. package/dist/commands/query-ids.d.ts.map +1 -0
  54. package/dist/commands/query-ids.js +80 -0
  55. package/dist/commands/query-ids.js.map +1 -0
  56. package/dist/commands/read.d.ts +4 -0
  57. package/dist/commands/read.d.ts.map +1 -0
  58. package/dist/commands/read.js +152 -0
  59. package/dist/commands/read.js.map +1 -0
  60. package/dist/commands/search.d.ts +4 -0
  61. package/dist/commands/search.d.ts.map +1 -0
  62. package/dist/commands/search.js +115 -0
  63. package/dist/commands/search.js.map +1 -0
  64. package/dist/commands/unbookmark.d.ts +4 -0
  65. package/dist/commands/unbookmark.d.ts.map +1 -0
  66. package/dist/commands/unbookmark.js +36 -0
  67. package/dist/commands/unbookmark.js.map +1 -0
  68. package/dist/commands/user-tweets.d.ts +4 -0
  69. package/dist/commands/user-tweets.d.ts.map +1 -0
  70. package/dist/commands/user-tweets.js +109 -0
  71. package/dist/commands/user-tweets.js.map +1 -0
  72. package/dist/commands/users.d.ts +4 -0
  73. package/dist/commands/users.d.ts.map +1 -0
  74. package/dist/commands/users.js +295 -0
  75. package/dist/commands/users.js.map +1 -0
  76. package/dist/index.d.ts +2 -0
  77. package/dist/index.d.ts.map +1 -0
  78. package/dist/index.js +2 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/lib/cli-args.d.ts +7 -0
  81. package/dist/lib/cli-args.d.ts.map +1 -0
  82. package/dist/lib/cli-args.js +25 -0
  83. package/dist/lib/cli-args.js.map +1 -0
  84. package/dist/lib/cookies.d.ts +31 -0
  85. package/dist/lib/cookies.d.ts.map +1 -0
  86. package/dist/lib/cookies.js +173 -0
  87. package/dist/lib/cookies.js.map +1 -0
  88. package/dist/lib/extract-bookmark-folder-id.d.ts +2 -0
  89. package/dist/lib/extract-bookmark-folder-id.d.ts.map +1 -0
  90. package/dist/lib/extract-bookmark-folder-id.js +20 -0
  91. package/dist/lib/extract-bookmark-folder-id.js.map +1 -0
  92. package/dist/lib/extract-list-id.d.ts +2 -0
  93. package/dist/lib/extract-list-id.d.ts.map +1 -0
  94. package/dist/lib/extract-list-id.js +19 -0
  95. package/dist/lib/extract-list-id.js.map +1 -0
  96. package/dist/lib/extract-tweet-id.d.ts +2 -0
  97. package/dist/lib/extract-tweet-id.d.ts.map +1 -0
  98. package/dist/lib/extract-tweet-id.js +14 -0
  99. package/dist/lib/extract-tweet-id.js.map +1 -0
  100. package/dist/lib/features.json +17 -0
  101. package/dist/lib/index.d.ts +10 -0
  102. package/dist/lib/index.d.ts.map +1 -0
  103. package/dist/lib/index.js +4 -0
  104. package/dist/lib/index.js.map +1 -0
  105. package/dist/lib/normalize-handle.d.ts +6 -0
  106. package/dist/lib/normalize-handle.d.ts.map +1 -0
  107. package/dist/lib/normalize-handle.js +31 -0
  108. package/dist/lib/normalize-handle.js.map +1 -0
  109. package/dist/lib/output.d.ts +29 -0
  110. package/dist/lib/output.d.ts.map +1 -0
  111. package/dist/lib/output.js +88 -0
  112. package/dist/lib/output.js.map +1 -0
  113. package/dist/lib/paginate-cursor.d.ts +27 -0
  114. package/dist/lib/paginate-cursor.d.ts.map +1 -0
  115. package/dist/lib/paginate-cursor.js +37 -0
  116. package/dist/lib/paginate-cursor.js.map +1 -0
  117. package/dist/lib/query-ids.json +20 -0
  118. package/dist/lib/runtime-features.d.ts +19 -0
  119. package/dist/lib/runtime-features.d.ts.map +1 -0
  120. package/dist/lib/runtime-features.js +151 -0
  121. package/dist/lib/runtime-features.js.map +1 -0
  122. package/dist/lib/runtime-query-ids.d.ts +33 -0
  123. package/dist/lib/runtime-query-ids.d.ts.map +1 -0
  124. package/dist/lib/runtime-query-ids.js +264 -0
  125. package/dist/lib/runtime-query-ids.js.map +1 -0
  126. package/dist/lib/thread-filters.d.ts +8 -0
  127. package/dist/lib/thread-filters.d.ts.map +1 -0
  128. package/dist/lib/thread-filters.js +124 -0
  129. package/dist/lib/thread-filters.js.map +1 -0
  130. package/dist/lib/twitter-client-base.d.ts +38 -0
  131. package/dist/lib/twitter-client-base.d.ts.map +1 -0
  132. package/dist/lib/twitter-client-base.js +129 -0
  133. package/dist/lib/twitter-client-base.js.map +1 -0
  134. package/dist/lib/twitter-client-bookmarks.d.ts +7 -0
  135. package/dist/lib/twitter-client-bookmarks.d.ts.map +1 -0
  136. package/dist/lib/twitter-client-bookmarks.js +61 -0
  137. package/dist/lib/twitter-client-bookmarks.js.map +1 -0
  138. package/dist/lib/twitter-client-constants.d.ts +44 -0
  139. package/dist/lib/twitter-client-constants.d.ts.map +1 -0
  140. package/dist/lib/twitter-client-constants.js +51 -0
  141. package/dist/lib/twitter-client-constants.js.map +1 -0
  142. package/dist/lib/twitter-client-engagement.d.ts +16 -0
  143. package/dist/lib/twitter-client-engagement.d.ts.map +1 -0
  144. package/dist/lib/twitter-client-engagement.js +81 -0
  145. package/dist/lib/twitter-client-engagement.js.map +1 -0
  146. package/dist/lib/twitter-client-features.d.ts +14 -0
  147. package/dist/lib/twitter-client-features.d.ts.map +1 -0
  148. package/dist/lib/twitter-client-features.js +347 -0
  149. package/dist/lib/twitter-client-features.js.map +1 -0
  150. package/dist/lib/twitter-client-follow.d.ts +8 -0
  151. package/dist/lib/twitter-client-follow.d.ts.map +1 -0
  152. package/dist/lib/twitter-client-follow.js +178 -0
  153. package/dist/lib/twitter-client-follow.js.map +1 -0
  154. package/dist/lib/twitter-client-home.d.ts +13 -0
  155. package/dist/lib/twitter-client-home.d.ts.map +1 -0
  156. package/dist/lib/twitter-client-home.js +138 -0
  157. package/dist/lib/twitter-client-home.js.map +1 -0
  158. package/dist/lib/twitter-client-lists.d.ts +12 -0
  159. package/dist/lib/twitter-client-lists.d.ts.map +1 -0
  160. package/dist/lib/twitter-client-lists.js +390 -0
  161. package/dist/lib/twitter-client-lists.js.map +1 -0
  162. package/dist/lib/twitter-client-media.d.ts +11 -0
  163. package/dist/lib/twitter-client-media.d.ts.map +1 -0
  164. package/dist/lib/twitter-client-media.js +136 -0
  165. package/dist/lib/twitter-client-media.js.map +1 -0
  166. package/dist/lib/twitter-client-news.d.ts +47 -0
  167. package/dist/lib/twitter-client-news.d.ts.map +1 -0
  168. package/dist/lib/twitter-client-news.js +283 -0
  169. package/dist/lib/twitter-client-news.js.map +1 -0
  170. package/dist/lib/twitter-client-posting.d.ts +8 -0
  171. package/dist/lib/twitter-client-posting.d.ts.map +1 -0
  172. package/dist/lib/twitter-client-posting.js +218 -0
  173. package/dist/lib/twitter-client-posting.js.map +1 -0
  174. package/dist/lib/twitter-client-search.d.ts +19 -0
  175. package/dist/lib/twitter-client-search.d.ts.map +1 -0
  176. package/dist/lib/twitter-client-search.js +157 -0
  177. package/dist/lib/twitter-client-search.js.map +1 -0
  178. package/dist/lib/twitter-client-timelines.d.ts +23 -0
  179. package/dist/lib/twitter-client-timelines.d.ts.map +1 -0
  180. package/dist/lib/twitter-client-timelines.js +471 -0
  181. package/dist/lib/twitter-client-timelines.js.map +1 -0
  182. package/dist/lib/twitter-client-tweet-detail.d.ts +25 -0
  183. package/dist/lib/twitter-client-tweet-detail.d.ts.map +1 -0
  184. package/dist/lib/twitter-client-tweet-detail.js +295 -0
  185. package/dist/lib/twitter-client-tweet-detail.js.map +1 -0
  186. package/dist/lib/twitter-client-types.d.ts +407 -0
  187. package/dist/lib/twitter-client-types.d.ts.map +1 -0
  188. package/dist/lib/twitter-client-types.js +2 -0
  189. package/dist/lib/twitter-client-types.js.map +1 -0
  190. package/dist/lib/twitter-client-user-lookup.d.ts +16 -0
  191. package/dist/lib/twitter-client-user-lookup.d.ts.map +1 -0
  192. package/dist/lib/twitter-client-user-lookup.js +224 -0
  193. package/dist/lib/twitter-client-user-lookup.js.map +1 -0
  194. package/dist/lib/twitter-client-user-tweets.d.ts +22 -0
  195. package/dist/lib/twitter-client-user-tweets.d.ts.map +1 -0
  196. package/dist/lib/twitter-client-user-tweets.js +154 -0
  197. package/dist/lib/twitter-client-user-tweets.js.map +1 -0
  198. package/dist/lib/twitter-client-users.d.ts +9 -0
  199. package/dist/lib/twitter-client-users.d.ts.map +1 -0
  200. package/dist/lib/twitter-client-users.js +358 -0
  201. package/dist/lib/twitter-client-users.js.map +1 -0
  202. package/dist/lib/twitter-client-utils.d.ts +173 -0
  203. package/dist/lib/twitter-client-utils.d.ts.map +1 -0
  204. package/dist/lib/twitter-client-utils.js +511 -0
  205. package/dist/lib/twitter-client-utils.js.map +1 -0
  206. package/dist/lib/twitter-client.d.ts +23 -0
  207. package/dist/lib/twitter-client.d.ts.map +1 -0
  208. package/dist/lib/twitter-client.js +21 -0
  209. package/dist/lib/twitter-client.js.map +1 -0
  210. package/dist/lib/version.d.ts +6 -0
  211. package/dist/lib/version.d.ts.map +1 -0
  212. package/dist/lib/version.js +174 -0
  213. package/dist/lib/version.js.map +1 -0
  214. package/package.json +61 -0
@@ -0,0 +1,283 @@
1
+ import { TWITTER_API_BASE } from './twitter-client-constants.js';
2
+ import { buildExploreFeatures } from './twitter-client-features.js';
3
+ const POST_COUNT_REGEX = /[\d.]+[KMB]?\s*posts?/i;
4
+ const POST_COUNT_MATCH_REGEX = /([\d.]+)([KMB]?)\s*posts?/i;
5
+ // Timeline IDs for different Explore tabs
6
+ const TIMELINE_IDS = {
7
+ forYou: 'VGltZWxpbmU6DAC2CwABAAAAB2Zvcl95b3UAAA==',
8
+ trending: 'VGltZWxpbmU6DAC2CwABAAAACHRyZW5kaW5nAAA=',
9
+ news: 'VGltZWxpbmU6DAC2CwABAAAABG5ld3MAAA==',
10
+ sports: 'VGltZWxpbmU6DAC2CwABAAAABnNwb3J0cwAA',
11
+ entertainment: 'VGltZWxpbmU6DAC2CwABAAAADWVudGVydGFpbm1lbnQAAA==',
12
+ };
13
+ export function withNews(Base) {
14
+ class TwitterClientNews extends Base {
15
+ // biome-ignore lint/complexity/noUselessConstructor lint/suspicious/noExplicitAny: TS mixin constructor requirement.
16
+ constructor(...args) {
17
+ super(...args);
18
+ }
19
+ /**
20
+ * Fetch news and trending topics from Twitter's Explore page tabs
21
+ */
22
+ async getNews(count = 10, options = {}) {
23
+ const { includeRaw = false, withTweets = false, tweetsPerItem = 5, aiOnly = false, tabs = ['forYou', 'news', 'sports', 'entertainment'], } = options;
24
+ const debug = process.env.BIRD_DEBUG === '1';
25
+ if (debug) {
26
+ console.error(`[getNews] Fetching from tabs: ${tabs.join(', ')}`);
27
+ }
28
+ const allItems = [];
29
+ const seenHeadlines = new Set();
30
+ // Fetch from each tab
31
+ for (const tab of tabs) {
32
+ const timelineId = TIMELINE_IDS[tab];
33
+ if (!timelineId) {
34
+ continue;
35
+ }
36
+ try {
37
+ const tabItems = await this.fetchTimelineTab(tab, timelineId, count, aiOnly, includeRaw);
38
+ // Deduplicate across tabs
39
+ for (const item of tabItems) {
40
+ if (!seenHeadlines.has(item.headline)) {
41
+ seenHeadlines.add(item.headline);
42
+ allItems.push(item);
43
+ }
44
+ }
45
+ if (debug) {
46
+ console.error(`[getNews] Tab ${tab}: found ${tabItems.length} items, total unique: ${allItems.length}`);
47
+ }
48
+ // Stop early if we have enough
49
+ if (allItems.length >= count) {
50
+ break;
51
+ }
52
+ }
53
+ catch (error) {
54
+ if (debug) {
55
+ console.error(`[getNews] Error fetching tab ${tab}:`, error);
56
+ }
57
+ // Continue with other tabs
58
+ }
59
+ }
60
+ if (allItems.length === 0) {
61
+ return { success: false, error: 'No news items found' };
62
+ }
63
+ // Limit to requested count
64
+ const items = allItems.slice(0, count);
65
+ if (withTweets) {
66
+ await this.enrichWithTweets(items, tweetsPerItem, includeRaw);
67
+ }
68
+ return { success: true, items };
69
+ }
70
+ /**
71
+ * Fetch a specific timeline tab using GenericTimelineById
72
+ */
73
+ async fetchTimelineTab(tabName, timelineId, maxCount, aiOnly, includeRaw) {
74
+ const queryId = await this.getQueryId('GenericTimelineById');
75
+ const features = buildExploreFeatures();
76
+ const variables = {
77
+ timelineId: timelineId,
78
+ count: maxCount * 2, // Fetch more to account for filtering
79
+ includePromotedContent: false,
80
+ };
81
+ const params = new URLSearchParams({
82
+ variables: JSON.stringify(variables),
83
+ features: JSON.stringify(features),
84
+ });
85
+ const url = `${TWITTER_API_BASE}/${queryId}/GenericTimelineById?${params.toString()}`;
86
+ const response = await this.fetchWithTimeout(url, {
87
+ method: 'GET',
88
+ headers: this.getHeaders(),
89
+ });
90
+ if (!response.ok) {
91
+ const text = await response.text();
92
+ throw new Error(`HTTP ${response.status}: ${text.slice(0, 200)}`);
93
+ }
94
+ const data = (await response.json());
95
+ // Debug: save response if BIRD_DEBUG_JSON is set
96
+ if (process.env.BIRD_DEBUG_JSON) {
97
+ const fs = await import('node:fs/promises');
98
+ const debugPath = process.env.BIRD_DEBUG_JSON.replace('.json', `-${tabName}.json`);
99
+ await fs.writeFile(debugPath, JSON.stringify(data, null, 2)).catch(() => { });
100
+ }
101
+ if (data.errors && data.errors.length > 0) {
102
+ throw new Error(data.errors.map((e) => e.message).join('; '));
103
+ }
104
+ // Parse timeline response
105
+ return this.parseTimelineTabItems(data, tabName, maxCount, aiOnly, includeRaw);
106
+ }
107
+ /**
108
+ * Parse items from a GenericTimelineById response
109
+ */
110
+ parseTimelineTabItems(
111
+ // biome-ignore lint/suspicious/noExplicitAny: API response structure is complex
112
+ data, source, maxCount, aiOnly, includeRaw) {
113
+ const items = [];
114
+ const seenHeadlines = new Set();
115
+ // Navigate to timeline instructions
116
+ const timeline = data?.data?.timeline?.timeline;
117
+ if (!timeline) {
118
+ return [];
119
+ }
120
+ const instructions = timeline.instructions || [];
121
+ for (const instruction of instructions) {
122
+ const entries = instruction.entries ?? (instruction.entry ? [instruction.entry] : []);
123
+ if (!entries || entries.length === 0) {
124
+ continue;
125
+ }
126
+ for (const entry of entries) {
127
+ if (items.length >= maxCount) {
128
+ break;
129
+ }
130
+ const content = entry.content;
131
+ if (!content) {
132
+ continue;
133
+ }
134
+ // Handle TimelineTimelineItem (single trend item)
135
+ if (content.itemContent) {
136
+ const newsItem = this.parseNewsItemFromContent(content.itemContent, entry.entryId, source, seenHeadlines, aiOnly, includeRaw);
137
+ if (newsItem) {
138
+ items.push(newsItem);
139
+ }
140
+ }
141
+ // Handle TimelineTimelineModule (multiple items)
142
+ const itemsArray = content?.items || [];
143
+ for (const data of itemsArray) {
144
+ if (items.length >= maxCount) {
145
+ break;
146
+ }
147
+ // Structure can be data.itemContent OR data.item.itemContent
148
+ const itemContent = data?.itemContent || data?.item?.itemContent;
149
+ if (!itemContent) {
150
+ continue;
151
+ }
152
+ const newsItem = this.parseNewsItemFromContent(itemContent, entry.entryId, source, seenHeadlines, aiOnly, includeRaw);
153
+ if (newsItem) {
154
+ items.push(newsItem);
155
+ }
156
+ }
157
+ }
158
+ }
159
+ return items;
160
+ }
161
+ parseNewsItemFromContent(
162
+ // biome-ignore lint/suspicious/noExplicitAny: API response structure is complex
163
+ itemContent, entryId, source, seenHeadlines, aiOnly, includeRaw) {
164
+ const headline = itemContent.name || itemContent.title;
165
+ if (!headline) {
166
+ return null;
167
+ }
168
+ const trendMetadata = itemContent?.trend_metadata;
169
+ const trendUrl = itemContent.trend_url?.url || trendMetadata?.url?.url;
170
+ // Detect AI news by characteristics:
171
+ // 1. Full sentence headlines (contains spaces and is longer)
172
+ // 2. Has social_context with "News" category
173
+ // 3. Or explicitly marked as is_ai_trend
174
+ const socialContext = itemContent?.social_context?.text || '';
175
+ const hasNewsCategory = socialContext.includes('News') || socialContext.includes('hours ago');
176
+ const isFullSentence = headline.split(' ').length >= 5; // AI news are full sentences
177
+ const isExplicitlyAiTrend = itemContent.is_ai_trend === true;
178
+ const isAiNews = isExplicitlyAiTrend || (isFullSentence && hasNewsCategory);
179
+ // Filter AI trends if aiOnly is enabled
180
+ if (aiOnly && !isAiNews) {
181
+ return null;
182
+ }
183
+ if (seenHeadlines.has(headline)) {
184
+ return null;
185
+ }
186
+ seenHeadlines.add(headline);
187
+ let postCount;
188
+ let timeAgo;
189
+ let category = 'Trending';
190
+ // Parse social context for metadata
191
+ const socialCtx = itemContent?.social_context;
192
+ if (socialCtx?.text) {
193
+ const socialContextText = socialCtx.text;
194
+ const parts = socialContextText.split('·').map((s) => s.trim());
195
+ for (const part of parts) {
196
+ if (part.includes('ago')) {
197
+ timeAgo = part;
198
+ }
199
+ else if (part.match(POST_COUNT_REGEX)) {
200
+ const match = part.match(POST_COUNT_MATCH_REGEX);
201
+ if (match) {
202
+ let num = Number.parseFloat(match[1]);
203
+ const suffix = match[2]?.toUpperCase();
204
+ if (suffix === 'K') {
205
+ num *= 1000;
206
+ }
207
+ else if (suffix === 'M') {
208
+ num *= 1_000_000;
209
+ }
210
+ else if (suffix === 'B') {
211
+ num *= 1_000_000_000;
212
+ }
213
+ postCount = Math.round(num);
214
+ }
215
+ }
216
+ else {
217
+ category = part;
218
+ }
219
+ }
220
+ }
221
+ // Parse trend metadata
222
+ if (trendMetadata?.meta_description) {
223
+ const metaDesc = trendMetadata.meta_description;
224
+ const postMatch = metaDesc.match(POST_COUNT_MATCH_REGEX);
225
+ if (postMatch) {
226
+ let num = Number.parseFloat(postMatch[1]);
227
+ const suffix = postMatch[2]?.toUpperCase();
228
+ if (suffix === 'K') {
229
+ num *= 1000;
230
+ }
231
+ else if (suffix === 'M') {
232
+ num *= 1_000_000;
233
+ }
234
+ else if (suffix === 'B') {
235
+ num *= 1_000_000_000;
236
+ }
237
+ postCount = Math.round(num);
238
+ }
239
+ }
240
+ if (trendMetadata?.domain_context && (category === 'Trending' || category === 'News')) {
241
+ category = trendMetadata.domain_context;
242
+ }
243
+ const item = {
244
+ id: trendUrl ?? (entryId ? `${entryId}-${headline}` : `${source}-${headline}`),
245
+ headline,
246
+ category: isAiNews ? `AI · ${category}` : category,
247
+ timeAgo,
248
+ postCount,
249
+ description: itemContent.description,
250
+ url: trendUrl,
251
+ };
252
+ if (includeRaw) {
253
+ item._raw = itemContent;
254
+ }
255
+ return item;
256
+ }
257
+ async enrichWithTweets(items, tweetsPerItem, includeRaw) {
258
+ const debug = process.env.BIRD_DEBUG === '1';
259
+ for (const item of items) {
260
+ try {
261
+ const searchQuery = item.headline;
262
+ if (!searchQuery) {
263
+ continue;
264
+ }
265
+ // Use the search method if available (requires search mixin)
266
+ if ('search' in this && typeof this.search === 'function') {
267
+ const result = (await this.search(searchQuery, tweetsPerItem, { includeRaw }));
268
+ if (result.success && result.tweets) {
269
+ item.tweets = result.tweets;
270
+ }
271
+ }
272
+ }
273
+ catch {
274
+ if (debug) {
275
+ console.error('[getNews] Failed to enrich item with tweets:', item.headline);
276
+ }
277
+ }
278
+ }
279
+ }
280
+ }
281
+ return TwitterClientNews;
282
+ }
283
+ //# sourceMappingURL=twitter-client-news.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"twitter-client-news.js","sourceRoot":"","sources":["../../src/lib/twitter-client-news.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { AbstractConstructor, Mixin, TwitterClientBase } from './twitter-client-base.js';
2
+ import type { TweetResult } from './twitter-client-types.js';
3
+ export interface TwitterClientPostingMethods {
4
+ tweet(text: string, mediaIds?: string[]): Promise<TweetResult>;
5
+ reply(text: string, replyToTweetId: string, mediaIds?: string[]): Promise<TweetResult>;
6
+ }
7
+ export declare function withPosting<TBase extends AbstractConstructor<TwitterClientBase>>(Base: TBase): Mixin<TBase, TwitterClientPostingMethods>;
8
+ //# sourceMappingURL=twitter-client-posting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"twitter-client-posting.d.ts","sourceRoot":"","sources":["../../src/lib/twitter-client-posting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG9F,OAAO,KAAK,EAAuB,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAElF,MAAM,WAAW,2BAA2B;IAC1C,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/D,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACxF;AAED,wBAAgB,WAAW,CAAC,KAAK,SAAS,mBAAmB,CAAC,iBAAiB,CAAC,EAC9E,IAAI,EAAE,KAAK,GACV,KAAK,CAAC,KAAK,EAAE,2BAA2B,CAAC,CAkR3C"}
@@ -0,0 +1,218 @@
1
+ import { TWITTER_API_BASE, TWITTER_GRAPHQL_POST_URL, TWITTER_STATUS_UPDATE_URL } from './twitter-client-constants.js';
2
+ import { buildTweetCreateFeatures } from './twitter-client-features.js';
3
+ export function withPosting(Base) {
4
+ class TwitterClientPosting extends Base {
5
+ // biome-ignore lint/complexity/noUselessConstructor lint/suspicious/noExplicitAny: TS mixin constructor requirement.
6
+ constructor(...args) {
7
+ super(...args);
8
+ }
9
+ /**
10
+ * Post a new tweet
11
+ */
12
+ async tweet(text, mediaIds) {
13
+ const variables = {
14
+ tweet_text: text,
15
+ dark_request: false,
16
+ media: {
17
+ media_entities: (mediaIds ?? []).map((id) => ({ media_id: id, tagged_users: [] })),
18
+ possibly_sensitive: false,
19
+ },
20
+ semantic_annotation_ids: [],
21
+ };
22
+ const features = buildTweetCreateFeatures();
23
+ return this.createTweet(variables, features);
24
+ }
25
+ /**
26
+ * Reply to an existing tweet
27
+ */
28
+ async reply(text, replyToTweetId, mediaIds) {
29
+ const variables = {
30
+ tweet_text: text,
31
+ reply: {
32
+ in_reply_to_tweet_id: replyToTweetId,
33
+ exclude_reply_user_ids: [],
34
+ },
35
+ dark_request: false,
36
+ media: {
37
+ media_entities: (mediaIds ?? []).map((id) => ({ media_id: id, tagged_users: [] })),
38
+ possibly_sensitive: false,
39
+ },
40
+ semantic_annotation_ids: [],
41
+ };
42
+ const features = buildTweetCreateFeatures();
43
+ return this.createTweet(variables, features);
44
+ }
45
+ async createTweet(variables, features) {
46
+ await this.ensureClientUserId();
47
+ let queryId = await this.getQueryId('CreateTweet');
48
+ let urlWithOperation = `${TWITTER_API_BASE}/${queryId}/CreateTweet`;
49
+ const buildBody = () => JSON.stringify({ variables, features, queryId });
50
+ let body = buildBody();
51
+ try {
52
+ const headers = { ...this.getHeaders(), referer: 'https://x.com/compose/post' };
53
+ let response = await this.fetchWithTimeout(urlWithOperation, {
54
+ method: 'POST',
55
+ headers,
56
+ body,
57
+ });
58
+ // Twitter increasingly prefers POST to /i/api/graphql with queryId in the payload.
59
+ // If the operation URL 404s, retry the generic endpoint.
60
+ if (response.status === 404) {
61
+ await this.refreshQueryIds();
62
+ queryId = await this.getQueryId('CreateTweet');
63
+ urlWithOperation = `${TWITTER_API_BASE}/${queryId}/CreateTweet`;
64
+ body = buildBody();
65
+ response = await this.fetchWithTimeout(urlWithOperation, {
66
+ method: 'POST',
67
+ headers: { ...this.getHeaders(), referer: 'https://x.com/compose/post' },
68
+ body,
69
+ });
70
+ if (response.status === 404) {
71
+ const retry = await this.fetchWithTimeout(TWITTER_GRAPHQL_POST_URL, {
72
+ method: 'POST',
73
+ headers: { ...this.getHeaders(), referer: 'https://x.com/compose/post' },
74
+ body,
75
+ });
76
+ if (!retry.ok) {
77
+ const text = await retry.text();
78
+ return { success: false, error: `HTTP ${retry.status}: ${text.slice(0, 200)}` };
79
+ }
80
+ const data = (await retry.json());
81
+ if (data.errors && data.errors.length > 0) {
82
+ const fallback = await this.tryStatusUpdateFallback(data.errors, variables);
83
+ if (fallback) {
84
+ return fallback;
85
+ }
86
+ return { success: false, error: this.formatErrors(data.errors) };
87
+ }
88
+ const tweetId = data.data?.create_tweet?.tweet_results?.result?.rest_id;
89
+ if (tweetId) {
90
+ return { success: true, tweetId };
91
+ }
92
+ return { success: false, error: 'Tweet created but no ID returned' };
93
+ }
94
+ }
95
+ if (!response.ok) {
96
+ const text = await response.text();
97
+ return {
98
+ success: false,
99
+ error: `HTTP ${response.status}: ${text.slice(0, 200)}`,
100
+ };
101
+ }
102
+ const data = (await response.json());
103
+ if (data.errors && data.errors.length > 0) {
104
+ const fallback = await this.tryStatusUpdateFallback(data.errors, variables);
105
+ if (fallback) {
106
+ return fallback;
107
+ }
108
+ return {
109
+ success: false,
110
+ error: this.formatErrors(data.errors),
111
+ };
112
+ }
113
+ const tweetId = data.data?.create_tweet?.tweet_results?.result?.rest_id;
114
+ if (tweetId) {
115
+ return {
116
+ success: true,
117
+ tweetId,
118
+ };
119
+ }
120
+ return {
121
+ success: false,
122
+ error: 'Tweet created but no ID returned',
123
+ };
124
+ }
125
+ catch (error) {
126
+ return {
127
+ success: false,
128
+ error: error instanceof Error ? error.message : String(error),
129
+ };
130
+ }
131
+ }
132
+ formatErrors(errors) {
133
+ return errors
134
+ .map((error) => (typeof error.code === 'number' ? `${error.message} (${error.code})` : error.message))
135
+ .join(', ');
136
+ }
137
+ statusUpdateInputFromCreateTweetVariables(variables) {
138
+ const text = typeof variables.tweet_text === 'string' ? variables.tweet_text : null;
139
+ if (!text) {
140
+ return null;
141
+ }
142
+ const reply = variables.reply;
143
+ const inReplyToTweetId = reply &&
144
+ typeof reply === 'object' &&
145
+ typeof reply.in_reply_to_tweet_id === 'string'
146
+ ? reply.in_reply_to_tweet_id
147
+ : undefined;
148
+ const media = variables.media;
149
+ const mediaEntities = media && typeof media === 'object' ? media.media_entities : undefined;
150
+ const mediaIds = Array.isArray(mediaEntities)
151
+ ? mediaEntities
152
+ .map((entity) => entity && typeof entity === 'object' && 'media_id' in entity
153
+ ? entity.media_id
154
+ : undefined)
155
+ .filter((value) => typeof value === 'string' || typeof value === 'number')
156
+ .map((value) => String(value))
157
+ : undefined;
158
+ return { text, inReplyToTweetId, mediaIds: mediaIds && mediaIds.length > 0 ? mediaIds : undefined };
159
+ }
160
+ async postStatusUpdate(input) {
161
+ const params = new URLSearchParams();
162
+ params.set('status', input.text);
163
+ if (input.inReplyToTweetId) {
164
+ params.set('in_reply_to_status_id', input.inReplyToTweetId);
165
+ params.set('auto_populate_reply_metadata', 'true');
166
+ }
167
+ if (input.mediaIds && input.mediaIds.length > 0) {
168
+ params.set('media_ids', input.mediaIds.join(','));
169
+ }
170
+ try {
171
+ const response = await this.fetchWithTimeout(TWITTER_STATUS_UPDATE_URL, {
172
+ method: 'POST',
173
+ headers: {
174
+ ...this.getBaseHeaders(),
175
+ 'content-type': 'application/x-www-form-urlencoded',
176
+ referer: 'https://x.com/compose/post',
177
+ },
178
+ body: params.toString(),
179
+ });
180
+ if (!response.ok) {
181
+ const text = await response.text();
182
+ return { success: false, error: `HTTP ${response.status}: ${text.slice(0, 200)}` };
183
+ }
184
+ const data = (await response.json());
185
+ if (data.errors && data.errors.length > 0) {
186
+ return { success: false, error: this.formatErrors(data.errors) };
187
+ }
188
+ const tweetId = typeof data.id_str === 'string' ? data.id_str : data.id !== undefined ? String(data.id) : undefined;
189
+ if (tweetId) {
190
+ return { success: true, tweetId };
191
+ }
192
+ return { success: false, error: 'Tweet created but no ID returned' };
193
+ }
194
+ catch (error) {
195
+ return { success: false, error: error instanceof Error ? error.message : String(error) };
196
+ }
197
+ }
198
+ async tryStatusUpdateFallback(errors, variables) {
199
+ if (!errors.some((error) => error.code === 226)) {
200
+ return null;
201
+ }
202
+ const input = this.statusUpdateInputFromCreateTweetVariables(variables);
203
+ if (!input) {
204
+ return null;
205
+ }
206
+ const fallback = await this.postStatusUpdate(input);
207
+ if (fallback.success) {
208
+ return fallback;
209
+ }
210
+ return {
211
+ success: false,
212
+ error: `${this.formatErrors(errors)} | fallback: ${fallback.error ?? 'Unknown error'}`,
213
+ };
214
+ }
215
+ }
216
+ return TwitterClientPosting;
217
+ }
218
+ //# sourceMappingURL=twitter-client-posting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"twitter-client-posting.js","sourceRoot":"","sources":["../../src/lib/twitter-client-posting.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { AbstractConstructor, Mixin, TwitterClientBase } from './twitter-client-base.js';
2
+ import type { SearchResult } from './twitter-client-types.js';
3
+ /** Options for search methods */
4
+ export interface SearchFetchOptions {
5
+ /** Include raw GraphQL response in `_raw` field */
6
+ includeRaw?: boolean;
7
+ }
8
+ /** Options for paged search methods */
9
+ export interface SearchPaginationOptions extends SearchFetchOptions {
10
+ maxPages?: number;
11
+ /** Starting cursor for pagination (resume from previous fetch) */
12
+ cursor?: string;
13
+ }
14
+ export interface TwitterClientSearchMethods {
15
+ search(query: string, count?: number, options?: SearchFetchOptions): Promise<SearchResult>;
16
+ getAllSearchResults(query: string, options?: SearchPaginationOptions): Promise<SearchResult>;
17
+ }
18
+ export declare function withSearch<TBase extends AbstractConstructor<TwitterClientBase>>(Base: TBase): Mixin<TBase, TwitterClientSearchMethods>;
19
+ //# sourceMappingURL=twitter-client-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"twitter-client-search.d.ts","sourceRoot":"","sources":["../../src/lib/twitter-client-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG9F,OAAO,KAAK,EAAE,YAAY,EAAa,MAAM,2BAA2B,CAAC;AAKzE,iCAAiC;AACjC,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,uCAAuC;AACvC,MAAM,WAAW,uBAAwB,SAAQ,kBAAkB;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC3F,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC9F;AAuBD,wBAAgB,UAAU,CAAC,KAAK,SAAS,mBAAmB,CAAC,iBAAiB,CAAC,EAC7E,IAAI,EAAE,KAAK,GACV,KAAK,CAAC,KAAK,EAAE,0BAA0B,CAAC,CA0M1C"}