@the-convocation/twitter-scraper 0.18.2 → 0.19.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.
- 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 +80 -26
- package/dist/default/cjs/index.js.map +1 -1
- package/dist/default/esm/index.mjs +80 -26
- package/dist/default/esm/index.mjs.map +1 -1
- package/dist/node/cjs/index.cjs +80 -26
- package/dist/node/cjs/index.cjs.map +1 -1
- package/dist/node/esm/index.mjs +80 -26
- package/dist/node/esm/index.mjs.map +1 -1
- package/examples/cycletls/README.md +54 -0
- package/examples/cycletls/package.json +12 -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;
|
|
@@ -302,6 +332,16 @@ class TwitterGuestAuth {
|
|
|
302
332
|
}
|
|
303
333
|
headers.set("cookie", await this.getCookieString());
|
|
304
334
|
}
|
|
335
|
+
async setCookie(key, value) {
|
|
336
|
+
const cookie = Cookie.parse(`${key}=${value}`);
|
|
337
|
+
if (!cookie) {
|
|
338
|
+
throw new Error("Failed to parse cookie.");
|
|
339
|
+
}
|
|
340
|
+
await this.jar.setCookie(cookie, this.getCookieJarUrl());
|
|
341
|
+
if (typeof document !== "undefined") {
|
|
342
|
+
document.cookie = cookie.toString();
|
|
343
|
+
}
|
|
344
|
+
}
|
|
305
345
|
async getCookies() {
|
|
306
346
|
return this.jar.getCookies(this.getCookieJarUrl());
|
|
307
347
|
}
|
|
@@ -352,6 +392,8 @@ class TwitterGuestAuth {
|
|
|
352
392
|
}
|
|
353
393
|
this.guestToken = newGuestToken;
|
|
354
394
|
this.guestCreatedAt = /* @__PURE__ */ new Date();
|
|
395
|
+
await this.setCookie("gt", newGuestToken);
|
|
396
|
+
log$1(`Updated guest token: ${newGuestToken}`);
|
|
355
397
|
}
|
|
356
398
|
/**
|
|
357
399
|
* Returns if the authentication token needs to be updated or not.
|
|
@@ -478,7 +520,11 @@ class TwitterUserAuth extends TwitterGuestAuth {
|
|
|
478
520
|
}
|
|
479
521
|
async installTo(headers) {
|
|
480
522
|
headers.set("authorization", `Bearer ${this.bearerToken}`);
|
|
481
|
-
|
|
523
|
+
const cookie = await this.getCookieString();
|
|
524
|
+
headers.set("cookie", cookie);
|
|
525
|
+
if (this.guestToken) {
|
|
526
|
+
headers.set("x-guest-token", this.guestToken);
|
|
527
|
+
}
|
|
482
528
|
await this.installCsrfToken(headers);
|
|
483
529
|
}
|
|
484
530
|
async initLogin() {
|
|
@@ -691,16 +737,27 @@ class TwitterUserAuth extends TwitterGuestAuth {
|
|
|
691
737
|
);
|
|
692
738
|
}
|
|
693
739
|
const headers = new Headers({
|
|
694
|
-
|
|
695
|
-
|
|
740
|
+
accept: "*/*",
|
|
741
|
+
"accept-language": "en-US,en;q=0.9",
|
|
696
742
|
"content-type": "application/json",
|
|
697
|
-
"
|
|
743
|
+
"cache-control": "no-cache",
|
|
744
|
+
origin: "https://x.com",
|
|
745
|
+
pragma: "no-cache",
|
|
746
|
+
priority: "u=1, i",
|
|
747
|
+
referer: "https://x.com/",
|
|
748
|
+
"sec-ch-ua": '"Google Chrome";v="135", "Not-A.Brand";v="8", "Chromium";v="135"',
|
|
749
|
+
"sec-ch-ua-mobile": "?0",
|
|
750
|
+
"sec-ch-ua-platform": '"Windows"',
|
|
751
|
+
"sec-fetch-dest": "empty",
|
|
752
|
+
"sec-fetch-mode": "cors",
|
|
753
|
+
"sec-fetch-site": "same-origin",
|
|
754
|
+
"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
755
|
"x-guest-token": token,
|
|
699
756
|
"x-twitter-auth-type": "OAuth2Client",
|
|
700
757
|
"x-twitter-active-user": "yes",
|
|
701
758
|
"x-twitter-client-language": "en"
|
|
702
759
|
});
|
|
703
|
-
await this.
|
|
760
|
+
await this.installTo(headers);
|
|
704
761
|
let res;
|
|
705
762
|
do {
|
|
706
763
|
const fetchParameters = [
|
|
@@ -773,12 +830,12 @@ class TwitterUserAuth extends TwitterGuestAuth {
|
|
|
773
830
|
|
|
774
831
|
const endpoints = {
|
|
775
832
|
// TODO: Migrate other endpoint URLs here
|
|
776
|
-
UserTweets: "https://x.com/
|
|
833
|
+
UserTweets: "https://api.x.com/graphql/VfoNveT-zJPGVZMPydZUfQ/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%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%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%3Afalse%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
834
|
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
835
|
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://x.com/
|
|
836
|
+
UserByScreenName: "https://api.x.com/graphql/96tVxbPqMZDoYB5pmzezKA/UserByScreenName?variables=%7B%22screen_name%22%3A%22geminiapp%22%2C%22withGrokTranslatedBio%22%3Afalse%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%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",
|
|
780
837
|
TweetDetail: "https://x.com/i/api/graphql/u5Tij6ERlSH2LZvCUqallw/TweetDetail?variables=%7B%22focalTweetId%22%3A%221924893675529900467%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%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%22withArticleRichContentState%22%3Atrue%2C%22withArticlePlainText%22%3Afalse%2C%22withGrokAnalyze%22%3Afalse%2C%22withDisallowedReplyControls%22%3Afalse%7D",
|
|
781
|
-
TweetResultByRestId: "https://api.x.com/graphql/
|
|
838
|
+
TweetResultByRestId: "https://api.x.com/graphql/wqi5M7wZ7tW-X9S2t-Mqcg/TweetResultByRestId?variables=%7B%22tweetId%22%3A%221924893675529900467%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%3Afalse%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%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
839
|
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
840
|
};
|
|
784
841
|
class ApiRequest {
|
|
@@ -869,19 +926,16 @@ function parseProfile(legacy, isBlueVerified) {
|
|
|
869
926
|
async function getProfile(username, auth) {
|
|
870
927
|
const request = apiRequestFactory.createUserByScreenNameRequest();
|
|
871
928
|
request.variables.screen_name = username;
|
|
872
|
-
request.variables.withSafetyModeUserFields = true;
|
|
873
|
-
request.features.hidden_profile_subscriptions_enabled = false;
|
|
874
|
-
request.fieldToggles.withAuxiliaryUserLabels = false;
|
|
875
929
|
const res = await requestApi(request.toRequestUrl(), auth);
|
|
876
930
|
if (!res.success) {
|
|
877
931
|
return res;
|
|
878
932
|
}
|
|
879
933
|
const { value } = res;
|
|
880
934
|
const { errors } = value;
|
|
881
|
-
if (errors != null && errors.length > 0) {
|
|
935
|
+
if ((!value.data || !value.data.user || !value.data.user.result) && errors != null && errors.length > 0) {
|
|
882
936
|
return {
|
|
883
937
|
success: false,
|
|
884
|
-
err: new Error(errors
|
|
938
|
+
err: new Error(errors.map((e) => e.message).join("\n"))
|
|
885
939
|
};
|
|
886
940
|
}
|
|
887
941
|
if (!value.data || !value.data.user || !value.data.user.result) {
|