@the-convocation/twitter-scraper 0.18.3 → 0.19.1
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.
- package/README.md +35 -0
- package/dist/cycletls/cjs/index.cjs +99 -0
- package/dist/cycletls/cjs/index.cjs.map +1 -0
- package/dist/cycletls/esm/index.mjs +96 -0
- package/dist/cycletls/esm/index.mjs.map +1 -0
- package/dist/cycletls/index.d.ts +11 -0
- package/dist/default/cjs/index.js +100 -25
- package/dist/default/cjs/index.js.map +1 -1
- package/dist/default/esm/index.mjs +100 -25
- package/dist/default/esm/index.mjs.map +1 -1
- package/dist/node/cjs/index.cjs +100 -25
- package/dist/node/cjs/index.cjs.map +1 -1
- package/dist/node/esm/index.mjs +100 -25
- package/dist/node/esm/index.mjs.map +1 -1
- package/examples/cycletls/README.md +48 -0
- package/examples/cycletls/package.json +13 -0
- package/package.json +25 -9
- package/rollup.config.mjs +34 -0
package/dist/node/esm/index.mjs
CHANGED
|
@@ -51,13 +51,13 @@ class AuthenticationError extends Error {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
const log$
|
|
54
|
+
const log$4 = debug("twitter-scraper:rate-limit");
|
|
55
55
|
class WaitingRateLimitStrategy {
|
|
56
56
|
async onRateLimit({ response: res }) {
|
|
57
57
|
const xRateLimitLimit = res.headers.get("x-rate-limit-limit");
|
|
58
58
|
const xRateLimitRemaining = res.headers.get("x-rate-limit-remaining");
|
|
59
59
|
const xRateLimitReset = res.headers.get("x-rate-limit-reset");
|
|
60
|
-
log$
|
|
60
|
+
log$4(
|
|
61
61
|
`Rate limit event: limit=${xRateLimitLimit}, remaining=${xRateLimitRemaining}, reset=${xRateLimitReset}`
|
|
62
62
|
);
|
|
63
63
|
if (xRateLimitRemaining == "0" && xRateLimitReset) {
|
|
@@ -86,16 +86,47 @@ class Platform {
|
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
const log$3 = debug("twitter-scraper:requests");
|
|
89
90
|
async function updateCookieJar(cookieJar, headers) {
|
|
90
|
-
|
|
91
|
-
if (
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
91
|
+
let setCookieHeaders = [];
|
|
92
|
+
if (typeof headers.getSetCookie === "function") {
|
|
93
|
+
setCookieHeaders = headers.getSetCookie();
|
|
94
|
+
} else {
|
|
95
|
+
const setCookieHeader = headers.get("set-cookie");
|
|
96
|
+
if (setCookieHeader) {
|
|
97
|
+
setCookieHeaders = setCookie.splitCookiesString(setCookieHeader);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (setCookieHeaders.length > 0) {
|
|
101
|
+
for (const cookieStr of setCookieHeaders) {
|
|
102
|
+
const cookie = Cookie.parse(cookieStr);
|
|
103
|
+
if (!cookie) {
|
|
104
|
+
log$3(`Failed to parse cookie: ${cookieStr.substring(0, 100)}`);
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (cookie.maxAge === 0 || cookie.expires && cookie.expires < /* @__PURE__ */ new Date()) {
|
|
108
|
+
if (cookie.key === "ct0") {
|
|
109
|
+
log$3(`Skipping deletion of ct0 cookie (Max-Age=0)`);
|
|
110
|
+
}
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
const url = `${cookie.secure ? "https" : "http"}://${cookie.domain}${cookie.path}`;
|
|
115
|
+
await cookieJar.setCookie(cookie, url);
|
|
116
|
+
if (cookie.key === "ct0") {
|
|
117
|
+
log$3(
|
|
118
|
+
`Successfully set ct0 cookie with value: ${cookie.value.substring(
|
|
119
|
+
0,
|
|
120
|
+
20
|
|
121
|
+
)}...`
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
} catch (err) {
|
|
125
|
+
log$3(`Failed to set cookie ${cookie.key}: ${err}`);
|
|
126
|
+
if (cookie.key === "ct0") {
|
|
127
|
+
log$3(`FAILED to set ct0 cookie! Error: ${err}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
99
130
|
}
|
|
100
131
|
} else if (typeof document !== "undefined") {
|
|
101
132
|
for (const cookie of document.cookie.split(";")) {
|
|
@@ -113,9 +144,8 @@ async function jitter(maxMs) {
|
|
|
113
144
|
const jitter2 = Math.random() * maxMs;
|
|
114
145
|
await new Promise((resolve) => setTimeout(resolve, jitter2));
|
|
115
146
|
}
|
|
116
|
-
async function requestApi(url, auth, method = "GET", platform = new Platform()) {
|
|
147
|
+
async function requestApi(url, auth, method = "GET", platform = new Platform(), headers = new Headers()) {
|
|
117
148
|
log$2(`Making ${method} request to ${url}`);
|
|
118
|
-
const headers = new Headers();
|
|
119
149
|
await auth.installTo(headers, url);
|
|
120
150
|
await platform.randomizeCiphers();
|
|
121
151
|
let res;
|
|
@@ -154,7 +184,7 @@ async function requestApi(url, auth, method = "GET", platform = new Platform())
|
|
|
154
184
|
err: await ApiError.fromResponse(res)
|
|
155
185
|
};
|
|
156
186
|
}
|
|
157
|
-
const value = await res
|
|
187
|
+
const value = await flexParseJson(res);
|
|
158
188
|
if (res.headers.get("x-rate-limit-incoming") == "0") {
|
|
159
189
|
auth.deleteToken();
|
|
160
190
|
return { success: true, value };
|
|
@@ -162,6 +192,16 @@ async function requestApi(url, auth, method = "GET", platform = new Platform())
|
|
|
162
192
|
return { success: true, value };
|
|
163
193
|
}
|
|
164
194
|
}
|
|
195
|
+
async function flexParseJson(res) {
|
|
196
|
+
try {
|
|
197
|
+
return await res.json();
|
|
198
|
+
} catch {
|
|
199
|
+
log$2("Failed to parse response as JSON, trying text parse...");
|
|
200
|
+
const text = await res.text();
|
|
201
|
+
log$2("Response text:", text);
|
|
202
|
+
return JSON.parse(text);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
165
205
|
function addApiFeatures(o) {
|
|
166
206
|
return {
|
|
167
207
|
...o,
|
|
@@ -294,6 +334,10 @@ class TwitterGuestAuth {
|
|
|
294
334
|
}
|
|
295
335
|
headers.set("authorization", `Bearer ${this.bearerToken}`);
|
|
296
336
|
headers.set("x-guest-token", token);
|
|
337
|
+
headers.set(
|
|
338
|
+
"user-agent",
|
|
339
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"
|
|
340
|
+
);
|
|
297
341
|
const cookies = await this.getCookies();
|
|
298
342
|
const xCsrfToken = cookies.find((cookie) => cookie.key === "ct0");
|
|
299
343
|
if (xCsrfToken) {
|
|
@@ -301,6 +345,16 @@ class TwitterGuestAuth {
|
|
|
301
345
|
}
|
|
302
346
|
headers.set("cookie", await this.getCookieString());
|
|
303
347
|
}
|
|
348
|
+
async setCookie(key, value) {
|
|
349
|
+
const cookie = Cookie.parse(`${key}=${value}`);
|
|
350
|
+
if (!cookie) {
|
|
351
|
+
throw new Error("Failed to parse cookie.");
|
|
352
|
+
}
|
|
353
|
+
await this.jar.setCookie(cookie, this.getCookieJarUrl());
|
|
354
|
+
if (typeof document !== "undefined") {
|
|
355
|
+
document.cookie = cookie.toString();
|
|
356
|
+
}
|
|
357
|
+
}
|
|
304
358
|
async getCookies() {
|
|
305
359
|
return this.jar.getCookies(this.getCookieJarUrl());
|
|
306
360
|
}
|
|
@@ -341,7 +395,7 @@ class TwitterGuestAuth {
|
|
|
341
395
|
if (!res.ok) {
|
|
342
396
|
throw new AuthenticationError(await res.text());
|
|
343
397
|
}
|
|
344
|
-
const o = await res
|
|
398
|
+
const o = await flexParseJson(res);
|
|
345
399
|
if (o == null || o["guest_token"] == null) {
|
|
346
400
|
throw new AuthenticationError("guest_token not found.");
|
|
347
401
|
}
|
|
@@ -351,6 +405,8 @@ class TwitterGuestAuth {
|
|
|
351
405
|
}
|
|
352
406
|
this.guestToken = newGuestToken;
|
|
353
407
|
this.guestCreatedAt = /* @__PURE__ */ new Date();
|
|
408
|
+
await this.setCookie("gt", newGuestToken);
|
|
409
|
+
log$1(`Updated guest token: ${newGuestToken}`);
|
|
354
410
|
}
|
|
355
411
|
/**
|
|
356
412
|
* Returns if the authentication token needs to be updated or not.
|
|
@@ -477,7 +533,15 @@ class TwitterUserAuth extends TwitterGuestAuth {
|
|
|
477
533
|
}
|
|
478
534
|
async installTo(headers) {
|
|
479
535
|
headers.set("authorization", `Bearer ${this.bearerToken}`);
|
|
480
|
-
|
|
536
|
+
const cookie = await this.getCookieString();
|
|
537
|
+
headers.set("cookie", cookie);
|
|
538
|
+
if (this.guestToken) {
|
|
539
|
+
headers.set("x-guest-token", this.guestToken);
|
|
540
|
+
}
|
|
541
|
+
headers.set(
|
|
542
|
+
"user-agent",
|
|
543
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"
|
|
544
|
+
);
|
|
481
545
|
await this.installCsrfToken(headers);
|
|
482
546
|
}
|
|
483
547
|
async initLogin() {
|
|
@@ -690,16 +754,27 @@ class TwitterUserAuth extends TwitterGuestAuth {
|
|
|
690
754
|
);
|
|
691
755
|
}
|
|
692
756
|
const headers = new Headers({
|
|
693
|
-
|
|
694
|
-
|
|
757
|
+
accept: "*/*",
|
|
758
|
+
"accept-language": "en-US,en;q=0.9",
|
|
695
759
|
"content-type": "application/json",
|
|
696
|
-
"
|
|
760
|
+
"cache-control": "no-cache",
|
|
761
|
+
origin: "https://x.com",
|
|
762
|
+
pragma: "no-cache",
|
|
763
|
+
priority: "u=1, i",
|
|
764
|
+
referer: "https://x.com/",
|
|
765
|
+
"sec-ch-ua": '"Google Chrome";v="135", "Not-A.Brand";v="8", "Chromium";v="135"',
|
|
766
|
+
"sec-ch-ua-mobile": "?0",
|
|
767
|
+
"sec-ch-ua-platform": '"Windows"',
|
|
768
|
+
"sec-fetch-dest": "empty",
|
|
769
|
+
"sec-fetch-mode": "cors",
|
|
770
|
+
"sec-fetch-site": "same-origin",
|
|
771
|
+
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36",
|
|
697
772
|
"x-guest-token": token,
|
|
698
773
|
"x-twitter-auth-type": "OAuth2Client",
|
|
699
774
|
"x-twitter-active-user": "yes",
|
|
700
775
|
"x-twitter-client-language": "en"
|
|
701
776
|
});
|
|
702
|
-
await this.
|
|
777
|
+
await this.installTo(headers);
|
|
703
778
|
let res;
|
|
704
779
|
do {
|
|
705
780
|
const fetchParameters = [
|
|
@@ -734,7 +809,7 @@ class TwitterUserAuth extends TwitterGuestAuth {
|
|
|
734
809
|
if (!res.ok) {
|
|
735
810
|
return { status: "error", err: await ApiError.fromResponse(res) };
|
|
736
811
|
}
|
|
737
|
-
const flow = await res
|
|
812
|
+
const flow = await flexParseJson(res);
|
|
738
813
|
if (flow?.flow_token == null) {
|
|
739
814
|
return {
|
|
740
815
|
status: "error",
|
|
@@ -772,12 +847,12 @@ class TwitterUserAuth extends TwitterGuestAuth {
|
|
|
772
847
|
|
|
773
848
|
const endpoints = {
|
|
774
849
|
// TODO: Migrate other endpoint URLs here
|
|
775
|
-
UserTweets: "https://
|
|
850
|
+
UserTweets: "https://x.com/i/api/graphql/oRJs8SLCRNRbQzuZG93_oA/UserTweets?variables=%7B%22userId%22%3A%221806359170830172162%22%2C%22count%22%3A20%2C%22includePromotedContent%22%3Atrue%2C%22withQuickPromoteEligibilityTweetFields%22%3Atrue%2C%22withVoice%22%3Atrue%7D&features=%7B%22rweb_video_screen_enabled%22%3Afalse%2C%22payments_enabled%22%3Afalse%2C%22profile_label_improvements_pcf_label_in_post_enabled%22%3Atrue%2C%22responsive_web_profile_redirect_enabled%22%3Afalse%2C%22rweb_tipjar_consumption_enabled%22%3Atrue%2C%22verified_phone_label_enabled%22%3Afalse%2C%22creator_subscriptions_tweet_preview_api_enabled%22%3Atrue%2C%22responsive_web_graphql_timeline_navigation_enabled%22%3Atrue%2C%22responsive_web_graphql_skip_user_profile_image_extensions_enabled%22%3Afalse%2C%22premium_content_api_read_enabled%22%3Afalse%2C%22communities_web_enable_tweet_community_results_fetch%22%3Atrue%2C%22c9s_tweet_anatomy_moderator_badge_enabled%22%3Atrue%2C%22responsive_web_grok_analyze_button_fetch_trends_enabled%22%3Afalse%2C%22responsive_web_grok_analyze_post_followups_enabled%22%3Atrue%2C%22responsive_web_jetfuel_frame%22%3Atrue%2C%22responsive_web_grok_share_attachment_enabled%22%3Atrue%2C%22articles_preview_enabled%22%3Atrue%2C%22responsive_web_edit_tweet_api_enabled%22%3Atrue%2C%22graphql_is_translatable_rweb_tweet_is_translatable_enabled%22%3Atrue%2C%22view_counts_everywhere_api_enabled%22%3Atrue%2C%22longform_notetweets_consumption_enabled%22%3Atrue%2C%22responsive_web_twitter_article_tweet_consumption_enabled%22%3Atrue%2C%22tweet_awards_web_tipping_enabled%22%3Afalse%2C%22responsive_web_grok_show_grok_translated_post%22%3Atrue%2C%22responsive_web_grok_analysis_button_from_backend%22%3Atrue%2C%22creator_subscriptions_quote_tweet_preview_enabled%22%3Afalse%2C%22freedom_of_speech_not_reach_fetch_enabled%22%3Atrue%2C%22standardized_nudges_misinfo%22%3Atrue%2C%22tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled%22%3Atrue%2C%22longform_notetweets_rich_text_read_enabled%22%3Atrue%2C%22longform_notetweets_inline_media_enabled%22%3Atrue%2C%22responsive_web_grok_image_annotation_enabled%22%3Atrue%2C%22responsive_web_grok_imagine_annotation_enabled%22%3Atrue%2C%22responsive_web_grok_community_note_auto_translation_is_enabled%22%3Afalse%2C%22responsive_web_enhance_cards_enabled%22%3Afalse%7D&fieldToggles=%7B%22withArticlePlainText%22%3Afalse%7D",
|
|
776
851
|
UserTweetsAndReplies: "https://x.com/i/api/graphql/Hk4KlJ-ONjlJsucqR55P7g/UserTweetsAndReplies?variables=%7B%22userId%22%3A%221806359170830172162%22%2C%22count%22%3A20%2C%22includePromotedContent%22%3Atrue%2C%22withCommunity%22%3Atrue%2C%22withVoice%22%3Atrue%7D&features=%7B%22rweb_video_screen_enabled%22%3Afalse%2C%22profile_label_improvements_pcf_label_in_post_enabled%22%3Atrue%2C%22rweb_tipjar_consumption_enabled%22%3Atrue%2C%22verified_phone_label_enabled%22%3Afalse%2C%22creator_subscriptions_tweet_preview_api_enabled%22%3Atrue%2C%22responsive_web_graphql_timeline_navigation_enabled%22%3Atrue%2C%22responsive_web_graphql_skip_user_profile_image_extensions_enabled%22%3Afalse%2C%22premium_content_api_read_enabled%22%3Afalse%2C%22communities_web_enable_tweet_community_results_fetch%22%3Atrue%2C%22c9s_tweet_anatomy_moderator_badge_enabled%22%3Atrue%2C%22responsive_web_grok_analyze_button_fetch_trends_enabled%22%3Afalse%2C%22responsive_web_grok_analyze_post_followups_enabled%22%3Atrue%2C%22responsive_web_jetfuel_frame%22%3Afalse%2C%22responsive_web_grok_share_attachment_enabled%22%3Atrue%2C%22articles_preview_enabled%22%3Atrue%2C%22responsive_web_edit_tweet_api_enabled%22%3Atrue%2C%22graphql_is_translatable_rweb_tweet_is_translatable_enabled%22%3Atrue%2C%22view_counts_everywhere_api_enabled%22%3Atrue%2C%22longform_notetweets_consumption_enabled%22%3Atrue%2C%22responsive_web_twitter_article_tweet_consumption_enabled%22%3Atrue%2C%22tweet_awards_web_tipping_enabled%22%3Afalse%2C%22responsive_web_grok_show_grok_translated_post%22%3Afalse%2C%22responsive_web_grok_analysis_button_from_backend%22%3Atrue%2C%22creator_subscriptions_quote_tweet_preview_enabled%22%3Afalse%2C%22freedom_of_speech_not_reach_fetch_enabled%22%3Atrue%2C%22standardized_nudges_misinfo%22%3Atrue%2C%22tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled%22%3Atrue%2C%22longform_notetweets_rich_text_read_enabled%22%3Atrue%2C%22longform_notetweets_inline_media_enabled%22%3Atrue%2C%22responsive_web_grok_image_annotation_enabled%22%3Atrue%2C%22responsive_web_enhance_cards_enabled%22%3Afalse%7D&fieldToggles=%7B%22withArticlePlainText%22%3Afalse%7D",
|
|
777
852
|
UserLikedTweets: "https://x.com/i/api/graphql/XHTMjDbiTGLQ9cP1em-aqQ/Likes?variables=%7B%22userId%22%3A%222244196397%22%2C%22count%22%3A20%2C%22includePromotedContent%22%3Afalse%2C%22withClientEventToken%22%3Afalse%2C%22withBirdwatchNotes%22%3Afalse%2C%22withVoice%22%3Atrue%7D&features=%7B%22rweb_video_screen_enabled%22%3Afalse%2C%22profile_label_improvements_pcf_label_in_post_enabled%22%3Atrue%2C%22rweb_tipjar_consumption_enabled%22%3Atrue%2C%22verified_phone_label_enabled%22%3Afalse%2C%22creator_subscriptions_tweet_preview_api_enabled%22%3Atrue%2C%22responsive_web_graphql_timeline_navigation_enabled%22%3Atrue%2C%22responsive_web_graphql_skip_user_profile_image_extensions_enabled%22%3Afalse%2C%22premium_content_api_read_enabled%22%3Afalse%2C%22communities_web_enable_tweet_community_results_fetch%22%3Atrue%2C%22c9s_tweet_anatomy_moderator_badge_enabled%22%3Atrue%2C%22responsive_web_grok_analyze_button_fetch_trends_enabled%22%3Afalse%2C%22responsive_web_grok_analyze_post_followups_enabled%22%3Atrue%2C%22responsive_web_jetfuel_frame%22%3Afalse%2C%22responsive_web_grok_share_attachment_enabled%22%3Atrue%2C%22articles_preview_enabled%22%3Atrue%2C%22responsive_web_edit_tweet_api_enabled%22%3Atrue%2C%22graphql_is_translatable_rweb_tweet_is_translatable_enabled%22%3Atrue%2C%22view_counts_everywhere_api_enabled%22%3Atrue%2C%22longform_notetweets_consumption_enabled%22%3Atrue%2C%22responsive_web_twitter_article_tweet_consumption_enabled%22%3Atrue%2C%22tweet_awards_web_tipping_enabled%22%3Afalse%2C%22responsive_web_grok_show_grok_translated_post%22%3Afalse%2C%22responsive_web_grok_analysis_button_from_backend%22%3Atrue%2C%22creator_subscriptions_quote_tweet_preview_enabled%22%3Afalse%2C%22freedom_of_speech_not_reach_fetch_enabled%22%3Atrue%2C%22standardized_nudges_misinfo%22%3Atrue%2C%22tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled%22%3Atrue%2C%22longform_notetweets_rich_text_read_enabled%22%3Atrue%2C%22longform_notetweets_inline_media_enabled%22%3Atrue%2C%22responsive_web_grok_image_annotation_enabled%22%3Atrue%2C%22responsive_web_enhance_cards_enabled%22%3Afalse%7D&fieldToggles=%7B%22withArticlePlainText%22%3Afalse%7D",
|
|
778
|
-
UserByScreenName: "https://
|
|
779
|
-
TweetDetail: "https://x.com/i/api/graphql/
|
|
780
|
-
TweetResultByRestId: "https://api.x.com/graphql/
|
|
853
|
+
UserByScreenName: "https://x.com/i/api/graphql/ZHSN3WlvahPKVvUxVQbg1A/UserByScreenName?variables=%7B%22screen_name%22%3A%22geminiapp%22%2C%22withGrokTranslatedBio%22%3Atrue%7D&features=%7B%22hidden_profile_subscriptions_enabled%22%3Atrue%2C%22payments_enabled%22%3Afalse%2C%22profile_label_improvements_pcf_label_in_post_enabled%22%3Atrue%2C%22responsive_web_profile_redirect_enabled%22%3Afalse%2C%22rweb_tipjar_consumption_enabled%22%3Atrue%2C%22verified_phone_label_enabled%22%3Afalse%2C%22subscriptions_verification_info_is_identity_verified_enabled%22%3Atrue%2C%22subscriptions_verification_info_verified_since_enabled%22%3Atrue%2C%22highlights_tweets_tab_ui_enabled%22%3Atrue%2C%22responsive_web_twitter_article_notes_tab_enabled%22%3Atrue%2C%22subscriptions_feature_can_gift_premium%22%3Atrue%2C%22creator_subscriptions_tweet_preview_api_enabled%22%3Atrue%2C%22responsive_web_graphql_skip_user_profile_image_extensions_enabled%22%3Afalse%2C%22responsive_web_graphql_timeline_navigation_enabled%22%3Atrue%7D&fieldToggles=%7B%22withAuxiliaryUserLabels%22%3Atrue%7D",
|
|
854
|
+
TweetDetail: "https://x.com/i/api/graphql/YVyS4SfwYW7Uw5qwy0mQCA/TweetDetail?variables=%7B%22focalTweetId%22%3A%221985465713096794294%22%2C%22referrer%22%3A%22profile%22%2C%22with_rux_injections%22%3Afalse%2C%22rankingMode%22%3A%22Relevance%22%2C%22includePromotedContent%22%3Atrue%2C%22withCommunity%22%3Atrue%2C%22withQuickPromoteEligibilityTweetFields%22%3Atrue%2C%22withBirdwatchNotes%22%3Atrue%2C%22withVoice%22%3Atrue%7D&features=%7B%22rweb_video_screen_enabled%22%3Afalse%2C%22payments_enabled%22%3Afalse%2C%22profile_label_improvements_pcf_label_in_post_enabled%22%3Atrue%2C%22responsive_web_profile_redirect_enabled%22%3Afalse%2C%22rweb_tipjar_consumption_enabled%22%3Atrue%2C%22verified_phone_label_enabled%22%3Afalse%2C%22creator_subscriptions_tweet_preview_api_enabled%22%3Atrue%2C%22responsive_web_graphql_timeline_navigation_enabled%22%3Atrue%2C%22responsive_web_graphql_skip_user_profile_image_extensions_enabled%22%3Afalse%2C%22premium_content_api_read_enabled%22%3Afalse%2C%22communities_web_enable_tweet_community_results_fetch%22%3Atrue%2C%22c9s_tweet_anatomy_moderator_badge_enabled%22%3Atrue%2C%22responsive_web_grok_analyze_button_fetch_trends_enabled%22%3Afalse%2C%22responsive_web_grok_analyze_post_followups_enabled%22%3Atrue%2C%22responsive_web_jetfuel_frame%22%3Atrue%2C%22responsive_web_grok_share_attachment_enabled%22%3Atrue%2C%22articles_preview_enabled%22%3Atrue%2C%22responsive_web_edit_tweet_api_enabled%22%3Atrue%2C%22graphql_is_translatable_rweb_tweet_is_translatable_enabled%22%3Atrue%2C%22view_counts_everywhere_api_enabled%22%3Atrue%2C%22longform_notetweets_consumption_enabled%22%3Atrue%2C%22responsive_web_twitter_article_tweet_consumption_enabled%22%3Atrue%2C%22tweet_awards_web_tipping_enabled%22%3Afalse%2C%22responsive_web_grok_show_grok_translated_post%22%3Atrue%2C%22responsive_web_grok_analysis_button_from_backend%22%3Atrue%2C%22creator_subscriptions_quote_tweet_preview_enabled%22%3Afalse%2C%22freedom_of_speech_not_reach_fetch_enabled%22%3Atrue%2C%22standardized_nudges_misinfo%22%3Atrue%2C%22tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled%22%3Atrue%2C%22longform_notetweets_rich_text_read_enabled%22%3Atrue%2C%22longform_notetweets_inline_media_enabled%22%3Atrue%2C%22responsive_web_grok_image_annotation_enabled%22%3Atrue%2C%22responsive_web_grok_imagine_annotation_enabled%22%3Atrue%2C%22responsive_web_grok_community_note_auto_translation_is_enabled%22%3Afalse%2C%22responsive_web_enhance_cards_enabled%22%3Afalse%7D&fieldToggles=%7B%22withArticleRichContentState%22%3Atrue%2C%22withArticlePlainText%22%3Afalse%2C%22withGrokAnalyze%22%3Afalse%2C%22withDisallowedReplyControls%22%3Afalse%7D",
|
|
855
|
+
TweetResultByRestId: "https://api.x.com/graphql/tCVRZ3WCvoj0BVO7BKnL-Q/TweetResultByRestId?variables=%7B%22tweetId%22%3A%221985465713096794294%22%2C%22withCommunity%22%3Afalse%2C%22includePromotedContent%22%3Afalse%2C%22withVoice%22%3Afalse%7D&features=%7B%22creator_subscriptions_tweet_preview_api_enabled%22%3Atrue%2C%22premium_content_api_read_enabled%22%3Afalse%2C%22communities_web_enable_tweet_community_results_fetch%22%3Atrue%2C%22c9s_tweet_anatomy_moderator_badge_enabled%22%3Atrue%2C%22responsive_web_grok_analyze_button_fetch_trends_enabled%22%3Afalse%2C%22responsive_web_grok_analyze_post_followups_enabled%22%3Afalse%2C%22responsive_web_jetfuel_frame%22%3Atrue%2C%22responsive_web_grok_share_attachment_enabled%22%3Atrue%2C%22articles_preview_enabled%22%3Atrue%2C%22responsive_web_edit_tweet_api_enabled%22%3Atrue%2C%22graphql_is_translatable_rweb_tweet_is_translatable_enabled%22%3Atrue%2C%22view_counts_everywhere_api_enabled%22%3Atrue%2C%22longform_notetweets_consumption_enabled%22%3Atrue%2C%22responsive_web_twitter_article_tweet_consumption_enabled%22%3Atrue%2C%22tweet_awards_web_tipping_enabled%22%3Afalse%2C%22responsive_web_grok_show_grok_translated_post%22%3Afalse%2C%22responsive_web_grok_analysis_button_from_backend%22%3Atrue%2C%22creator_subscriptions_quote_tweet_preview_enabled%22%3Afalse%2C%22freedom_of_speech_not_reach_fetch_enabled%22%3Atrue%2C%22standardized_nudges_misinfo%22%3Atrue%2C%22tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled%22%3Atrue%2C%22longform_notetweets_rich_text_read_enabled%22%3Atrue%2C%22longform_notetweets_inline_media_enabled%22%3Atrue%2C%22payments_enabled%22%3Afalse%2C%22profile_label_improvements_pcf_label_in_post_enabled%22%3Atrue%2C%22responsive_web_profile_redirect_enabled%22%3Afalse%2C%22rweb_tipjar_consumption_enabled%22%3Atrue%2C%22verified_phone_label_enabled%22%3Afalse%2C%22responsive_web_grok_image_annotation_enabled%22%3Atrue%2C%22responsive_web_grok_imagine_annotation_enabled%22%3Atrue%2C%22responsive_web_grok_community_note_auto_translation_is_enabled%22%3Afalse%2C%22responsive_web_graphql_skip_user_profile_image_extensions_enabled%22%3Afalse%2C%22responsive_web_graphql_timeline_navigation_enabled%22%3Atrue%2C%22responsive_web_enhance_cards_enabled%22%3Afalse%7D&fieldToggles=%7B%22withArticleRichContentState%22%3Atrue%2C%22withArticlePlainText%22%3Afalse%2C%22withGrokAnalyze%22%3Afalse%2C%22withDisallowedReplyControls%22%3Afalse%7D",
|
|
781
856
|
ListTweets: "https://x.com/i/api/graphql/S1Sm3_mNJwa-fnY9htcaAQ/ListLatestTweetsTimeline?variables=%7B%22listId%22%3A%221736495155002106192%22%2C%22count%22%3A20%7D&features=%7B%22rweb_video_screen_enabled%22%3Afalse%2C%22profile_label_improvements_pcf_label_in_post_enabled%22%3Atrue%2C%22rweb_tipjar_consumption_enabled%22%3Atrue%2C%22verified_phone_label_enabled%22%3Afalse%2C%22creator_subscriptions_tweet_preview_api_enabled%22%3Atrue%2C%22responsive_web_graphql_timeline_navigation_enabled%22%3Atrue%2C%22responsive_web_graphql_skip_user_profile_image_extensions_enabled%22%3Afalse%2C%22premium_content_api_read_enabled%22%3Afalse%2C%22communities_web_enable_tweet_community_results_fetch%22%3Atrue%2C%22c9s_tweet_anatomy_moderator_badge_enabled%22%3Atrue%2C%22responsive_web_grok_analyze_button_fetch_trends_enabled%22%3Afalse%2C%22responsive_web_grok_analyze_post_followups_enabled%22%3Atrue%2C%22responsive_web_jetfuel_frame%22%3Afalse%2C%22responsive_web_grok_share_attachment_enabled%22%3Atrue%2C%22articles_preview_enabled%22%3Atrue%2C%22responsive_web_edit_tweet_api_enabled%22%3Atrue%2C%22graphql_is_translatable_rweb_tweet_is_translatable_enabled%22%3Atrue%2C%22view_counts_everywhere_api_enabled%22%3Atrue%2C%22longform_notetweets_consumption_enabled%22%3Atrue%2C%22responsive_web_twitter_article_tweet_consumption_enabled%22%3Atrue%2C%22tweet_awards_web_tipping_enabled%22%3Afalse%2C%22responsive_web_grok_show_grok_translated_post%22%3Afalse%2C%22responsive_web_grok_analysis_button_from_backend%22%3Atrue%2C%22creator_subscriptions_quote_tweet_preview_enabled%22%3Afalse%2C%22freedom_of_speech_not_reach_fetch_enabled%22%3Atrue%2C%22standardized_nudges_misinfo%22%3Atrue%2C%22tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled%22%3Atrue%2C%22longform_notetweets_rich_text_read_enabled%22%3Atrue%2C%22longform_notetweets_inline_media_enabled%22%3Atrue%2C%22responsive_web_grok_image_annotation_enabled%22%3Atrue%2C%22responsive_web_enhance_cards_enabled%22%3Afalse%7D"
|
|
782
857
|
};
|
|
783
858
|
class ApiRequest {
|