emusks 2.0.3 → 2.0.5
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/build/graphql.js +5 -13
- package/package.json +14 -3
- package/src/graphql.js +34 -12
- package/src/helpers/account.js +267 -269
- package/src/helpers/bookmarks.js +101 -103
- package/src/helpers/communities.js +236 -238
- package/src/helpers/dms.js +129 -131
- package/src/helpers/index.js +50 -31
- package/src/helpers/lists.js +222 -224
- package/src/helpers/media.js +137 -139
- package/src/helpers/notifications.js +42 -44
- package/src/helpers/search.js +117 -119
- package/src/helpers/spaces.js +47 -49
- package/src/helpers/syndication.js +23 -25
- package/src/helpers/timelines.js +76 -78
- package/src/helpers/topics.js +87 -89
- package/src/helpers/trends.js +74 -76
- package/src/helpers/tweets.js +302 -304
- package/src/helpers/users.js +287 -289
- package/src/index.js +23 -19
- package/src/static/graphql.js +1 -1
package/build/graphql.js
CHANGED
|
@@ -3,21 +3,13 @@ const URL = `https://raw.githubusercontent.com/fa0311/TwitterInternalAPIDocument
|
|
|
3
3
|
const json = await fetch(URL).then((r) => r.json());
|
|
4
4
|
const graphql = json.graphql;
|
|
5
5
|
|
|
6
|
-
const buildUrl = (base, features) => {
|
|
7
|
-
const params = new URLSearchParams();
|
|
8
|
-
|
|
9
|
-
if (features && Object.keys(features).length) {
|
|
10
|
-
params.set(`features`, JSON.stringify(features));
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const query = params.toString();
|
|
14
|
-
return query ? `${base}?${query}` : base;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
6
|
const transformed = Object.fromEntries(
|
|
18
7
|
Object.entries(graphql).map(([name, data]) => {
|
|
19
|
-
const
|
|
20
|
-
|
|
8
|
+
const features = data.features
|
|
9
|
+
? Object.fromEntries(Object.keys(data.features).map((k) => [k, true]))
|
|
10
|
+
: undefined;
|
|
11
|
+
const queryId = data.url.match(/\/graphql\/([^\/]+)\//)?.[1];
|
|
12
|
+
return [name, [data.method, data.url, features, queryId]];
|
|
21
13
|
}),
|
|
22
14
|
);
|
|
23
15
|
|
package/package.json
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "emusks",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
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
|
-
"keywords": [
|
|
5
|
+
"keywords": [
|
|
6
|
+
"client",
|
|
7
|
+
"reverse-engineering",
|
|
8
|
+
"twitter",
|
|
9
|
+
"twitter-api",
|
|
10
|
+
"x",
|
|
11
|
+
"x-api"
|
|
12
|
+
],
|
|
6
13
|
"homepage": "https://github.com/tiagozip/emusks",
|
|
7
|
-
"main": "src/index.js",
|
|
8
14
|
"bugs": {
|
|
9
15
|
"url": "https://github.com/tiagozip/emusks/issues"
|
|
10
16
|
},
|
|
@@ -13,6 +19,11 @@
|
|
|
13
19
|
"type": "git",
|
|
14
20
|
"url": "https://github.com/tiagozip/emusks.git"
|
|
15
21
|
},
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "src/index.js",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": "./src/index.js"
|
|
26
|
+
},
|
|
16
27
|
"dependencies": {
|
|
17
28
|
"cycletls": "^2.0.5",
|
|
18
29
|
"x-client-transaction-id": "^0.1.9"
|
package/src/graphql.js
CHANGED
|
@@ -7,18 +7,35 @@ export default async function graphql(queryName, { variables, fieldToggles, body
|
|
|
7
7
|
throw new Error(`graphql query ${queryName} not found`);
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
const [method, baseUrl] = entry;
|
|
10
|
+
const [method, baseUrl, features, queryId] = entry;
|
|
11
|
+
const isPost = method.toLowerCase() === "post";
|
|
11
12
|
|
|
12
13
|
let finalUrl = baseUrl;
|
|
14
|
+
let requestBody;
|
|
13
15
|
|
|
14
|
-
if (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
if (isPost) {
|
|
17
|
+
requestBody = {
|
|
18
|
+
...body,
|
|
19
|
+
variables: { ...variables, ...body?.variables },
|
|
20
|
+
queryId,
|
|
21
|
+
};
|
|
22
|
+
if (features) requestBody.features = features;
|
|
23
|
+
if (fieldToggles && Object.keys(fieldToggles).length) {
|
|
24
|
+
requestBody.fieldToggles = fieldToggles;
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
if (variables && Object.keys(variables).length) {
|
|
28
|
+
const separator = finalUrl.includes("?") ? "&" : "?";
|
|
29
|
+
finalUrl = `${finalUrl}${separator}variables=${encodeURIComponent(JSON.stringify(variables))}`;
|
|
30
|
+
}
|
|
31
|
+
if (features) {
|
|
32
|
+
const separator = finalUrl.includes("?") ? "&" : "?";
|
|
33
|
+
finalUrl = `${finalUrl}${separator}features=${encodeURIComponent(JSON.stringify(features))}`;
|
|
34
|
+
}
|
|
35
|
+
if (fieldToggles && Object.keys(fieldToggles).length) {
|
|
36
|
+
const separator = finalUrl.includes("?") ? "&" : "?";
|
|
37
|
+
finalUrl = `${finalUrl}${separator}fieldToggles=${encodeURIComponent(JSON.stringify(fieldToggles))}`;
|
|
38
|
+
}
|
|
22
39
|
}
|
|
23
40
|
|
|
24
41
|
const url = new URL(finalUrl);
|
|
@@ -51,8 +68,7 @@ export default async function graphql(queryName, { variables, fieldToggles, body
|
|
|
51
68
|
};
|
|
52
69
|
|
|
53
70
|
const cycleTLS = await getCycleTLS();
|
|
54
|
-
|
|
55
|
-
return await (
|
|
71
|
+
const res = await (
|
|
56
72
|
await cycleTLS(
|
|
57
73
|
finalUrl,
|
|
58
74
|
{
|
|
@@ -60,11 +76,17 @@ export default async function graphql(queryName, { variables, fieldToggles, body
|
|
|
60
76
|
userAgent: this.auth.client.fingerprints.userAgent,
|
|
61
77
|
ja3: this.auth.client.fingerprints.ja3,
|
|
62
78
|
ja4r: this.auth.client.fingerprints.ja4r,
|
|
63
|
-
body:
|
|
79
|
+
body: isPost ? JSON.stringify(requestBody) : undefined,
|
|
64
80
|
proxy: this.proxy || undefined,
|
|
65
81
|
referrer: "https://x.com/",
|
|
66
82
|
},
|
|
67
83
|
method,
|
|
68
84
|
)
|
|
69
85
|
).json();
|
|
86
|
+
|
|
87
|
+
if (res?.errors?.[0]) {
|
|
88
|
+
throw new Error(res.errors.map((err) => err.message).join(", "));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return res;
|
|
70
92
|
}
|