@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
|
@@ -49,13 +49,13 @@ class AuthenticationError extends Error {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
const log$
|
|
52
|
+
const log$4 = debug("twitter-scraper:rate-limit");
|
|
53
53
|
class WaitingRateLimitStrategy {
|
|
54
54
|
async onRateLimit({ response: res }) {
|
|
55
55
|
const xRateLimitLimit = res.headers.get("x-rate-limit-limit");
|
|
56
56
|
const xRateLimitRemaining = res.headers.get("x-rate-limit-remaining");
|
|
57
57
|
const xRateLimitReset = res.headers.get("x-rate-limit-reset");
|
|
58
|
-
log$
|
|
58
|
+
log$4(
|
|
59
59
|
`Rate limit event: limit=${xRateLimitLimit}, remaining=${xRateLimitRemaining}, reset=${xRateLimitReset}`
|
|
60
60
|
);
|
|
61
61
|
if (xRateLimitRemaining == "0" && xRateLimitReset) {
|
|
@@ -87,16 +87,47 @@ class Platform {
|
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
const log$3 = debug("twitter-scraper:requests");
|
|
90
91
|
async function updateCookieJar(cookieJar, headers) {
|
|
91
|
-
|
|
92
|
-
if (
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
92
|
+
let setCookieHeaders = [];
|
|
93
|
+
if (typeof headers.getSetCookie === "function") {
|
|
94
|
+
setCookieHeaders = headers.getSetCookie();
|
|
95
|
+
} else {
|
|
96
|
+
const setCookieHeader = headers.get("set-cookie");
|
|
97
|
+
if (setCookieHeader) {
|
|
98
|
+
setCookieHeaders = setCookie.splitCookiesString(setCookieHeader);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (setCookieHeaders.length > 0) {
|
|
102
|
+
for (const cookieStr of setCookieHeaders) {
|
|
103
|
+
const cookie = Cookie.parse(cookieStr);
|
|
104
|
+
if (!cookie) {
|
|
105
|
+
log$3(`Failed to parse cookie: ${cookieStr.substring(0, 100)}`);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (cookie.maxAge === 0 || cookie.expires && cookie.expires < /* @__PURE__ */ new Date()) {
|
|
109
|
+
if (cookie.key === "ct0") {
|
|
110
|
+
log$3(`Skipping deletion of ct0 cookie (Max-Age=0)`);
|
|
111
|
+
}
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
const url = `${cookie.secure ? "https" : "http"}://${cookie.domain}${cookie.path}`;
|
|
116
|
+
await cookieJar.setCookie(cookie, url);
|
|
117
|
+
if (cookie.key === "ct0") {
|
|
118
|
+
log$3(
|
|
119
|
+
`Successfully set ct0 cookie with value: ${cookie.value.substring(
|
|
120
|
+
0,
|
|
121
|
+
20
|
|
122
|
+
)}...`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
} catch (err) {
|
|
126
|
+
log$3(`Failed to set cookie ${cookie.key}: ${err}`);
|
|
127
|
+
if (cookie.key === "ct0") {
|
|
128
|
+
log$3(`FAILED to set ct0 cookie! Error: ${err}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
100
131
|
}
|
|
101
132
|
} else if (typeof document !== "undefined") {
|
|
102
133
|
for (const cookie of document.cookie.split(";")) {
|
|
@@ -114,9 +145,8 @@ async function jitter(maxMs) {
|
|
|
114
145
|
const jitter2 = Math.random() * maxMs;
|
|
115
146
|
await new Promise((resolve) => setTimeout(resolve, jitter2));
|
|
116
147
|
}
|
|
117
|
-
async function requestApi(url, auth, method = "GET", platform = new Platform()) {
|
|
148
|
+
async function requestApi(url, auth, method = "GET", platform = new Platform(), headers = new Headers()) {
|
|
118
149
|
log$2(`Making ${method} request to ${url}`);
|
|
119
|
-
const headers = new Headers();
|
|
120
150
|
await auth.installTo(headers, url);
|
|
121
151
|
await platform.randomizeCiphers();
|
|
122
152
|
let res;
|
|
@@ -155,7 +185,7 @@ async function requestApi(url, auth, method = "GET", platform = new Platform())
|
|
|
155
185
|
err: await ApiError.fromResponse(res)
|
|
156
186
|
};
|
|
157
187
|
}
|
|
158
|
-
const value = await res
|
|
188
|
+
const value = await flexParseJson(res);
|
|
159
189
|
if (res.headers.get("x-rate-limit-incoming") == "0") {
|
|
160
190
|
auth.deleteToken();
|
|
161
191
|
return { success: true, value };
|
|
@@ -163,6 +193,16 @@ async function requestApi(url, auth, method = "GET", platform = new Platform())
|
|
|
163
193
|
return { success: true, value };
|
|
164
194
|
}
|
|
165
195
|
}
|
|
196
|
+
async function flexParseJson(res) {
|
|
197
|
+
try {
|
|
198
|
+
return await res.json();
|
|
199
|
+
} catch {
|
|
200
|
+
log$2("Failed to parse response as JSON, trying text parse...");
|
|
201
|
+
const text = await res.text();
|
|
202
|
+
log$2("Response text:", text);
|
|
203
|
+
return JSON.parse(text);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
166
206
|
function addApiFeatures(o) {
|
|
167
207
|
return {
|
|
168
208
|
...o,
|
|
@@ -295,6 +335,10 @@ class TwitterGuestAuth {
|
|
|
295
335
|
}
|
|
296
336
|
headers.set("authorization", `Bearer ${this.bearerToken}`);
|
|
297
337
|
headers.set("x-guest-token", token);
|
|
338
|
+
headers.set(
|
|
339
|
+
"user-agent",
|
|
340
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"
|
|
341
|
+
);
|
|
298
342
|
const cookies = await this.getCookies();
|
|
299
343
|
const xCsrfToken = cookies.find((cookie) => cookie.key === "ct0");
|
|
300
344
|
if (xCsrfToken) {
|
|
@@ -302,6 +346,16 @@ class TwitterGuestAuth {
|
|
|
302
346
|
}
|
|
303
347
|
headers.set("cookie", await this.getCookieString());
|
|
304
348
|
}
|
|
349
|
+
async setCookie(key, value) {
|
|
350
|
+
const cookie = Cookie.parse(`${key}=${value}`);
|
|
351
|
+
if (!cookie) {
|
|
352
|
+
throw new Error("Failed to parse cookie.");
|
|
353
|
+
}
|
|
354
|
+
await this.jar.setCookie(cookie, this.getCookieJarUrl());
|
|
355
|
+
if (typeof document !== "undefined") {
|
|
356
|
+
document.cookie = cookie.toString();
|
|
357
|
+
}
|
|
358
|
+
}
|
|
305
359
|
async getCookies() {
|
|
306
360
|
return this.jar.getCookies(this.getCookieJarUrl());
|
|
307
361
|
}
|
|
@@ -342,7 +396,7 @@ class TwitterGuestAuth {
|
|
|
342
396
|
if (!res.ok) {
|
|
343
397
|
throw new AuthenticationError(await res.text());
|
|
344
398
|
}
|
|
345
|
-
const o = await res
|
|
399
|
+
const o = await flexParseJson(res);
|
|
346
400
|
if (o == null || o["guest_token"] == null) {
|
|
347
401
|
throw new AuthenticationError("guest_token not found.");
|
|
348
402
|
}
|
|
@@ -352,6 +406,8 @@ class TwitterGuestAuth {
|
|
|
352
406
|
}
|
|
353
407
|
this.guestToken = newGuestToken;
|
|
354
408
|
this.guestCreatedAt = /* @__PURE__ */ new Date();
|
|
409
|
+
await this.setCookie("gt", newGuestToken);
|
|
410
|
+
log$1(`Updated guest token: ${newGuestToken}`);
|
|
355
411
|
}
|
|
356
412
|
/**
|
|
357
413
|
* Returns if the authentication token needs to be updated or not.
|
|
@@ -478,7 +534,15 @@ class TwitterUserAuth extends TwitterGuestAuth {
|
|
|
478
534
|
}
|
|
479
535
|
async installTo(headers) {
|
|
480
536
|
headers.set("authorization", `Bearer ${this.bearerToken}`);
|
|
481
|
-
|
|
537
|
+
const cookie = await this.getCookieString();
|
|
538
|
+
headers.set("cookie", cookie);
|
|
539
|
+
if (this.guestToken) {
|
|
540
|
+
headers.set("x-guest-token", this.guestToken);
|
|
541
|
+
}
|
|
542
|
+
headers.set(
|
|
543
|
+
"user-agent",
|
|
544
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"
|
|
545
|
+
);
|
|
482
546
|
await this.installCsrfToken(headers);
|
|
483
547
|
}
|
|
484
548
|
async initLogin() {
|
|
@@ -691,16 +755,27 @@ class TwitterUserAuth extends TwitterGuestAuth {
|
|
|
691
755
|
);
|
|
692
756
|
}
|
|
693
757
|
const headers = new Headers({
|
|
694
|
-
|
|
695
|
-
|
|
758
|
+
accept: "*/*",
|
|
759
|
+
"accept-language": "en-US,en;q=0.9",
|
|
696
760
|
"content-type": "application/json",
|
|
697
|
-
"
|
|
761
|
+
"cache-control": "no-cache",
|
|
762
|
+
origin: "https://x.com",
|
|
763
|
+
pragma: "no-cache",
|
|
764
|
+
priority: "u=1, i",
|
|
765
|
+
referer: "https://x.com/",
|
|
766
|
+
"sec-ch-ua": '"Google Chrome";v="135", "Not-A.Brand";v="8", "Chromium";v="135"',
|
|
767
|
+
"sec-ch-ua-mobile": "?0",
|
|
768
|
+
"sec-ch-ua-platform": '"Windows"',
|
|
769
|
+
"sec-fetch-dest": "empty",
|
|
770
|
+
"sec-fetch-mode": "cors",
|
|
771
|
+
"sec-fetch-site": "same-origin",
|
|
772
|
+
"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",
|
|
698
773
|
"x-guest-token": token,
|
|
699
774
|
"x-twitter-auth-type": "OAuth2Client",
|
|
700
775
|
"x-twitter-active-user": "yes",
|
|
701
776
|
"x-twitter-client-language": "en"
|
|
702
777
|
});
|
|
703
|
-
await this.
|
|
778
|
+
await this.installTo(headers);
|
|
704
779
|
let res;
|
|
705
780
|
do {
|
|
706
781
|
const fetchParameters = [
|
|
@@ -735,7 +810,7 @@ class TwitterUserAuth extends TwitterGuestAuth {
|
|
|
735
810
|
if (!res.ok) {
|
|
736
811
|
return { status: "error", err: await ApiError.fromResponse(res) };
|
|
737
812
|
}
|
|
738
|
-
const flow = await res
|
|
813
|
+
const flow = await flexParseJson(res);
|
|
739
814
|
if (flow?.flow_token == null) {
|
|
740
815
|
return {
|
|
741
816
|
status: "error",
|
|
@@ -773,12 +848,12 @@ class TwitterUserAuth extends TwitterGuestAuth {
|
|
|
773
848
|
|
|
774
849
|
const endpoints = {
|
|
775
850
|
// TODO: Migrate other endpoint URLs here
|
|
776
|
-
UserTweets: "https://
|
|
851
|
+
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",
|
|
777
852
|
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",
|
|
778
853
|
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",
|
|
779
|
-
UserByScreenName: "https://
|
|
780
|
-
TweetDetail: "https://x.com/i/api/graphql/
|
|
781
|
-
TweetResultByRestId: "https://api.x.com/graphql/
|
|
854
|
+
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",
|
|
855
|
+
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",
|
|
856
|
+
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",
|
|
782
857
|
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"
|
|
783
858
|
};
|
|
784
859
|
class ApiRequest {
|