@the-convocation/twitter-scraper 0.18.3 → 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.
@@ -49,13 +49,13 @@ class AuthenticationError extends Error {
49
49
  }
50
50
  }
51
51
 
52
- const log$3 = debug("twitter-scraper:rate-limit");
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$3(
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
- const setCookieHeader = headers.get("set-cookie");
92
- if (setCookieHeader) {
93
- const cookies = setCookie.splitCookiesString(setCookieHeader);
94
- for (const cookie of cookies.map((c) => Cookie.parse(c))) {
95
- if (!cookie) continue;
96
- await cookieJar.setCookie(
97
- cookie,
98
- `${cookie.secure ? "https" : "http"}://${cookie.domain}${cookie.path}`
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
- headers.set("cookie", await this.getCookieString());
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
- authorization: `Bearer ${this.bearerToken}`,
695
- cookie: await this.getCookieString(),
740
+ accept: "*/*",
741
+ "accept-language": "en-US,en;q=0.9",
696
742
  "content-type": "application/json",
697
- "User-Agent": "Mozilla/5.0 (Linux; Android 11; Nokia G20) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.88 Mobile Safari/537.36",
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.installCsrfToken(headers);
760
+ await this.installTo(headers);
704
761
  let res;
705
762
  do {
706
763
  const fetchParameters = [