emusks 2.3.8 → 2.3.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "emusks",
3
- "version": "2.3.8",
3
+ "version": "2.3.10",
4
4
  "description": "Reverse-engineered Twitter API client. Log in and interact with the unofficial X API using any client identity - web, Android, iOS, or TweetDeck",
5
5
  "keywords": [
6
6
  "client",
@@ -146,10 +146,10 @@ function extractUserId(cookies) {
146
146
  return null;
147
147
  }
148
148
 
149
- async function resolve(value, onRequest, type) {
149
+ async function resolve(value, onRequest, type, context) {
150
150
  if (value != null && value !== "") return value;
151
151
  if (onRequest) {
152
- const v = await onRequest(type);
152
+ const v = await onRequest(type, context);
153
153
  if (v != null && v !== "") return v;
154
154
  }
155
155
  throw new Error(
@@ -267,7 +267,8 @@ export default async function flowLoginJetfuel(opts) {
267
267
  if (passwordSwitch) {
268
268
  const knowledgeCheck = response.forms.find((form) => form.url === "/onboarding/web/actions/finish_knowledge_check");
269
269
  if (knowledgeCheck && onRequest) {
270
- const alternate = await onRequest("alternate_identifier");
270
+ const kc = knowledgeCheck.fields;
271
+ const alternate = await onRequest("alternate_identifier", { challengeType: kc.challenge_type ?? null, accountFound: kc.account_found ?? null, accountFoundType: kc.account_found_type ?? null });
271
272
  if (alternate != null && alternate !== "") {
272
273
  response = await post("finish_knowledge_check", { ...knowledgeCheck.fields, challenge_response: alternate });
273
274
  strings = response.strings;
@@ -300,7 +301,7 @@ export default async function flowLoginJetfuel(opts) {
300
301
  if (challenge === "email") alternate = email || (identifier.includes("@") ? identifier : null);
301
302
  if (challenge === "phone") alternate = phone;
302
303
  }
303
- fields[field] = await resolve(alternate, onRequest, type);
304
+ fields[field] = await resolve(alternate, onRequest, type, { challengeType: fields.challenge_type ?? null, accountFound: fields.account_found ?? null, accountFoundType: fields.account_found_type ?? null });
304
305
  }
305
306
  response = await post(action, fields);
306
307
  strings = response.strings;
@@ -52,7 +52,8 @@ export async function viewer() {
52
52
  fieldToggles: { withAuxiliaryUserLabels: false },
53
53
  });
54
54
  const user = res?.data?.viewer?.user_results?.result;
55
- return user ? parseUser(user) : res;
55
+ if (!user) throw new Error("couldn't get viewer, response: " + JSON.stringify(res));
56
+ return parseUser(user);
56
57
  }
57
58
 
58
59
  export async function sessions() {
@@ -241,7 +241,8 @@ export async function get(tweetId) {
241
241
  },
242
242
  });
243
243
  const tweet = res?.data?.tweetResult?.result;
244
- return tweet ? parseTweet(tweet) : res;
244
+ if (!tweet) throw new Error("couldn't get tweet, response: " + JSON.stringify(res));
245
+ return parseTweet(tweet);
245
246
  }
246
247
 
247
248
  export async function getMany(tweetIds) {
@@ -7,7 +7,8 @@ export async function get(userId) {
7
7
  fieldToggles: { withAuxiliaryUserLabels: false },
8
8
  });
9
9
  const user = res?.data?.user?.result;
10
- return user ? parseUser(user) : res;
10
+ if (!user) throw new Error("couldn't get user, response: " + JSON.stringify(res));
11
+ return parseUser(user);
11
12
  }
12
13
 
13
14
  export async function getByUsername(username) {
@@ -16,7 +17,8 @@ export async function getByUsername(username) {
16
17
  fieldToggles: { withAuxiliaryUserLabels: false },
17
18
  });
18
19
  const user = res?.data?.user?.result;
19
- return user ? parseUser(user) : res;
20
+ if (!user) throw new Error("couldn't get user, response: " + JSON.stringify(res));
21
+ return parseUser(user);
20
22
  }
21
23
 
22
24
  export async function getMany(userIds) {
@@ -64,6 +64,10 @@ export default function parseTweet(tweet) {
64
64
  ? parseTweet(get(tweet, "quoted_status_result.result"))
65
65
  : null,
66
66
 
67
+ retweeting: legacy.retweeted_status_result?.result
68
+ ? parseTweet(legacy.retweeted_status_result.result)
69
+ : null,
70
+
67
71
  edit_control: data.edit_control || {},
68
72
  card: data.card || null,
69
73
  unmention_data: data.unmention_data || {},
@@ -27,15 +27,19 @@ export default function parseUser(user) {
27
27
  legacy.screen_name ||
28
28
  data.screen_name ||
29
29
  data.username,
30
- description: legacy.description || data.description,
30
+ description:
31
+ get(data, "profile_bio.description") ??
32
+ legacy.description ??
33
+ data.description,
31
34
  banner:
35
+ get(data, "banner.image_url") ||
32
36
  legacy.profile_banner_url ||
33
37
  legacy.profile_background_image_url ||
34
38
  legacy.profile_background_image_url_https ||
35
39
  data.profile_banner_url ||
36
40
  data.profile_background_image_url ||
37
41
  data.profile_background_image_url_https,
38
- url: legacy.url || data.url,
42
+ url: get(data, "website.url") || legacy.url || data.url,
39
43
  location: locationObj.location || legacy.location || data.location || null,
40
44
  protected: get(
41
45
  data,
@@ -61,21 +65,36 @@ export default function parseUser(user) {
61
65
 
62
66
  stats: {
63
67
  followers: {
64
- count: legacy.followers_count || data.followers_count,
68
+ count:
69
+ get(data, "relationship_counts.followers") ??
70
+ legacy.followers_count ??
71
+ data.followers_count,
65
72
  fast_followers:
66
73
  legacy.fast_followers_count || data.fast_followers_count || 0,
67
74
  normal_followers:
68
75
  legacy.normal_followers_count || data.normal_followers_count,
69
76
  },
70
- following: legacy.friends_count || data.friends_count,
77
+ following:
78
+ get(data, "relationship_counts.following") ??
79
+ legacy.friends_count ??
80
+ data.friends_count,
71
81
  subscriptions_count:
72
82
  data.creator_subscriptions_count ||
73
83
  legacy.creator_subscriptions_count ||
74
84
  0,
75
- likes: legacy.favourites_count || data.favourites_count,
85
+ likes:
86
+ get(data, "action_counts.favorites_count") ??
87
+ legacy.favourites_count ??
88
+ data.favourites_count,
76
89
  listed: legacy.listed_count || data.listed_count,
77
- media: legacy.media_count || data.media_count,
78
- posts: legacy.statuses_count || data.statuses_count,
90
+ media:
91
+ get(data, "tweet_counts.media_tweets") ??
92
+ legacy.media_count ??
93
+ data.media_count,
94
+ posts:
95
+ get(data, "tweet_counts.tweets") ??
96
+ legacy.statuses_count ??
97
+ data.statuses_count,
79
98
  },
80
99
  verification: {
81
100
  verified: get(verification, "verified", legacy.verified || data.verified),
@@ -87,22 +106,31 @@ export default function parseUser(user) {
87
106
  false,
88
107
  },
89
108
  pinned_tweets:
90
- legacy.pinned_tweet_ids_str || data.pinned_tweet_ids_str || [],
91
- birthdate: data.birthdate || {},
109
+ get(data, "pinned_items.tweet_ids_str") ||
110
+ legacy.pinned_tweet_ids_str ||
111
+ data.pinned_tweet_ids_str ||
112
+ [],
113
+ birthdate:
114
+ get(data, "legacy_extended_profile.birthdate") || data.birthdate || {},
92
115
  misc: {
93
116
  default_profile: legacy.default_profile || data.default_profile,
94
117
  default_profile_image:
95
118
  legacy.default_profile_image || data.default_profile_image || false,
96
- entities: legacy.entities || data.entities,
119
+ entities: get(data, "profile_bio.entities") || legacy.entities || data.entities,
97
120
  has_custom_timelines:
98
121
  legacy.has_custom_timelines || data.has_custom_timelines,
99
122
  is_translator: legacy.is_translator || data.is_translator || false,
100
- translator_type: legacy.translator_type || data.translator_type,
123
+ translator_type:
124
+ get(data, "profile_translation.translator_type") ||
125
+ legacy.translator_type ||
126
+ data.translator_type,
101
127
  is_profile_translatable: data.is_profile_translatable,
102
128
  needs_phone_verification: data.needs_phone_verification,
103
129
  possibly_sensitive: legacy.possibly_sensitive || data.possibly_sensitive,
104
130
  profile_interstitial_type:
105
- legacy.profile_interstitial_type || data.profile_interstitial_type,
131
+ get(data, "profile_metadata.profile_interstitial_type") ??
132
+ legacy.profile_interstitial_type ??
133
+ data.profile_interstitial_type,
106
134
  want_retweets: legacy.want_retweets || data.want_retweets,
107
135
  withheld_in_countries:
108
136
  legacy.withheld_in_countries || data.withheld_in_countries || [],
@@ -115,16 +143,25 @@ export default function parseUser(user) {
115
143
  ),
116
144
  blocked_by: get(
117
145
  data,
118
- "relationship_perspectives.followed_by",
146
+ "relationship_perspectives.blocked_by",
119
147
  data.blocked_by
120
148
  ),
121
- blocking: data.blocking,
149
+ blocking: get(
150
+ data,
151
+ "relationship_perspectives.blocking",
152
+ data.blocking
153
+ ),
154
+ followed_by: get(
155
+ data,
156
+ "relationship_perspectives.followed_by",
157
+ data.followed_by
158
+ ),
122
159
  following: get(
123
160
  data,
124
161
  "relationship_perspectives.following",
125
162
  data.following
126
163
  ),
127
- muting: data.muting,
164
+ muting: get(data, "relationship_perspectives.muting", data.muting),
128
165
  has_graduated_access: data.has_graduated_access,
129
166
  geo_enabled: data.geo_enabled,
130
167