djs-selfbot-v13 3.1.7 → 3.2.2

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 (155) hide show
  1. package/README.md +18 -35
  2. package/package.json +85 -100
  3. package/src/client/BaseClient.js +3 -4
  4. package/src/client/Client.js +249 -530
  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 +0 -1
  12. package/src/client/actions/GuildMemberUpdate.js +0 -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 +19 -13
  23. package/src/client/websocket/handlers/GUILD_MEMBER_ADD.js +0 -1
  24. package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +1 -0
  25. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_ADD.js +22 -0
  26. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_REMOVE.js +12 -0
  27. package/src/client/websocket/handlers/READY.js +90 -140
  28. package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +7 -5
  29. package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +7 -5
  30. package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +32 -9
  31. package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +2 -8
  32. package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +1 -1
  33. package/src/client/websocket/handlers/USER_REQUIRED_ACTION_UPDATE.js +78 -0
  34. package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +1 -5
  35. package/src/client/websocket/handlers/VOICE_CHANNEL_STATUS_UPDATE.js +12 -0
  36. package/src/client/websocket/handlers/index.js +17 -20
  37. package/src/errors/Messages.js +25 -69
  38. package/src/index.js +13 -43
  39. package/src/managers/ApplicationCommandManager.js +9 -12
  40. package/src/managers/ApplicationCommandPermissionsManager.js +3 -11
  41. package/src/managers/ChannelManager.js +2 -3
  42. package/src/managers/ClientUserSettingManager.js +162 -280
  43. package/src/managers/GuildBanManager.js +47 -1
  44. package/src/managers/GuildChannelManager.js +2 -16
  45. package/src/managers/GuildForumThreadManager.js +24 -30
  46. package/src/managers/GuildManager.js +1 -1
  47. package/src/managers/GuildMemberManager.js +50 -222
  48. package/src/managers/GuildSettingManager.js +22 -15
  49. package/src/managers/MessageManager.js +42 -44
  50. package/src/managers/PermissionOverwriteManager.js +1 -1
  51. package/src/managers/ReactionUserManager.js +5 -5
  52. package/src/managers/RelationshipManager.js +83 -76
  53. package/src/managers/ThreadManager.js +12 -45
  54. package/src/managers/ThreadMemberManager.js +1 -1
  55. package/src/managers/UserManager.js +6 -10
  56. package/src/managers/UserNoteManager.js +53 -0
  57. package/src/rest/APIRequest.js +48 -20
  58. package/src/rest/DiscordAPIError.js +17 -16
  59. package/src/rest/RESTManager.js +1 -21
  60. package/src/rest/RequestHandler.js +35 -21
  61. package/src/structures/ApplicationCommand.js +19 -456
  62. package/src/structures/ApplicationRoleConnectionMetadata.js +3 -0
  63. package/src/structures/AutoModerationRule.js +5 -5
  64. package/src/structures/AutocompleteInteraction.js +1 -0
  65. package/src/structures/BaseGuildTextChannel.js +10 -12
  66. package/src/structures/BaseGuildVoiceChannel.js +16 -18
  67. package/src/structures/{Call.js → CallState.js} +17 -12
  68. package/src/structures/CategoryChannel.js +2 -0
  69. package/src/structures/Channel.js +2 -3
  70. package/src/structures/ClientPresence.js +20 -19
  71. package/src/structures/ClientUser.js +117 -338
  72. package/src/structures/ContextMenuInteraction.js +1 -1
  73. package/src/structures/DMChannel.js +29 -92
  74. package/src/structures/ForumChannel.js +0 -10
  75. package/src/structures/GroupDMChannel.js +387 -0
  76. package/src/structures/Guild.js +135 -271
  77. package/src/structures/GuildAuditLogs.js +0 -5
  78. package/src/structures/GuildChannel.js +16 -2
  79. package/src/structures/GuildMember.js +27 -145
  80. package/src/structures/Interaction.js +1 -62
  81. package/src/structures/Invite.js +35 -52
  82. package/src/structures/Message.js +220 -203
  83. package/src/structures/MessageAttachment.js +11 -0
  84. package/src/structures/MessageButton.js +1 -67
  85. package/src/structures/MessageEmbed.js +1 -1
  86. package/src/structures/MessageMentions.js +3 -2
  87. package/src/structures/MessagePayload.js +6 -46
  88. package/src/structures/MessagePoll.js +238 -0
  89. package/src/structures/MessageReaction.js +1 -1
  90. package/src/structures/MessageSelectMenu.js +1 -252
  91. package/src/structures/Modal.js +70 -188
  92. package/src/structures/Presence.js +787 -129
  93. package/src/structures/Role.js +18 -2
  94. package/src/structures/SelectMenuInteraction.js +2 -151
  95. package/src/structures/Team.js +0 -49
  96. package/src/structures/TextInputComponent.js +0 -70
  97. package/src/structures/ThreadChannel.js +0 -19
  98. package/src/structures/User.js +145 -339
  99. package/src/structures/UserContextMenuInteraction.js +2 -2
  100. package/src/structures/VoiceState.js +74 -39
  101. package/src/structures/WebEmbed.js +38 -52
  102. package/src/structures/Webhook.js +17 -11
  103. package/src/structures/interfaces/Application.js +146 -23
  104. package/src/structures/interfaces/TextBasedChannel.js +409 -256
  105. package/src/util/ApplicationFlags.js +1 -1
  106. package/src/util/AttachmentFlags.js +38 -0
  107. package/src/util/Constants.js +120 -285
  108. package/src/util/Formatters.js +16 -2
  109. package/src/util/InviteFlags.js +29 -0
  110. package/src/util/LimitedCollection.js +1 -1
  111. package/src/util/Options.js +48 -74
  112. package/src/util/Permissions.js +15 -0
  113. package/src/util/PurchasedFlags.js +2 -0
  114. package/src/util/RemoteAuth.js +221 -356
  115. package/src/util/RoleFlags.js +37 -0
  116. package/src/util/Sweepers.js +1 -1
  117. package/src/util/Util.js +158 -32
  118. package/typings/enums.d.ts +24 -73
  119. package/typings/index.d.ts +978 -1288
  120. package/typings/rawDataTypes.d.ts +68 -9
  121. package/src/client/actions/InteractionCreate.js +0 -115
  122. package/src/client/websocket/handlers/APPLICATION_COMMAND_AUTOCOMPLETE_RESPONSE.js +0 -23
  123. package/src/client/websocket/handlers/GUILD_APPLICATION_COMMANDS_UPDATE.js +0 -11
  124. package/src/client/websocket/handlers/GUILD_MEMBER_LIST_UPDATE.js +0 -55
  125. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUNDS_UPDATE.js +0 -0
  126. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.js +0 -0
  127. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.js +0 -0
  128. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.js +0 -0
  129. package/src/client/websocket/handlers/INTERACTION_CREATE.js +0 -16
  130. package/src/client/websocket/handlers/INTERACTION_FAILURE.js +0 -18
  131. package/src/client/websocket/handlers/INTERACTION_SUCCESS.js +0 -30
  132. package/src/client/websocket/handlers/MESSAGE_ACK.js +0 -16
  133. package/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.js +0 -0
  134. package/src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.js +0 -0
  135. package/src/managers/DeveloperPortalManager.js +0 -104
  136. package/src/managers/GuildApplicationCommandManager.js +0 -28
  137. package/src/managers/GuildFolderManager.js +0 -24
  138. package/src/managers/SessionManager.js +0 -57
  139. package/src/rest/CaptchaSolver.js +0 -132
  140. package/src/structures/ClientApplication.js +0 -204
  141. package/src/structures/DeveloperPortalApplication.js +0 -520
  142. package/src/structures/GuildFolder.js +0 -75
  143. package/src/structures/InteractionResponse.js +0 -114
  144. package/src/structures/PartialGroupDMChannel.js +0 -433
  145. package/src/structures/RichPresence.js +0 -722
  146. package/src/structures/Session.js +0 -81
  147. package/src/util/Voice.js +0 -1456
  148. package/src/util/arRPC/index.js +0 -229
  149. package/src/util/arRPC/process/detectable.json +0 -1
  150. package/src/util/arRPC/process/index.js +0 -102
  151. package/src/util/arRPC/process/native/index.js +0 -5
  152. package/src/util/arRPC/process/native/linux.js +0 -37
  153. package/src/util/arRPC/process/native/win32.js +0 -25
  154. package/src/util/arRPC/transports/ipc.js +0 -281
  155. package/src/util/arRPC/transports/websocket.js +0 -128
@@ -3,15 +3,15 @@
3
3
  const { Collection } = require('@discordjs/collection');
4
4
  const CachedManager = require('./CachedManager');
5
5
  const { Error } = require('../errors');
6
- const { lazy } = require('../util/Util');
7
- const User = lazy(() => require('../structures/User'));
6
+ const User = require('../structures/User');
7
+
8
8
  /**
9
9
  * Manages API methods for users who reacted to a reaction and stores their cache.
10
10
  * @extends {CachedManager}
11
11
  */
12
12
  class ReactionUserManager extends CachedManager {
13
13
  constructor(reaction, iterable) {
14
- super(reaction.client, User(), iterable);
14
+ super(reaction.client, User, iterable);
15
15
 
16
16
  /**
17
17
  * The reaction that this manager belongs to
@@ -22,7 +22,7 @@ class ReactionUserManager extends CachedManager {
22
22
 
23
23
  /**
24
24
  * The cache of this manager
25
- * @type {Collection<Snowflake, Discord.User>}
25
+ * @type {Collection<Snowflake, User>}
26
26
  * @name ReactionUserManager#cache
27
27
  */
28
28
 
@@ -36,7 +36,7 @@ class ReactionUserManager extends CachedManager {
36
36
  /**
37
37
  * Fetches all the users that gave this reaction. Resolves with a collection of users, mapped by their ids.
38
38
  * @param {FetchReactionUsersOptions} [options] Options for fetching the users
39
- * @returns {Promise<Collection<Snowflake, Discord.User>>}
39
+ * @returns {Promise<Collection<Snowflake, User>>}
40
40
  */
41
41
  async fetch({ limit = 100, after } = {}) {
42
42
  const message = this.reaction.message;
@@ -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
- * @type {Collection<Snowflake, RelationshipTypes>}
24
- * @readonly
19
+ * @type {Collection<Snowflake, RelationshipType>}
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 {RelationshipType} 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
 
@@ -113,7 +130,7 @@ class RelationshipManager {
113
130
  * Obtains a user from Discord, or the user cache if it's already available.
114
131
  * @param {UserResolvable} [user] The user to fetch
115
132
  * @param {BaseFetchOptions} [options] Additional options for this fetch
116
- * @returns {Promise<RelationshipTypes|RelationshipManager>}
133
+ * @returns {Promise<RelationshipType|RelationshipManager>}
117
134
  */
118
135
  async fetch(user, { force = false } = {}) {
119
136
  if (user) {
@@ -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;
@@ -7,6 +7,8 @@ const makeFetchCookie = require('fetch-cookie');
7
7
  const FormData = require('form-data');
8
8
  const fetchOriginal = require('node-fetch');
9
9
  const { CookieJar } = require('tough-cookie');
10
+ const { ciphers } = require('../util/Constants');
11
+ const Util = require('../util/Util');
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,28 @@ 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 (Util.verifyProxyAgent(this.client.options.http.agent)) {
44
+ // Bad code
45
+ for (const [k, v] of Object.entries({
46
+ keepAlive: true,
47
+ honorCipherOrder: true,
48
+ secureProtocol: 'TLSv1_2_method',
49
+ ciphers: ciphers.join(':'),
50
+ })) {
51
+ this.client.options.http.agent.options[k] = v;
52
+ this.client.options.http.agent.httpsAgent.options.options[k] = v;
53
+ }
41
54
  agent = this.client.options.http.agent;
42
- agent.keepAlive = true;
43
55
  } else {
44
- agent = new https.Agent({ ...this.client.options.http.agent, keepAlive: true });
56
+ agent = new https.Agent({
57
+ ...this.client.options.http.agent,
58
+ keepAlive: true,
59
+ honorCipherOrder: true,
60
+ secureProtocol: 'TLSv1_2_method',
61
+ ciphers: ciphers.join(':'),
62
+ });
45
63
  }
46
64
  }
47
65
 
@@ -52,10 +70,10 @@ class APIRequest {
52
70
  const url = API + this.path;
53
71
 
54
72
  let headers = {
55
- ...this.client.options.http.headers,
73
+ authority: 'discord.com',
56
74
  accept: '*/*',
57
75
  'accept-language': 'en-US',
58
- 'sec-ch-ua': `"Not?A_Brand";v="8", "Chromium";v="108"`,
76
+ 'sec-ch-ua': '"Not?A_Brand";v="8", "Chromium";v="108"',
59
77
  'sec-ch-ua-mobile': '?0',
60
78
  'sec-ch-ua-platform': '"Windows"',
61
79
  'sec-fetch-dest': 'empty',
@@ -64,18 +82,20 @@ class APIRequest {
64
82
  'x-debug-options': 'bugReporterEnabled',
65
83
  'x-discord-locale': 'en-US',
66
84
  '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')}`,
85
+ 'x-super-properties': `${Buffer.from(JSON.stringify(this.client.options.ws.properties), 'ascii').toString(
86
+ 'base64',
87
+ )}`,
71
88
  Referer: 'https://discord.com/channels/@me',
72
89
  origin: 'https://discord.com',
73
90
  'Referrer-Policy': 'strict-origin-when-cross-origin',
91
+ ...this.client.options.http.headers,
92
+ 'User-Agent': this.fullUserAgent,
74
93
  };
75
94
 
76
95
  if (this.options.auth !== false) headers.Authorization = this.rest.getAuth();
77
96
  if (this.options.reason) headers['X-Audit-Log-Reason'] = encodeURIComponent(this.options.reason);
78
97
  if (this.options.headers) headers = Object.assign(headers, this.options.headers);
98
+
79
99
  // Delete all headers if undefined
80
100
  for (const [key, value] of Object.entries(headers)) {
81
101
  if (value === undefined) delete headers[key];
@@ -85,9 +105,15 @@ class APIRequest {
85
105
  'User-Agent': this.client.options.http.headers['User-Agent'],
86
106
  };
87
107
  }
88
- if (captchaKey && typeof captchaKey == 'string') {
89
- headers['x-captcha-key'] = captchaKey;
90
- if (captchaRqtoken) headers['x-captcha-rqtoken'] = captchaRqtoken;
108
+
109
+ // Some options
110
+ if (this.options.DiscordContext) {
111
+ headers['X-Context-Properties'] = Buffer.from(JSON.stringify(this.options.DiscordContext), 'utf8').toString(
112
+ 'base64',
113
+ );
114
+ }
115
+ if (this.options.mfaToken) {
116
+ headers['X-Discord-Mfa-Authorization'] = this.options.mfaToken;
91
117
  }
92
118
 
93
119
  let body;
@@ -106,19 +132,21 @@ class APIRequest {
106
132
  headers = Object.assign(headers, body.getHeaders());
107
133
  // eslint-disable-next-line eqeqeq
108
134
  } else if (this.options.data != null) {
109
- if (this.options.useFormDataPayloadJSON) {
135
+ if (this.options.usePayloadJSON) {
110
136
  body = new FormData();
111
137
  body.append('payload_json', JSON.stringify(this.options.data));
112
- headers = Object.assign(headers, body.getHeaders());
113
138
  } else {
114
139
  body = JSON.stringify(this.options.data);
115
140
  headers['Content-Type'] = 'application/json';
116
141
  }
117
142
  }
118
143
 
144
+ // Captcha
145
+ if (captchaKey && typeof captchaKey == 'string') headers['X-Captcha-Key'] = captchaKey;
146
+ if (captchaRqToken && typeof captchaRqToken == 'string') headers['X-Captcha-Rqtoken'] = captchaRqToken;
147
+
119
148
  const controller = new AbortController();
120
149
  const timeout = setTimeout(() => controller.abort(), this.client.options.restRequestTimeout).unref();
121
-
122
150
  return fetch(url, {
123
151
  method: this.method,
124
152
  headers,