djs-selfbot-v13 1.0.1 → 3.1.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/README.md +15 -42
- package/package.json +9 -24
- package/src/client/BaseClient.js +2 -3
- package/src/client/Client.js +187 -539
- package/src/client/actions/Action.js +18 -13
- package/src/client/actions/ActionsManager.js +7 -1
- package/src/client/actions/AutoModerationActionExecution.js +1 -0
- package/src/client/actions/AutoModerationRuleCreate.js +1 -0
- package/src/client/actions/AutoModerationRuleDelete.js +1 -0
- package/src/client/actions/AutoModerationRuleUpdate.js +1 -0
- package/src/client/actions/GuildMemberRemove.js +1 -1
- package/src/client/actions/GuildMemberUpdate.js +1 -1
- package/src/client/actions/MessageCreate.js +0 -4
- package/src/client/actions/PresenceUpdate.js +17 -16
- package/src/client/websocket/WebSocketManager.js +11 -31
- package/src/client/websocket/WebSocketShard.js +39 -38
- package/src/client/websocket/handlers/CALL_CREATE.js +3 -3
- package/src/client/websocket/handlers/CALL_DELETE.js +2 -2
- package/src/client/websocket/handlers/CALL_UPDATE.js +2 -2
- package/src/client/websocket/handlers/CHANNEL_RECIPIENT_ADD.js +16 -13
- package/src/client/websocket/handlers/CHANNEL_RECIPIENT_REMOVE.js +11 -11
- package/src/client/websocket/handlers/GUILD_CREATE.js +7 -0
- package/src/client/websocket/handlers/GUILD_MEMBER_ADD.js +1 -1
- package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +1 -0
- package/src/client/websocket/handlers/READY.js +47 -137
- package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +7 -5
- package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +6 -4
- package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +32 -9
- package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +2 -8
- package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +1 -1
- package/src/client/websocket/handlers/USER_REQUIRED_ACTION_UPDATE.js +78 -0
- package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +1 -5
- package/src/client/websocket/handlers/VOICE_CHANNEL_STATUS_UPDATE.js +12 -0
- package/src/client/websocket/handlers/index.js +15 -20
- package/src/errors/Messages.js +24 -69
- package/src/index.js +12 -43
- package/src/managers/ApplicationCommandManager.js +9 -12
- package/src/managers/ApplicationCommandPermissionsManager.js +3 -11
- package/src/managers/ChannelManager.js +2 -4
- package/src/managers/ClientUserSettingManager.js +161 -279
- package/src/managers/GuildBanManager.js +1 -1
- package/src/managers/GuildChannelManager.js +2 -0
- package/src/managers/GuildForumThreadManager.js +22 -28
- package/src/managers/GuildMemberManager.js +40 -216
- package/src/managers/GuildSettingManager.js +22 -15
- package/src/managers/MessageManager.js +42 -44
- package/src/managers/PermissionOverwriteManager.js +1 -1
- package/src/managers/ReactionUserManager.js +5 -5
- package/src/managers/RelationshipManager.js +81 -74
- package/src/managers/ThreadManager.js +12 -45
- package/src/managers/ThreadMemberManager.js +1 -1
- package/src/managers/UserManager.js +6 -10
- package/src/managers/UserNoteManager.js +53 -0
- package/src/rest/APIRequest.js +42 -20
- package/src/rest/DiscordAPIError.js +17 -16
- package/src/rest/RESTManager.js +1 -21
- package/src/rest/RequestHandler.js +35 -21
- package/src/structures/ApplicationCommand.js +19 -456
- package/src/structures/ApplicationRoleConnectionMetadata.js +3 -0
- package/src/structures/AutoModerationRule.js +5 -5
- package/src/structures/AutocompleteInteraction.js +1 -0
- package/src/structures/BaseGuildTextChannel.js +10 -12
- package/src/structures/BaseGuildVoiceChannel.js +16 -18
- package/src/structures/{Call.js → CallState.js} +17 -12
- package/src/structures/CategoryChannel.js +2 -0
- package/src/structures/Channel.js +2 -3
- package/src/structures/ClientPresence.js +12 -8
- package/src/structures/ClientUser.js +124 -310
- package/src/structures/ContextMenuInteraction.js +1 -1
- package/src/structures/DMChannel.js +29 -92
- package/src/structures/ForumChannel.js +0 -10
- package/src/structures/GroupDMChannel.js +387 -0
- package/src/structures/Guild.js +135 -271
- package/src/structures/GuildAuditLogs.js +0 -5
- package/src/structures/GuildChannel.js +16 -2
- package/src/structures/GuildMember.js +27 -145
- package/src/structures/Interaction.js +1 -62
- package/src/structures/Invite.js +35 -52
- package/src/structures/Message.js +222 -202
- package/src/structures/MessageAttachment.js +11 -0
- package/src/structures/MessageButton.js +1 -67
- package/src/structures/MessageEmbed.js +1 -1
- package/src/structures/MessageMentions.js +3 -2
- package/src/structures/MessagePayload.js +4 -46
- package/src/structures/MessageReaction.js +1 -1
- package/src/structures/MessageSelectMenu.js +1 -252
- package/src/structures/Modal.js +75 -180
- package/src/structures/Presence.js +2 -2
- package/src/structures/RichPresence.js +14 -34
- package/src/structures/Role.js +18 -2
- package/src/structures/SelectMenuInteraction.js +2 -151
- package/src/structures/Team.js +0 -49
- package/src/structures/TextInputComponent.js +0 -70
- package/src/structures/ThreadChannel.js +0 -19
- package/src/structures/User.js +117 -345
- package/src/structures/UserContextMenuInteraction.js +2 -2
- package/src/structures/VoiceState.js +74 -39
- package/src/structures/WebEmbed.js +38 -52
- package/src/structures/Webhook.js +17 -11
- package/src/structures/interfaces/Application.js +146 -23
- package/src/structures/interfaces/TextBasedChannel.js +411 -256
- package/src/util/ApplicationFlags.js +1 -1
- package/src/util/AttachmentFlags.js +38 -0
- package/src/util/Constants.js +106 -284
- package/src/util/Formatters.js +16 -2
- package/src/util/InviteFlags.js +29 -0
- package/src/util/LimitedCollection.js +1 -1
- package/src/util/Options.js +48 -68
- package/src/util/Permissions.js +5 -0
- package/src/util/PurchasedFlags.js +2 -0
- package/src/util/RemoteAuth.js +221 -356
- package/src/util/RoleFlags.js +37 -0
- package/src/util/Sweepers.js +1 -1
- package/src/util/Util.js +76 -36
- package/typings/enums.d.ts +18 -73
- package/typings/index.d.ts +874 -1226
- package/typings/rawDataTypes.d.ts +68 -9
- package/LICENSE +0 -674
- package/src/client/actions/InteractionCreate.js +0 -115
- package/src/client/websocket/handlers/APPLICATION_COMMAND_AUTOCOMPLETE_RESPONSE.js +0 -23
- package/src/client/websocket/handlers/GUILD_APPLICATION_COMMANDS_UPDATE.js +0 -11
- package/src/client/websocket/handlers/GUILD_MEMBER_LIST_UPDATE.js +0 -55
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUNDS_UPDATE.js +0 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.js +0 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.js +0 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.js +0 -0
- package/src/client/websocket/handlers/INTERACTION_CREATE.js +0 -16
- package/src/client/websocket/handlers/INTERACTION_FAILURE.js +0 -18
- package/src/client/websocket/handlers/INTERACTION_SUCCESS.js +0 -30
- package/src/client/websocket/handlers/MESSAGE_ACK.js +0 -16
- package/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.js +0 -0
- package/src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.js +0 -0
- package/src/managers/DeveloperPortalManager.js +0 -104
- package/src/managers/GuildApplicationCommandManager.js +0 -28
- package/src/managers/GuildFolderManager.js +0 -24
- package/src/managers/SessionManager.js +0 -57
- package/src/rest/CaptchaSolver.js +0 -132
- package/src/structures/ClientApplication.js +0 -204
- package/src/structures/DeveloperPortalApplication.js +0 -520
- package/src/structures/GuildFolder.js +0 -75
- package/src/structures/InteractionResponse.js +0 -114
- package/src/structures/PartialGroupDMChannel.js +0 -433
- package/src/structures/Session.js +0 -81
- package/src/util/Voice.js +0 -1456
- package/src/util/arRPC/index.js +0 -229
- package/src/util/arRPC/process/detectable.json +0 -1
- package/src/util/arRPC/process/index.js +0 -102
- package/src/util/arRPC/process/native/index.js +0 -5
- package/src/util/arRPC/process/native/linux.js +0 -37
- package/src/util/arRPC/process/native/win32.js +0 -25
- package/src/util/arRPC/transports/ipc.js +0 -281
- package/src/util/arRPC/transports/websocket.js +0 -128
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const Buffer = require('node:buffer').Buffer;
|
|
4
3
|
const { Collection } = require('@discordjs/collection');
|
|
4
|
+
const BaseManager = require('./BaseManager');
|
|
5
5
|
const { GuildMember } = require('../structures/GuildMember');
|
|
6
6
|
const { Message } = require('../structures/Message');
|
|
7
7
|
const ThreadMember = require('../structures/ThreadMember');
|
|
@@ -11,19 +11,22 @@ const { RelationshipTypes } = require('../util/Constants');
|
|
|
11
11
|
/**
|
|
12
12
|
* Manages API methods for Relationships and stores their cache.
|
|
13
13
|
*/
|
|
14
|
-
class RelationshipManager {
|
|
14
|
+
class RelationshipManager extends BaseManager {
|
|
15
15
|
constructor(client, users) {
|
|
16
|
-
|
|
17
|
-
* The client that instantiated this manager.
|
|
18
|
-
* @type {Client}
|
|
19
|
-
*/
|
|
20
|
-
this.client = client;
|
|
16
|
+
super(client);
|
|
21
17
|
/**
|
|
22
18
|
* A collection of users this manager is caching. (Type: Number)
|
|
23
19
|
* @type {Collection<Snowflake, RelationshipTypes>}
|
|
24
|
-
* @readonly
|
|
25
20
|
*/
|
|
26
21
|
this.cache = new Collection();
|
|
22
|
+
/**
|
|
23
|
+
* @type {Collection<Snowflake, string>}
|
|
24
|
+
*/
|
|
25
|
+
this.friendNicknames = new Collection();
|
|
26
|
+
/**
|
|
27
|
+
* @type {Collection<Snowflake, Date>}
|
|
28
|
+
*/
|
|
29
|
+
this.sinceCache = new Collection();
|
|
27
30
|
this._setup(users);
|
|
28
31
|
}
|
|
29
32
|
|
|
@@ -35,7 +38,7 @@ class RelationshipManager {
|
|
|
35
38
|
get friendCache() {
|
|
36
39
|
const users = this.cache
|
|
37
40
|
.filter(value => value === RelationshipTypes.FRIEND)
|
|
38
|
-
.map((
|
|
41
|
+
.map((_, key) => [key, this.client.users.cache.get(key)]);
|
|
39
42
|
return new Collection(users);
|
|
40
43
|
}
|
|
41
44
|
|
|
@@ -47,7 +50,7 @@ class RelationshipManager {
|
|
|
47
50
|
get blockedCache() {
|
|
48
51
|
const users = this.cache
|
|
49
52
|
.filter(value => value === RelationshipTypes.BLOCKED)
|
|
50
|
-
.map((
|
|
53
|
+
.map((_, key) => [key, this.client.users.cache.get(key)]);
|
|
51
54
|
return new Collection(users);
|
|
52
55
|
}
|
|
53
56
|
|
|
@@ -59,7 +62,7 @@ class RelationshipManager {
|
|
|
59
62
|
get incomingCache() {
|
|
60
63
|
const users = this.cache
|
|
61
64
|
.filter(value => value === RelationshipTypes.PENDING_INCOMING)
|
|
62
|
-
.map((
|
|
65
|
+
.map((_, key) => [key, this.client.users.cache.get(key)]);
|
|
63
66
|
return new Collection(users);
|
|
64
67
|
}
|
|
65
68
|
|
|
@@ -71,16 +74,29 @@ class RelationshipManager {
|
|
|
71
74
|
get outgoingCache() {
|
|
72
75
|
const users = this.cache
|
|
73
76
|
.filter(value => value === RelationshipTypes.PENDING_OUTGOING)
|
|
74
|
-
.map((
|
|
77
|
+
.map((_, key) => [key, this.client.users.cache.get(key)]);
|
|
75
78
|
return new Collection(users);
|
|
76
79
|
}
|
|
77
80
|
|
|
81
|
+
/**
|
|
82
|
+
* @typedef {Object} RelationshipJSONData
|
|
83
|
+
* @property {Snowflake} id The ID of the target user
|
|
84
|
+
* @property {RelationshipTypes} type The type of relationship
|
|
85
|
+
* @property {string | null} nickname The nickname of the user in this relationship (1-32 characters)
|
|
86
|
+
* @property {string} since When the user requested a relationship (ISO8601 timestamp)
|
|
87
|
+
*/
|
|
88
|
+
|
|
78
89
|
/**
|
|
79
90
|
* Return array of cache
|
|
80
|
-
* @returns {
|
|
91
|
+
* @returns {RelationshipJSONData[]}
|
|
81
92
|
*/
|
|
82
|
-
|
|
83
|
-
return this.cache.map((value, key) => ({
|
|
93
|
+
toJSON() {
|
|
94
|
+
return this.cache.map((value, key) => ({
|
|
95
|
+
id: key,
|
|
96
|
+
type: RelationshipTypes[value],
|
|
97
|
+
nickname: this.friendNicknames.get(key),
|
|
98
|
+
since: this.sinceCache.get(key).toISOString(),
|
|
99
|
+
}));
|
|
84
100
|
}
|
|
85
101
|
|
|
86
102
|
/**
|
|
@@ -91,8 +107,9 @@ class RelationshipManager {
|
|
|
91
107
|
_setup(users) {
|
|
92
108
|
if (!Array.isArray(users)) return;
|
|
93
109
|
for (const relationShip of users) {
|
|
94
|
-
this.
|
|
110
|
+
this.friendNicknames.set(relationShip.id, relationShip.nickname);
|
|
95
111
|
this.cache.set(relationShip.id, relationShip.type);
|
|
112
|
+
this.sinceCache.set(relationShip.id, new Date(relationShip.since || 0));
|
|
96
113
|
}
|
|
97
114
|
}
|
|
98
115
|
|
|
@@ -133,66 +150,55 @@ class RelationshipManager {
|
|
|
133
150
|
}
|
|
134
151
|
|
|
135
152
|
/**
|
|
136
|
-
* Deletes a friend relationship with a client user.
|
|
153
|
+
* Deletes a friend / blocked relationship with a client user or cancels a friend request.
|
|
137
154
|
* @param {UserResolvable} user Target
|
|
138
155
|
* @returns {Promise<boolean>}
|
|
139
156
|
*/
|
|
140
|
-
|
|
157
|
+
async deleteRelationship(user) {
|
|
141
158
|
const id = this.resolveId(user);
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
159
|
+
if (
|
|
160
|
+
![RelationshipTypes.FRIEND, RelationshipTypes.BLOCKED, RelationshipTypes.PENDING_OUTGOING].includes(
|
|
161
|
+
this.cache.get(id),
|
|
162
|
+
)
|
|
163
|
+
) {
|
|
164
|
+
return Promise.resolve(false);
|
|
165
|
+
}
|
|
166
|
+
await this.client.api.users['@me'].relationships[id].delete({
|
|
167
|
+
DiscordContext: { location: 'Friends' },
|
|
168
|
+
});
|
|
169
|
+
return true;
|
|
145
170
|
}
|
|
146
171
|
|
|
147
172
|
/**
|
|
148
|
-
*
|
|
149
|
-
* @
|
|
150
|
-
* @
|
|
173
|
+
* @typedef {Object} FriendRequestOptions
|
|
174
|
+
* @property {UserResolvable} [user] Target
|
|
175
|
+
* @property {string} [username] Discord username
|
|
176
|
+
* @property {number | null} [discriminator] Discord discriminator
|
|
151
177
|
*/
|
|
152
|
-
deleteBlocked(user) {
|
|
153
|
-
const id = this.resolveId(user);
|
|
154
|
-
// Check if already blocked
|
|
155
|
-
if (this.cache.get(id) !== RelationshipTypes.BLOCKED) return false;
|
|
156
|
-
return this.__cancel(id);
|
|
157
|
-
}
|
|
158
178
|
|
|
159
179
|
/**
|
|
160
180
|
* Sends a friend request.
|
|
161
|
-
* @param {
|
|
162
|
-
* @param {?number} discriminator Discriminator of the user to send the request to
|
|
181
|
+
* @param {FriendRequestOptions} options Target
|
|
163
182
|
* @returns {Promise<boolean>}
|
|
164
183
|
*/
|
|
165
|
-
async sendFriendRequest(
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
cancelFriendRequest(user) {
|
|
184
|
-
const id = this.resolveId(user);
|
|
185
|
-
if (this.cache.get(id) !== RelationshipTypes.PENDING_OUTGOING) return false;
|
|
186
|
-
return this.__cancel(id);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
async __cancel(id) {
|
|
190
|
-
await this.client.api.users['@me'].relationships[id].delete({
|
|
191
|
-
headers: {
|
|
192
|
-
'X-Context-Properties': Buffer.from(JSON.stringify({ location: 'Friends' }), 'utf8').toString('base64'),
|
|
193
|
-
},
|
|
194
|
-
});
|
|
195
|
-
return true;
|
|
184
|
+
async sendFriendRequest(options) {
|
|
185
|
+
if (options?.user) {
|
|
186
|
+
const id = this.resolveId(options.user);
|
|
187
|
+
await this.client.api.users['@me'].relationships[id].put({
|
|
188
|
+
data: {},
|
|
189
|
+
DiscordContext: { location: 'ContextMenu' },
|
|
190
|
+
});
|
|
191
|
+
return true;
|
|
192
|
+
} else {
|
|
193
|
+
await this.client.api.users['@me'].relationships.post({
|
|
194
|
+
data: {
|
|
195
|
+
username: options.username,
|
|
196
|
+
discriminator: options.discriminator,
|
|
197
|
+
},
|
|
198
|
+
DiscordContext: { location: 'Add Friend' },
|
|
199
|
+
});
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
196
202
|
}
|
|
197
203
|
|
|
198
204
|
/**
|
|
@@ -203,16 +209,14 @@ class RelationshipManager {
|
|
|
203
209
|
async addFriend(user) {
|
|
204
210
|
const id = this.resolveId(user);
|
|
205
211
|
// Check if already friends
|
|
206
|
-
if (this.cache.get(id) === RelationshipTypes.FRIEND) return false;
|
|
212
|
+
if (this.cache.get(id) === RelationshipTypes.FRIEND) return Promise.resolve(false);
|
|
207
213
|
// Check if outgoing request
|
|
208
|
-
if (this.cache.get(id) === RelationshipTypes.PENDING_OUTGOING) return false;
|
|
214
|
+
if (this.cache.get(id) === RelationshipTypes.PENDING_OUTGOING) return Promise.resolve(false);
|
|
209
215
|
await this.client.api.users['@me'].relationships[id].put({
|
|
210
216
|
data: {
|
|
211
217
|
type: RelationshipTypes.FRIEND,
|
|
212
218
|
},
|
|
213
|
-
|
|
214
|
-
'X-Context-Properties': Buffer.from(JSON.stringify({ location: 'Friends' }), 'utf8').toString('base64'),
|
|
215
|
-
},
|
|
219
|
+
DiscordContext: { location: 'Friends' },
|
|
216
220
|
});
|
|
217
221
|
return true;
|
|
218
222
|
}
|
|
@@ -223,14 +227,19 @@ class RelationshipManager {
|
|
|
223
227
|
* @param {?string} nickname New nickname
|
|
224
228
|
* @returns {Promise<boolean>}
|
|
225
229
|
*/
|
|
226
|
-
async setNickname(user, nickname) {
|
|
230
|
+
async setNickname(user, nickname = null) {
|
|
227
231
|
const id = this.resolveId(user);
|
|
228
|
-
if (this.cache.get(id) !== RelationshipTypes.FRIEND) return false;
|
|
232
|
+
if (this.cache.get(id) !== RelationshipTypes.FRIEND) return Promise.resolve(false);
|
|
229
233
|
await this.client.api.users['@me'].relationships[id].patch({
|
|
230
234
|
data: {
|
|
231
235
|
nickname: typeof nickname === 'string' ? nickname : null,
|
|
232
236
|
},
|
|
233
237
|
});
|
|
238
|
+
if (nickname) {
|
|
239
|
+
this.friendNicknames.set(id, nickname);
|
|
240
|
+
} else {
|
|
241
|
+
this.friendNicknames.delete(id);
|
|
242
|
+
}
|
|
234
243
|
return true;
|
|
235
244
|
}
|
|
236
245
|
|
|
@@ -242,14 +251,12 @@ class RelationshipManager {
|
|
|
242
251
|
async addBlocked(user) {
|
|
243
252
|
const id = this.resolveId(user);
|
|
244
253
|
// Check
|
|
245
|
-
if (this.cache.get(id) === RelationshipTypes.BLOCKED) return false;
|
|
254
|
+
if (this.cache.get(id) === RelationshipTypes.BLOCKED) return Promise.resolve(false);
|
|
246
255
|
await this.client.api.users['@me'].relationships[id].put({
|
|
247
256
|
data: {
|
|
248
257
|
type: RelationshipTypes.BLOCKED,
|
|
249
258
|
},
|
|
250
|
-
|
|
251
|
-
'X-Context-Properties': Buffer.from(JSON.stringify({ location: 'ContextMenu' }), 'utf8').toString('base64'),
|
|
252
|
-
},
|
|
259
|
+
DiscordContext: { location: 'ContextMenu' },
|
|
253
260
|
});
|
|
254
261
|
return true;
|
|
255
262
|
}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
const { Collection } = require('@discordjs/collection');
|
|
4
4
|
const CachedManager = require('./CachedManager');
|
|
5
|
-
const { TypeError } = require('../errors');
|
|
6
5
|
const ThreadChannel = require('../structures/ThreadChannel');
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -119,34 +118,8 @@ class ThreadManager extends CachedManager {
|
|
|
119
118
|
* @param {boolean} [cache=true] Whether to cache the new thread objects if they aren't already
|
|
120
119
|
* @returns {Promise<FetchedThreads>}
|
|
121
120
|
*/
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
let { type = 'public', fetchAll = false, before, limit } = options;
|
|
125
|
-
let path = this.client.api.channels(this.channel.id);
|
|
126
|
-
if (type === 'private' && !fetchAll) {
|
|
127
|
-
path = path.users('@me');
|
|
128
|
-
}
|
|
129
|
-
let timestamp;
|
|
130
|
-
let id;
|
|
131
|
-
if (typeof before !== 'undefined') {
|
|
132
|
-
if (before instanceof ThreadChannel || /^\d{17,19}$/.test(String(before))) {
|
|
133
|
-
id = this.resolveId(before);
|
|
134
|
-
timestamp = this.resolve(before)?.archivedAt?.toISOString();
|
|
135
|
-
} else {
|
|
136
|
-
try {
|
|
137
|
-
timestamp = new Date(before).toISOString();
|
|
138
|
-
} catch {
|
|
139
|
-
throw new TypeError('INVALID_TYPE', 'before', 'DateResolvable or ThreadChannelResolvable');
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
const raw = await path.threads
|
|
144
|
-
.archived(type)
|
|
145
|
-
.get({ query: { before: type === 'private' && !fetchAll ? id : timestamp, limit } });
|
|
146
|
-
return this.constructor._mapThreads(raw, this.client, { parent: this.channel, cache });
|
|
147
|
-
} else {
|
|
148
|
-
return this.fetchActive(cache, { archived: true, ...options });
|
|
149
|
-
}
|
|
121
|
+
fetchArchived(options = {}, cache = true) {
|
|
122
|
+
return this.fetchActive(cache, { archived: true, ...options });
|
|
150
123
|
}
|
|
151
124
|
|
|
152
125
|
/**
|
|
@@ -165,22 +138,16 @@ class ThreadManager extends CachedManager {
|
|
|
165
138
|
* @param {FetchChannelThreadsOptions} [options] Options for self-bots where advanced users can specify further options
|
|
166
139
|
* @returns {Promise<FetchedThreads>}
|
|
167
140
|
*/
|
|
168
|
-
async fetchActive(cache = true, options =
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
limit: options?.limit ?? 25,
|
|
179
|
-
offset: options?.offset ?? 0,
|
|
180
|
-
sort_by: options?.sortBy ?? 'last_message_time',
|
|
181
|
-
sort_order: options?.sortOrder ?? 'desc',
|
|
182
|
-
},
|
|
183
|
-
});
|
|
141
|
+
async fetchActive(cache = true, options = {}) {
|
|
142
|
+
const raw = await this.client.api.channels(this.channel.id).threads.search.get({
|
|
143
|
+
query: {
|
|
144
|
+
archived: options?.archived ?? false,
|
|
145
|
+
limit: options?.limit ?? 25,
|
|
146
|
+
offset: options?.offset ?? 0,
|
|
147
|
+
sort_by: options?.sortBy ?? 'last_message_time',
|
|
148
|
+
sort_order: options?.sortOrder ?? 'desc',
|
|
149
|
+
},
|
|
150
|
+
});
|
|
184
151
|
|
|
185
152
|
return this.constructor._mapThreads(raw, this.client, { parent: this.channel, cache });
|
|
186
153
|
}
|
|
@@ -179,7 +179,7 @@ class ThreadMemberManager extends CachedManager {
|
|
|
179
179
|
const id = this.resolveId(member);
|
|
180
180
|
return id
|
|
181
181
|
? this._fetchOne(id, options)
|
|
182
|
-
: this._fetchMany(typeof member
|
|
182
|
+
: this._fetchMany(typeof member === 'boolean' ? { ...options, cache: member } : options);
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
|
|
@@ -56,16 +56,15 @@ class UserManager extends CachedManager {
|
|
|
56
56
|
if (dmChannel && !dmChannel.partial) return dmChannel;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
const data = await this.client.api.users
|
|
59
|
+
const data = await this.client.api.users['@me'].channels.post({
|
|
60
60
|
data: {
|
|
61
61
|
recipients: [id],
|
|
62
62
|
},
|
|
63
|
-
|
|
64
|
-
'X-Context-Properties': 'e30=', // {}
|
|
65
|
-
},
|
|
63
|
+
DiscordContext: {},
|
|
66
64
|
});
|
|
65
|
+
|
|
67
66
|
const dm_channel = await this.client.channels._add(data, null, { cache });
|
|
68
|
-
|
|
67
|
+
dm_channel.sync();
|
|
69
68
|
return dm_channel;
|
|
70
69
|
}
|
|
71
70
|
|
|
@@ -87,10 +86,9 @@ class UserManager extends CachedManager {
|
|
|
87
86
|
* Obtains a user from Discord, or the user cache if it's already available.
|
|
88
87
|
* @param {UserResolvable} user The user to fetch
|
|
89
88
|
* @param {BaseFetchOptions} [options] Additional options for this fetch
|
|
90
|
-
* @param {?Snowflake} [options.guildId] The guild ID to fetch the member for
|
|
91
89
|
* @returns {Promise<User>}
|
|
92
90
|
*/
|
|
93
|
-
async fetch(user, { cache = true, force = false
|
|
91
|
+
async fetch(user, { cache = true, force = false } = {}) {
|
|
94
92
|
const id = this.resolveId(user);
|
|
95
93
|
if (!force) {
|
|
96
94
|
const existing = this.cache.get(id);
|
|
@@ -98,9 +96,7 @@ class UserManager extends CachedManager {
|
|
|
98
96
|
}
|
|
99
97
|
|
|
100
98
|
const data = await this.client.api.users(id).get();
|
|
101
|
-
|
|
102
|
-
await userObject.getProfile(guildId ?? null).catch(() => {});
|
|
103
|
-
return userObject;
|
|
99
|
+
return this._add(data, cache);
|
|
104
100
|
}
|
|
105
101
|
|
|
106
102
|
/**
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { Collection } = require('@discordjs/collection');
|
|
4
|
+
const BaseManager = require('./BaseManager');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Manages API methods for Client and stores their cache.
|
|
8
|
+
* @extends {BaseManager}
|
|
9
|
+
*/
|
|
10
|
+
class UserNoteManager extends BaseManager {
|
|
11
|
+
constructor(client, data = {}) {
|
|
12
|
+
super(client);
|
|
13
|
+
/**
|
|
14
|
+
* Cache User Note
|
|
15
|
+
* @type {Collection<Snowflake, string>}
|
|
16
|
+
*/
|
|
17
|
+
this.cache = new Collection(Object.entries(data));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
_reload(data = {}) {
|
|
21
|
+
this.cache = new Collection(Object.entries(data));
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async updateNote(id, note = null) {
|
|
26
|
+
await this.client.api.users['@me'].notes(id).put({ data: { note } });
|
|
27
|
+
if (!note) this.cache.delete(id, note);
|
|
28
|
+
else this.cache.set(id, note);
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Obtains a user from Discord, or the user cache if it's already available.
|
|
34
|
+
* @param {UserResolvable} user The user to fetch
|
|
35
|
+
* @param {BaseFetchOptions} [options] Additional options for this fetch
|
|
36
|
+
* @returns {Promise<string>}
|
|
37
|
+
*/
|
|
38
|
+
async fetch(user, { cache = true, force = false } = {}) {
|
|
39
|
+
const id = this.resolveId(user);
|
|
40
|
+
if (!force) {
|
|
41
|
+
const existing = this.cache.get(id);
|
|
42
|
+
if (existing) return existing;
|
|
43
|
+
}
|
|
44
|
+
const data = await this.client.api.users['@me'].notes[id]
|
|
45
|
+
.get()
|
|
46
|
+
.then(d => d.note)
|
|
47
|
+
.catch(() => '');
|
|
48
|
+
if (cache) this.cache.set(id, data);
|
|
49
|
+
return data;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
module.exports = UserNoteManager;
|
package/src/rest/APIRequest.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const Buffer = require('node:buffer').Buffer;
|
|
4
|
+
const http = require('node:http');
|
|
4
5
|
const https = require('node:https');
|
|
5
6
|
const { setTimeout } = require('node:timers');
|
|
6
7
|
const makeFetchCookie = require('fetch-cookie');
|
|
7
8
|
const FormData = require('form-data');
|
|
8
9
|
const fetchOriginal = require('node-fetch');
|
|
9
10
|
const { CookieJar } = require('tough-cookie');
|
|
11
|
+
const { ciphers } = require('../util/Constants');
|
|
10
12
|
|
|
11
13
|
const cookieJar = new CookieJar();
|
|
12
14
|
const fetch = makeFetchCookie(fetchOriginal, cookieJar);
|
|
@@ -22,6 +24,10 @@ class APIRequest {
|
|
|
22
24
|
this.options = options;
|
|
23
25
|
this.retries = 0;
|
|
24
26
|
|
|
27
|
+
this.fullUserAgent = this.client.options.http.headers['User-Agent'];
|
|
28
|
+
|
|
29
|
+
this.client.options.ws.properties.browser_user_agent = this.fullUserAgent;
|
|
30
|
+
|
|
25
31
|
let queryString = '';
|
|
26
32
|
if (options.query) {
|
|
27
33
|
const query = Object.entries(options.query)
|
|
@@ -32,16 +38,22 @@ class APIRequest {
|
|
|
32
38
|
this.path = `${path}${queryString && `?${queryString}`}`;
|
|
33
39
|
}
|
|
34
40
|
|
|
35
|
-
make(captchaKey
|
|
36
|
-
if (agent
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
make(captchaKey, captchaRqToken) {
|
|
42
|
+
if (!agent) {
|
|
43
|
+
if (this.client.options.http.agent instanceof http.Agent) {
|
|
44
|
+
this.client.options.http.agent.options.keepAlive = true;
|
|
45
|
+
this.client.options.http.agent.options.honorCipherOrder = true;
|
|
46
|
+
this.client.options.http.agent.options.minVersion = 'TLSv1.2';
|
|
47
|
+
this.client.options.http.agent.options.ciphers = ciphers.join(':');
|
|
41
48
|
agent = this.client.options.http.agent;
|
|
42
|
-
agent.keepAlive = true;
|
|
43
49
|
} else {
|
|
44
|
-
agent = new https.Agent({
|
|
50
|
+
agent = new https.Agent({
|
|
51
|
+
...this.client.options.http.agent,
|
|
52
|
+
keepAlive: true,
|
|
53
|
+
honorCipherOrder: true,
|
|
54
|
+
minVersion: 'TLSv1.2',
|
|
55
|
+
ciphers: ciphers.join(':'),
|
|
56
|
+
});
|
|
45
57
|
}
|
|
46
58
|
}
|
|
47
59
|
|
|
@@ -52,10 +64,10 @@ class APIRequest {
|
|
|
52
64
|
const url = API + this.path;
|
|
53
65
|
|
|
54
66
|
let headers = {
|
|
55
|
-
|
|
67
|
+
authority: 'discord.com',
|
|
56
68
|
accept: '*/*',
|
|
57
69
|
'accept-language': 'en-US',
|
|
58
|
-
'sec-ch-ua':
|
|
70
|
+
'sec-ch-ua': '"Not?A_Brand";v="8", "Chromium";v="108"',
|
|
59
71
|
'sec-ch-ua-mobile': '?0',
|
|
60
72
|
'sec-ch-ua-platform': '"Windows"',
|
|
61
73
|
'sec-fetch-dest': 'empty',
|
|
@@ -64,18 +76,20 @@ class APIRequest {
|
|
|
64
76
|
'x-debug-options': 'bugReporterEnabled',
|
|
65
77
|
'x-discord-locale': 'en-US',
|
|
66
78
|
'x-discord-timezone': 'Asia/Saigon',
|
|
67
|
-
'x-super-properties': `${Buffer.from(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
).toString('base64')}`,
|
|
79
|
+
'x-super-properties': `${Buffer.from(JSON.stringify(this.client.options.ws.properties), 'ascii').toString(
|
|
80
|
+
'base64',
|
|
81
|
+
)}`,
|
|
71
82
|
Referer: 'https://discord.com/channels/@me',
|
|
72
83
|
origin: 'https://discord.com',
|
|
73
84
|
'Referrer-Policy': 'strict-origin-when-cross-origin',
|
|
85
|
+
...this.client.options.http.headers,
|
|
86
|
+
'User-Agent': this.fullUserAgent,
|
|
74
87
|
};
|
|
75
88
|
|
|
76
89
|
if (this.options.auth !== false) headers.Authorization = this.rest.getAuth();
|
|
77
90
|
if (this.options.reason) headers['X-Audit-Log-Reason'] = encodeURIComponent(this.options.reason);
|
|
78
91
|
if (this.options.headers) headers = Object.assign(headers, this.options.headers);
|
|
92
|
+
|
|
79
93
|
// Delete all headers if undefined
|
|
80
94
|
for (const [key, value] of Object.entries(headers)) {
|
|
81
95
|
if (value === undefined) delete headers[key];
|
|
@@ -85,9 +99,15 @@ class APIRequest {
|
|
|
85
99
|
'User-Agent': this.client.options.http.headers['User-Agent'],
|
|
86
100
|
};
|
|
87
101
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
102
|
+
|
|
103
|
+
// Some options
|
|
104
|
+
if (this.options.DiscordContext) {
|
|
105
|
+
headers['X-Context-Properties'] = Buffer.from(JSON.stringify(this.options.DiscordContext), 'utf8').toString(
|
|
106
|
+
'base64',
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
if (this.options.mfaToken) {
|
|
110
|
+
headers['X-Discord-Mfa-Authorization'] = this.options.mfaToken;
|
|
91
111
|
}
|
|
92
112
|
|
|
93
113
|
let body;
|
|
@@ -106,19 +126,21 @@ class APIRequest {
|
|
|
106
126
|
headers = Object.assign(headers, body.getHeaders());
|
|
107
127
|
// eslint-disable-next-line eqeqeq
|
|
108
128
|
} else if (this.options.data != null) {
|
|
109
|
-
if (this.options.
|
|
129
|
+
if (this.options.usePayloadJSON) {
|
|
110
130
|
body = new FormData();
|
|
111
131
|
body.append('payload_json', JSON.stringify(this.options.data));
|
|
112
|
-
headers = Object.assign(headers, body.getHeaders());
|
|
113
132
|
} else {
|
|
114
133
|
body = JSON.stringify(this.options.data);
|
|
115
134
|
headers['Content-Type'] = 'application/json';
|
|
116
135
|
}
|
|
117
136
|
}
|
|
118
137
|
|
|
138
|
+
// Captcha
|
|
139
|
+
if (captchaKey && typeof captchaKey == 'string') headers['X-Captcha-Key'] = captchaKey;
|
|
140
|
+
if (captchaRqToken && typeof captchaRqToken == 'string') headers['X-Captcha-Rqtoken'] = captchaRqToken;
|
|
141
|
+
|
|
119
142
|
const controller = new AbortController();
|
|
120
143
|
const timeout = setTimeout(() => controller.abort(), this.client.options.restRequestTimeout).unref();
|
|
121
|
-
|
|
122
144
|
return fetch(url, {
|
|
123
145
|
method: this.method,
|
|
124
146
|
headers,
|
|
@@ -25,7 +25,7 @@ class DiscordAPIError extends Error {
|
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* HTTP error code returned by Discord
|
|
28
|
-
* @type {number
|
|
28
|
+
* @type {number}
|
|
29
29
|
*/
|
|
30
30
|
this.code = error.code;
|
|
31
31
|
|
|
@@ -35,21 +35,6 @@ class DiscordAPIError extends Error {
|
|
|
35
35
|
*/
|
|
36
36
|
this.httpStatus = status;
|
|
37
37
|
|
|
38
|
-
/**
|
|
39
|
-
* @typedef {Object} Captcha
|
|
40
|
-
* @property {Array<string>} captcha_key ['message']
|
|
41
|
-
* @property {string} captcha_sitekey Captcha sitekey (hcaptcha)
|
|
42
|
-
* @property {string} captcha_service hcaptcha
|
|
43
|
-
* @property {string} [captcha_rqdata]
|
|
44
|
-
* @property {string} [captcha_rqtoken]
|
|
45
|
-
*/
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Captcha response data if the request requires a captcha
|
|
49
|
-
* @type {Captcha | null}
|
|
50
|
-
*/
|
|
51
|
-
this.captcha = error?.captcha_service ? error : null;
|
|
52
|
-
|
|
53
38
|
/**
|
|
54
39
|
* The data associated with the request that caused this error
|
|
55
40
|
* @type {HTTPErrorData}
|
|
@@ -57,6 +42,7 @@ class DiscordAPIError extends Error {
|
|
|
57
42
|
this.requestData = {
|
|
58
43
|
json: request.options.data,
|
|
59
44
|
files: request.options.files ?? [],
|
|
45
|
+
headers: request.options.headers,
|
|
60
46
|
};
|
|
61
47
|
|
|
62
48
|
/**
|
|
@@ -64,6 +50,21 @@ class DiscordAPIError extends Error {
|
|
|
64
50
|
* @type {number}
|
|
65
51
|
*/
|
|
66
52
|
this.retries = request.retries;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @typedef {Object} Captcha
|
|
56
|
+
* @property {Array<string>} captcha_key ['message']
|
|
57
|
+
* @property {string} captcha_sitekey Captcha sitekey (hcaptcha)
|
|
58
|
+
* @property {string} captcha_service hcaptcha
|
|
59
|
+
* @property {string} [captcha_rqdata]
|
|
60
|
+
* @property {string} [captcha_rqtoken]
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Captcha response data if the request requires a captcha
|
|
65
|
+
* @type {Captcha | null}
|
|
66
|
+
*/
|
|
67
|
+
this.captcha = error?.captcha_service ? error : null;
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
/**
|