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.
Files changed (152) hide show
  1. package/README.md +15 -42
  2. package/package.json +9 -24
  3. package/src/client/BaseClient.js +2 -3
  4. package/src/client/Client.js +187 -539
  5. package/src/client/actions/Action.js +18 -13
  6. package/src/client/actions/ActionsManager.js +7 -1
  7. package/src/client/actions/AutoModerationActionExecution.js +1 -0
  8. package/src/client/actions/AutoModerationRuleCreate.js +1 -0
  9. package/src/client/actions/AutoModerationRuleDelete.js +1 -0
  10. package/src/client/actions/AutoModerationRuleUpdate.js +1 -0
  11. package/src/client/actions/GuildMemberRemove.js +1 -1
  12. package/src/client/actions/GuildMemberUpdate.js +1 -1
  13. package/src/client/actions/MessageCreate.js +0 -4
  14. package/src/client/actions/PresenceUpdate.js +17 -16
  15. package/src/client/websocket/WebSocketManager.js +11 -31
  16. package/src/client/websocket/WebSocketShard.js +39 -38
  17. package/src/client/websocket/handlers/CALL_CREATE.js +3 -3
  18. package/src/client/websocket/handlers/CALL_DELETE.js +2 -2
  19. package/src/client/websocket/handlers/CALL_UPDATE.js +2 -2
  20. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_ADD.js +16 -13
  21. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_REMOVE.js +11 -11
  22. package/src/client/websocket/handlers/GUILD_CREATE.js +7 -0
  23. package/src/client/websocket/handlers/GUILD_MEMBER_ADD.js +1 -1
  24. package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +1 -0
  25. package/src/client/websocket/handlers/READY.js +47 -137
  26. package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +7 -5
  27. package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +6 -4
  28. package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +32 -9
  29. package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +2 -8
  30. package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +1 -1
  31. package/src/client/websocket/handlers/USER_REQUIRED_ACTION_UPDATE.js +78 -0
  32. package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +1 -5
  33. package/src/client/websocket/handlers/VOICE_CHANNEL_STATUS_UPDATE.js +12 -0
  34. package/src/client/websocket/handlers/index.js +15 -20
  35. package/src/errors/Messages.js +24 -69
  36. package/src/index.js +12 -43
  37. package/src/managers/ApplicationCommandManager.js +9 -12
  38. package/src/managers/ApplicationCommandPermissionsManager.js +3 -11
  39. package/src/managers/ChannelManager.js +2 -4
  40. package/src/managers/ClientUserSettingManager.js +161 -279
  41. package/src/managers/GuildBanManager.js +1 -1
  42. package/src/managers/GuildChannelManager.js +2 -0
  43. package/src/managers/GuildForumThreadManager.js +22 -28
  44. package/src/managers/GuildMemberManager.js +40 -216
  45. package/src/managers/GuildSettingManager.js +22 -15
  46. package/src/managers/MessageManager.js +42 -44
  47. package/src/managers/PermissionOverwriteManager.js +1 -1
  48. package/src/managers/ReactionUserManager.js +5 -5
  49. package/src/managers/RelationshipManager.js +81 -74
  50. package/src/managers/ThreadManager.js +12 -45
  51. package/src/managers/ThreadMemberManager.js +1 -1
  52. package/src/managers/UserManager.js +6 -10
  53. package/src/managers/UserNoteManager.js +53 -0
  54. package/src/rest/APIRequest.js +42 -20
  55. package/src/rest/DiscordAPIError.js +17 -16
  56. package/src/rest/RESTManager.js +1 -21
  57. package/src/rest/RequestHandler.js +35 -21
  58. package/src/structures/ApplicationCommand.js +19 -456
  59. package/src/structures/ApplicationRoleConnectionMetadata.js +3 -0
  60. package/src/structures/AutoModerationRule.js +5 -5
  61. package/src/structures/AutocompleteInteraction.js +1 -0
  62. package/src/structures/BaseGuildTextChannel.js +10 -12
  63. package/src/structures/BaseGuildVoiceChannel.js +16 -18
  64. package/src/structures/{Call.js → CallState.js} +17 -12
  65. package/src/structures/CategoryChannel.js +2 -0
  66. package/src/structures/Channel.js +2 -3
  67. package/src/structures/ClientPresence.js +12 -8
  68. package/src/structures/ClientUser.js +124 -310
  69. package/src/structures/ContextMenuInteraction.js +1 -1
  70. package/src/structures/DMChannel.js +29 -92
  71. package/src/structures/ForumChannel.js +0 -10
  72. package/src/structures/GroupDMChannel.js +387 -0
  73. package/src/structures/Guild.js +135 -271
  74. package/src/structures/GuildAuditLogs.js +0 -5
  75. package/src/structures/GuildChannel.js +16 -2
  76. package/src/structures/GuildMember.js +27 -145
  77. package/src/structures/Interaction.js +1 -62
  78. package/src/structures/Invite.js +35 -52
  79. package/src/structures/Message.js +222 -202
  80. package/src/structures/MessageAttachment.js +11 -0
  81. package/src/structures/MessageButton.js +1 -67
  82. package/src/structures/MessageEmbed.js +1 -1
  83. package/src/structures/MessageMentions.js +3 -2
  84. package/src/structures/MessagePayload.js +4 -46
  85. package/src/structures/MessageReaction.js +1 -1
  86. package/src/structures/MessageSelectMenu.js +1 -252
  87. package/src/structures/Modal.js +75 -180
  88. package/src/structures/Presence.js +2 -2
  89. package/src/structures/RichPresence.js +14 -34
  90. package/src/structures/Role.js +18 -2
  91. package/src/structures/SelectMenuInteraction.js +2 -151
  92. package/src/structures/Team.js +0 -49
  93. package/src/structures/TextInputComponent.js +0 -70
  94. package/src/structures/ThreadChannel.js +0 -19
  95. package/src/structures/User.js +117 -345
  96. package/src/structures/UserContextMenuInteraction.js +2 -2
  97. package/src/structures/VoiceState.js +74 -39
  98. package/src/structures/WebEmbed.js +38 -52
  99. package/src/structures/Webhook.js +17 -11
  100. package/src/structures/interfaces/Application.js +146 -23
  101. package/src/structures/interfaces/TextBasedChannel.js +411 -256
  102. package/src/util/ApplicationFlags.js +1 -1
  103. package/src/util/AttachmentFlags.js +38 -0
  104. package/src/util/Constants.js +106 -284
  105. package/src/util/Formatters.js +16 -2
  106. package/src/util/InviteFlags.js +29 -0
  107. package/src/util/LimitedCollection.js +1 -1
  108. package/src/util/Options.js +48 -68
  109. package/src/util/Permissions.js +5 -0
  110. package/src/util/PurchasedFlags.js +2 -0
  111. package/src/util/RemoteAuth.js +221 -356
  112. package/src/util/RoleFlags.js +37 -0
  113. package/src/util/Sweepers.js +1 -1
  114. package/src/util/Util.js +76 -36
  115. package/typings/enums.d.ts +18 -73
  116. package/typings/index.d.ts +874 -1226
  117. package/typings/rawDataTypes.d.ts +68 -9
  118. package/LICENSE +0 -674
  119. package/src/client/actions/InteractionCreate.js +0 -115
  120. package/src/client/websocket/handlers/APPLICATION_COMMAND_AUTOCOMPLETE_RESPONSE.js +0 -23
  121. package/src/client/websocket/handlers/GUILD_APPLICATION_COMMANDS_UPDATE.js +0 -11
  122. package/src/client/websocket/handlers/GUILD_MEMBER_LIST_UPDATE.js +0 -55
  123. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUNDS_UPDATE.js +0 -0
  124. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.js +0 -0
  125. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.js +0 -0
  126. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.js +0 -0
  127. package/src/client/websocket/handlers/INTERACTION_CREATE.js +0 -16
  128. package/src/client/websocket/handlers/INTERACTION_FAILURE.js +0 -18
  129. package/src/client/websocket/handlers/INTERACTION_SUCCESS.js +0 -30
  130. package/src/client/websocket/handlers/MESSAGE_ACK.js +0 -16
  131. package/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.js +0 -0
  132. package/src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.js +0 -0
  133. package/src/managers/DeveloperPortalManager.js +0 -104
  134. package/src/managers/GuildApplicationCommandManager.js +0 -28
  135. package/src/managers/GuildFolderManager.js +0 -24
  136. package/src/managers/SessionManager.js +0 -57
  137. package/src/rest/CaptchaSolver.js +0 -132
  138. package/src/structures/ClientApplication.js +0 -204
  139. package/src/structures/DeveloperPortalApplication.js +0 -520
  140. package/src/structures/GuildFolder.js +0 -75
  141. package/src/structures/InteractionResponse.js +0 -114
  142. package/src/structures/PartialGroupDMChannel.js +0 -433
  143. package/src/structures/Session.js +0 -81
  144. package/src/util/Voice.js +0 -1456
  145. package/src/util/arRPC/index.js +0 -229
  146. package/src/util/arRPC/process/detectable.json +0 -1
  147. package/src/util/arRPC/process/index.js +0 -102
  148. package/src/util/arRPC/process/native/index.js +0 -5
  149. package/src/util/arRPC/process/native/linux.js +0 -37
  150. package/src/util/arRPC/process/native/win32.js +0 -25
  151. package/src/util/arRPC/transports/ipc.js +0 -281
  152. 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((value, key) => [key, this.client.users.cache.get(key)]);
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((value, key) => [key, this.client.users.cache.get(key)]);
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((value, key) => [key, this.client.users.cache.get(key)]);
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((value, key) => [key, this.client.users.cache.get(key)]);
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 {Array<{id: Snowflake, type: RelationshipTypes}>}
91
+ * @returns {RelationshipJSONData[]}
81
92
  */
82
- toArray() {
83
- return this.cache.map((value, key) => ({ id: key, type: RelationshipTypes[value] }));
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.client.user.friendNicknames.set(relationShip.id, relationShip.nickname);
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
- deleteFriend(user) {
157
+ async deleteRelationship(user) {
141
158
  const id = this.resolveId(user);
142
- // Check if already friends
143
- if (this.cache.get(id) !== RelationshipTypes.FRIEND) return false;
144
- return this.__cancel(id);
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
- * Deletes a blocked relationship with a client user.
149
- * @param {UserResolvable} user Target
150
- * @returns {Promise<boolean>}
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 {string} username Username of the user to send the request to
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(username, discriminator) {
166
- await this.client.api.users('@me').relationships.post({
167
- data: {
168
- username,
169
- discriminator: discriminator == 0 ? null : parseInt(discriminator),
170
- },
171
- headers: {
172
- 'X-Context-Properties': Buffer.from(JSON.stringify({ location: 'Add Friend' }), 'utf8').toString('base64'),
173
- },
174
- });
175
- return true;
176
- }
177
-
178
- /**
179
- * Cancels a friend request.
180
- * @param {UserResolvable} user the user you want to delete
181
- * @returns {Promise<boolean>}
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
- headers: {
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
- headers: {
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
- async fetchArchived(options = {}, cache = true) {
123
- if (this.client.user.bot) {
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 = null) {
169
- if (options && this.client.user.bot) {
170
- throw new Error('INVALID_BOT_OPTIONS: Options can only be specified for user accounts.');
171
- }
172
-
173
- const raw = this.client.user.bot
174
- ? await this.client.api.guilds(this.channel.guild.id).threads.active.get()
175
- : await this.client.api.channels(this.channel.id).threads.search.get({
176
- query: {
177
- archived: options?.archived ?? false,
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 !== 'boolean' ? member : { ...options, cache: 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(this.client.user.id).channels.post({
59
+ const data = await this.client.api.users['@me'].channels.post({
60
60
  data: {
61
61
  recipients: [id],
62
62
  },
63
- headers: {
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
- await dm_channel.sync();
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, guildId = null } = {}) {
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
- const userObject = this._add(data, cache);
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;
@@ -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 = undefined, captchaRqtoken = undefined) {
36
- if (agent === null) {
37
- if (typeof this.client.options.proxy === 'string' && this.client.options.proxy.length > 0) {
38
- const proxy = require('proxy-agent');
39
- agent = new proxy(this.client.options.proxy);
40
- } else if (this.client.options.http.agent instanceof https.Agent) {
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({ ...this.client.options.http.agent, keepAlive: true });
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
- ...this.client.options.http.headers,
67
+ authority: 'discord.com',
56
68
  accept: '*/*',
57
69
  'accept-language': 'en-US',
58
- 'sec-ch-ua': `"Not?A_Brand";v="8", "Chromium";v="108"`,
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
- this.client.options.jsonTransformer(this.client.options.ws.properties),
69
- 'ascii',
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
- if (captchaKey && typeof captchaKey == 'string') {
89
- headers['x-captcha-key'] = captchaKey;
90
- if (captchaRqtoken) headers['x-captcha-rqtoken'] = captchaRqtoken;
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.useFormDataPayloadJSON) {
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 | string}
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
  /**