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,7 +3,7 @@
3
3
  const ThreadManager = require('./ThreadManager');
4
4
  const { TypeError } = require('../errors');
5
5
  const MessagePayload = require('../structures/MessagePayload');
6
- const { resolveAutoArchiveMaxLimit, getAttachments, uploadFile } = require('../util/Util');
6
+ const { resolveAutoArchiveMaxLimit, getUploadURL, uploadFile } = require('../util/Util');
7
7
 
8
8
  /**
9
9
  * Manages API methods for threads in forum channels and stores their cache.
@@ -20,7 +20,7 @@ class GuildForumThreadManager extends ThreadManager {
20
20
  * @typedef {BaseMessageOptions} GuildForumThreadMessageCreateOptions
21
21
  * @property {StickerResolvable} [stickers] The stickers to send with the message
22
22
  * @property {BitFieldResolvable} [flags] The flags to send with the message.
23
- * Only `SUPPRESS_EMBEDS`, `SUPPRESS_NOTIFICATIONS` and `IS_VOICE_MESSAGE` can be set.
23
+ * Only `SUPPRESS_EMBEDS` and `SUPPRESS_NOTIFICATIONS` can be set.
24
24
  */
25
25
 
26
26
  /**
@@ -63,51 +63,45 @@ class GuildForumThreadManager extends ThreadManager {
63
63
  let messagePayload;
64
64
 
65
65
  if (message instanceof MessagePayload) {
66
- messagePayload = await message.resolveData();
66
+ messagePayload = message.resolveData();
67
67
  } else {
68
- messagePayload = await MessagePayload.create(this, message).resolveData();
68
+ messagePayload = MessagePayload.create(this, message).resolveData();
69
69
  }
70
70
 
71
- let { data: body, files } = await messagePayload.resolveFiles();
71
+ const { data: body, files } = await messagePayload.resolveFiles();
72
72
 
73
- if (typeof message == 'object' && typeof message.usingNewAttachmentAPI !== 'boolean') {
74
- message.usingNewAttachmentAPI = this.client.options.usingNewAttachmentAPI;
75
- }
76
-
77
- if (message?.usingNewAttachmentAPI === true) {
78
- const attachments = await getAttachments(this.client, this.channel.id, ...files);
79
- const requestPromises = attachments.map(async attachment => {
80
- await uploadFile(files[attachment.id].file, attachment.upload_url);
81
- return {
82
- id: attachment.id,
83
- filename: files[attachment.id].name,
84
- uploaded_filename: attachment.upload_filename,
85
- description: files[attachment.id].description,
86
- duration_secs: files[attachment.id].duration_secs,
87
- waveform: files[attachment.id].waveform,
88
- };
89
- });
90
- const attachmentsData = await Promise.all(requestPromises);
91
- attachmentsData.sort((a, b) => parseInt(a.id) - parseInt(b.id));
92
- body.attachments = attachmentsData;
93
- files = [];
94
- }
73
+ // New API
74
+ const attachments = await getUploadURL(this.client, this.channel.id, files);
75
+ const requestPromises = attachments.map(async attachment => {
76
+ await uploadFile(files[attachment.id].file, attachment.upload_url);
77
+ return {
78
+ id: attachment.id,
79
+ filename: files[attachment.id].name,
80
+ uploaded_filename: attachment.upload_filename,
81
+ description: files[attachment.id].description,
82
+ duration_secs: files[attachment.id].duration_secs,
83
+ waveform: files[attachment.id].waveform,
84
+ };
85
+ });
86
+ const attachmentsData = await Promise.all(requestPromises);
87
+ attachmentsData.sort((a, b) => parseInt(a.id) - parseInt(b.id));
95
88
 
96
89
  if (autoArchiveDuration === 'MAX') autoArchiveDuration = resolveAutoArchiveMaxLimit(this.channel.guild);
97
90
 
98
- const data = await this.client.api.channels(this.channel.id).threads.post({
91
+ const post_data = await this.client.api.channels(this.channel.id).threads.post({
99
92
  data: {
100
93
  name,
101
94
  auto_archive_duration: autoArchiveDuration,
102
95
  rate_limit_per_user: rateLimitPerUser,
103
96
  applied_tags: appliedTags,
104
97
  message: body,
98
+ attachments: attachmentsData,
105
99
  },
106
- files,
100
+ files: [],
107
101
  reason,
108
102
  });
109
103
 
110
- return this.client.actions.ThreadCreate.handle(data).thread;
104
+ return this.client.actions.ThreadCreate.handle(post_data).thread;
111
105
  }
112
106
  }
113
107
 
@@ -162,7 +162,6 @@ class GuildManager extends CachedManager {
162
162
 
163
163
  /**
164
164
  * Creates a guild.
165
- * <warn>This is only available to bots in fewer than 10 guilds.</warn>
166
165
  * @param {string} name The name of the guild
167
166
  * @param {GuildCreateOptions} [options] Options for creating the guild
168
167
  * @returns {Promise<Guild>} The guild that was created
@@ -238,6 +237,7 @@ class GuildManager extends CachedManager {
238
237
  afk_timeout: afkTimeout,
239
238
  system_channel_id: systemChannelId,
240
239
  system_channel_flags: systemChannelFlags,
240
+ guild_template_code: '2TffvPucqHkN', // From Discord
241
241
  },
242
242
  });
243
243
 
@@ -1,10 +1,9 @@
1
+ /* eslint-disable newline-per-chained-call */
1
2
  'use strict';
2
3
 
3
4
  const { Buffer } = require('node:buffer');
4
5
  const { setTimeout } = require('node:timers');
5
6
  const { Collection } = require('@discordjs/collection');
6
- require('lodash.permutations');
7
- const _ = require('lodash');
8
7
  const CachedManager = require('./CachedManager');
9
8
  const { Error, TypeError, RangeError } = require('../errors');
10
9
  const BaseGuildVoiceChannel = require('../structures/BaseGuildVoiceChannel');
@@ -191,26 +190,17 @@ class GuildMemberManager extends CachedManager {
191
190
  * guild.members.fetch({ query: 'hydra', limit: 1 })
192
191
  * .then(console.log)
193
192
  * .catch(console.error);
194
- * @see {@link https://github.com/aiko-chan-ai/discord.js-selfbot-v13/blob/main/Document/FetchGuildMember.md}
195
193
  */
196
194
  fetch(options) {
197
- if (!options || (typeof options === 'object' && !('user' in options) && !('query' in options))) {
195
+ if (!options) {
198
196
  if (
199
- this.guild.members.me.permissions.has('KICK_MEMBERS') ||
200
- this.guild.members.me.permissions.has('BAN_MEMBERS') ||
201
- this.guild.members.me.permissions.has('MANAGE_ROLES')
197
+ this.me.permissions.has('KICK_MEMBERS') ||
198
+ this.me.permissions.has('BAN_MEMBERS') ||
199
+ this.me.permissions.has('MANAGE_ROLES')
202
200
  ) {
203
201
  return this._fetchMany();
204
202
  } else {
205
203
  return this.fetchByMemberSafety();
206
- /*
207
- NOTE: This is a very slow method, and can take up to 999+ minutes to complete.
208
- this.fetchBruteforce({
209
- delay: 50,
210
- skipWarn: true,
211
- depth: 1,
212
- });
213
- */
214
204
  }
215
205
  }
216
206
  const user = this.client.users.resolveId(options);
@@ -473,248 +463,86 @@ class GuildMemberManager extends CachedManager {
473
463
  }
474
464
 
475
465
  /**
476
- * Options used to fetch multiple members from a guild.
477
- * @typedef {Object} BruteforceOptions
478
- * @property {number} [limit=100] Maximum number of members per request
479
- * @property {number} [delay=500] Timeout for new requests in ms
480
- * @property {number} [depth=1] Permutations length
466
+ * Adds a role to a member.
467
+ * @param {GuildMemberResolvable} user The user to add the role from
468
+ * @param {RoleResolvable} role The role to add
469
+ * @param {string} [reason] Reason for adding the role
470
+ * @returns {Promise<GuildMember|User|Snowflake>}
481
471
  */
472
+ async addRole(user, role, reason) {
473
+ const userId = this.guild.members.resolveId(user);
474
+ const roleId = this.guild.roles.resolveId(role);
475
+
476
+ await this.client.api.guilds(this.guild.id).members(userId).roles(roleId).put({ reason });
477
+
478
+ return this.resolve(user) ?? this.client.users.resolve(user) ?? userId;
479
+ }
482
480
 
483
481
  /**
484
- * Fetches multiple members from the guild.
485
- * @param {BruteforceOptions} options Options for the bruteforce
486
- * @returns {Collection<Snowflake, GuildMember>} (All) members in the guild
487
- * @see https://github.com/aiko-chan-ai/discord.js-selfbot-v13/blob/main/Document/FetchGuildMember.md
488
- * @example
489
- * guild.members.fetchBruteforce()
490
- * .then(members => console.log(`Fetched ${members.size} members`))
491
- * .catch(console.error);
482
+ * Removes a role from a member.
483
+ * @param {UserResolvable} user The user to remove the role from
484
+ * @param {RoleResolvable} role The role to remove
485
+ * @param {string} [reason] Reason for removing the role
486
+ * @returns {Promise<GuildMember|User|Snowflake>}
492
487
  */
493
- fetchBruteforce(options = {}) {
494
- const defaultQuery = 'abcdefghijklmnopqrstuvwxyz0123456789!"#$%&\'()*+,-./:;<=>?@[]^_`{|}~ ';
495
- let dictionary;
496
- let limit = 100;
497
- let delay = 500;
498
- let depth = 1;
499
- if (options?.limit) limit = options?.limit;
500
- if (options?.delay) delay = options?.delay;
501
- if (options?.depth) depth = options?.depth;
502
- if (typeof limit !== 'number') throw new TypeError('INVALID_TYPE', 'limit', 'Number');
503
- if (limit < 1 || limit > 100) throw new RangeError('INVALID_RANGE_QUERY_MEMBER');
504
- if (typeof delay !== 'number') throw new TypeError('INVALID_TYPE', 'delay', 'Number');
505
- if (typeof depth !== 'number') throw new TypeError('INVALID_TYPE', 'depth', 'Number');
506
- if (depth < 1) throw new RangeError('INVALID_RANGE_QUERY_MEMBER');
507
- if (depth > 2) {
508
- console.warn(`[WARNING] GuildMemberManager#fetchBruteforce: depth greater than 2, can lead to very slow speeds`);
509
- }
510
- if (delay < 500 && !options?.skipWarn) {
511
- console.warn(
512
- `[WARNING] GuildMemberManager#fetchBruteforce: delay is less than 500ms, this may cause rate limits.`,
513
- );
514
- }
515
- let skipValues = [];
516
- // eslint-disable-next-line no-async-promise-executor
517
- return new Promise(async (resolve, reject) => {
518
- for (let i = 1; i <= depth; i++) {
519
- dictionary = _(defaultQuery)
520
- .permutations(i)
521
- .map(v => _.join(v, ''))
522
- .value();
523
- for (const query of dictionary) {
524
- if (this.guild.members.cache.size >= this.guild.memberCount) break;
525
- this.client.emit(
526
- 'debug',
527
- `[INFO] GuildMemberManager#fetchBruteforce: Querying ${query}, Skip: [${skipValues.join(', ')}]`,
528
- );
529
- if (skipValues.some(v => query.startsWith(v))) continue;
530
- await this._fetchMany({ query, limit })
531
- .then(members => {
532
- if (members.size === 0) skipValues.push(query);
533
- })
534
- .catch(reject);
535
- await this.guild.client.sleep(delay);
536
- }
537
- }
538
- resolve(this.guild.members.cache);
539
- });
488
+ async removeRole(user, role, reason) {
489
+ const userId = this.guild.members.resolveId(user);
490
+ const roleId = this.guild.roles.resolveId(role);
491
+
492
+ await this.client.api.guilds(this.guild.id).members(userId).roles(roleId).delete({ reason });
493
+
494
+ return this.resolve(user) ?? this.client.users.resolve(user) ?? userId;
540
495
  }
541
496
 
542
497
  /**
543
- * Experimental method to fetch all members from the guild.
544
- * @param {number} [timeout=120000] Timeout for receipt of members in ms
498
+ * Experimental method to fetch members from the guild.
499
+ * <info>Lists up to 10000 members of the guild.</info>
500
+ * @param {number} [timeout=15_000] Timeout for receipt of members in ms
545
501
  * @returns {Promise<Collection<Snowflake, GuildMember>>}
546
502
  */
547
- fetchByMemberSafety(timeout = 120_000) {
503
+ fetchByMemberSafety(timeout = 15_000) {
548
504
  return new Promise(resolve => {
505
+ const nonce = SnowflakeUtil.generate();
506
+ const fetchedMembers = new Collection();
549
507
  let timeout_ = setTimeout(() => {
550
- this.client.removeListener(Events.GUILD_MEMBER_LIST_UPDATE, handler);
551
- resolve(this.guild.members.cache);
508
+ this.client.removeListener(Events.GUILD_MEMBERS_CHUNK, handler);
509
+ resolve(fetchedMembers);
552
510
  }, timeout).unref();
553
- const handler = (members, guild, raw) => {
554
- if (guild.id == this.guild.id && !raw.nonce && raw.index == 0 && raw.count == 1) {
511
+ const handler = (members, guild, chunk) => {
512
+ if (guild.id == this.guild.id && chunk.nonce == nonce) {
555
513
  if (members.size > 0) {
514
+ for (const member of members.values()) {
515
+ fetchedMembers.set(member.id, member);
516
+ }
556
517
  this.client.ws.broadcast({
557
- op: 35,
518
+ op: Opcodes.SEARCH_RECENT_MEMBERS,
558
519
  d: {
559
520
  guild_id: this.guild.id,
560
521
  query: '',
561
522
  continuation_token: members.first()?.id,
523
+ nonce,
562
524
  },
563
525
  });
564
526
  } else {
565
527
  clearTimeout(timeout_);
566
- this.client.removeListener(Events.GUILD_MEMBER_LIST_UPDATE, handler);
567
- resolve(this.guild.members.cache);
528
+ this.client.removeListener(Events.GUILD_MEMBERS_CHUNK, handler);
529
+ resolve(fetchedMembers);
568
530
  }
569
531
  }
570
532
  };
571
- this.client.on('guildMembersChunk', handler);
533
+ this.client.on(Events.GUILD_MEMBERS_CHUNK, handler);
572
534
  this.client.ws.broadcast({
573
- op: 35,
535
+ op: Opcodes.SEARCH_RECENT_MEMBERS,
574
536
  d: {
575
537
  guild_id: this.guild.id,
576
538
  query: '',
577
539
  continuation_token: null,
540
+ nonce,
578
541
  },
579
542
  });
580
543
  });
581
544
  }
582
545
 
583
- /**
584
- * Fetches multiple members from the guild in the channel.
585
- * @param {GuildTextChannelResolvable} channel The channel to get members from (Members has VIEW_CHANNEL permission)
586
- * @param {number} [offset=0] Start index of the members to get
587
- * @param {boolean} [double=false] Whether to use double range
588
- * @param {number} [retryMax=3] Number of retries
589
- * @param {number} [time=10e3] Timeout for receipt of members
590
- * @returns {Collection<Snowflake, GuildMember>} Members in the guild
591
- * @see {@link https://github.com/aiko-chan-ai/discord.js-selfbot-v13/blob/main/Document/FetchGuildMember.md}
592
- * @example
593
- * const guild = client.guilds.cache.get('id');
594
- * const channel = guild.channels.cache.get('id');
595
- * // Overlap (slow)
596
- * for (let index = 0; index <= guild.memberCount; index += 100) {
597
- * await guild.members.fetchMemberList(channel, index, index !== 100).catch(() => {});
598
- * await client.sleep(500);
599
- * }
600
- * // Non-overlap (fast)
601
- * for (let index = 0; index <= guild.memberCount; index += 200) {
602
- * await guild.members.fetchMemberList(channel, index == 0 ? 100 : index, index !== 100).catch(() => {});
603
- * await client.sleep(500);
604
- * }
605
- * console.log(guild.members.cache.size); // will print the number of members in the guild
606
- */
607
- fetchMemberList(channel, offset = 0, double = false, retryMax = 3, time = 10_000) {
608
- const channel_ = this.guild.channels.resolve(channel);
609
- if (!channel_?.isText()) throw new TypeError('INVALID_TYPE', 'channel', 'GuildTextChannelResolvable');
610
- if (typeof offset !== 'number') throw new TypeError('INVALID_TYPE', 'offset', 'Number');
611
- if (typeof time !== 'number') throw new TypeError('INVALID_TYPE', 'time', 'Number');
612
- if (typeof retryMax !== 'number') throw new TypeError('INVALID_TYPE', 'retryMax', 'Number');
613
- if (retryMax < 1) throw new RangeError('INVALID_RANGE_RETRY');
614
- if (typeof double !== 'boolean') throw new TypeError('INVALID_TYPE', 'double', 'Boolean');
615
- // TODO: if (this.guild.large) throw new Error('GUILD_IS_LARGE');
616
- return new Promise((resolve, reject) => {
617
- const default_ = [[0, 99]];
618
- const fetchedMembers = new Collection();
619
- if (offset > 99) {
620
- // eslint-disable-next-line no-unused-expressions
621
- double
622
- ? default_.push([offset, offset + 99], [offset + 100, offset + 199])
623
- : default_.push([offset, offset + 99]);
624
- }
625
- let retry = 0;
626
- const handler = (members, guild, type, raw) => {
627
- timeout.refresh();
628
- if (guild.id !== this.guild.id) return;
629
- if (type == 'INVALIDATE' && offset > 100) {
630
- if (retry < retryMax) {
631
- this.guild.shard.send({
632
- op: Opcodes.GUILD_SUBSCRIPTIONS,
633
- d: {
634
- guild_id: this.guild.id,
635
- typing: true,
636
- threads: true,
637
- activities: true,
638
- channels: {
639
- [channel_.id]: default_,
640
- },
641
- thread_member_lists: [],
642
- members: [],
643
- },
644
- });
645
- retry++;
646
- } else {
647
- clearTimeout(timeout);
648
- this.client.removeListener(Events.GUILD_MEMBER_LIST_UPDATE, handler);
649
- this.client.decrementMaxListeners();
650
- reject(new Error('INVALIDATE_MEMBER', raw.ops[0].range));
651
- }
652
- } else {
653
- for (const member of members.values()) {
654
- fetchedMembers.set(member.id, member);
655
- }
656
- clearTimeout(timeout);
657
- this.client.removeListener(Events.GUILD_MEMBER_LIST_UPDATE, handler);
658
- this.client.decrementMaxListeners();
659
- resolve(fetchedMembers);
660
- }
661
- };
662
- const timeout = setTimeout(() => {
663
- this.client.removeListener(Events.GUILD_MEMBER_LIST_UPDATE, handler);
664
- this.client.decrementMaxListeners();
665
- reject(new Error('GUILD_MEMBERS_TIMEOUT'));
666
- }, time).unref();
667
- this.client.incrementMaxListeners();
668
- this.client.on(Events.GUILD_MEMBER_LIST_UPDATE, handler);
669
- this.guild.shard.send({
670
- op: Opcodes.GUILD_SUBSCRIPTIONS,
671
- d: {
672
- guild_id: this.guild.id,
673
- typing: true,
674
- threads: true,
675
- activities: true,
676
- channels: {
677
- [channel_.id]: default_,
678
- },
679
- thread_member_lists: [],
680
- members: [],
681
- },
682
- });
683
- });
684
- }
685
-
686
- /**
687
- * Adds a role to a member.
688
- * @param {GuildMemberResolvable} user The user to add the role from
689
- * @param {RoleResolvable} role The role to add
690
- * @param {string} [reason] Reason for adding the role
691
- * @returns {Promise<GuildMember|User|Snowflake>}
692
- */
693
- async addRole(user, role, reason) {
694
- const userId = this.guild.members.resolveId(user);
695
- const roleId = this.guild.roles.resolveId(role);
696
-
697
- await this.client.api.guilds(this.guild.id).members(userId).roles(roleId).put({ reason });
698
-
699
- return this.resolve(user) ?? this.client.users.resolve(user) ?? userId;
700
- }
701
-
702
- /**
703
- * Removes a role from a member.
704
- * @param {UserResolvable} user The user to remove the role from
705
- * @param {RoleResolvable} role The role to remove
706
- * @param {string} [reason] Reason for removing the role
707
- * @returns {Promise<GuildMember|User|Snowflake>}
708
- */
709
- async removeRole(user, role, reason) {
710
- const userId = this.guild.members.resolveId(user);
711
- const roleId = this.guild.roles.resolveId(role);
712
-
713
- await this.client.api.guilds(this.guild.id).members(userId).roles(roleId).delete({ reason });
714
-
715
- return this.resolve(user) ?? this.client.users.resolve(user) ?? userId;
716
- }
717
-
718
546
  _fetchMany({
719
547
  limit = 0,
720
548
  withPresences: presences = true,
@@ -7,19 +7,24 @@ const BaseManager = require('./BaseManager');
7
7
  * @see {@link https://luna.gitlab.io/discord-unofficial-docs/user_settings.html}
8
8
  */
9
9
  class GuildSettingManager extends BaseManager {
10
- constructor(client, guildId = null) {
11
- super(client);
12
- /**
13
- * Raw data
14
- * @type {Object}
15
- */
16
- this.rawSetting = {};
10
+ #rawSetting = {};
11
+ constructor(guild) {
12
+ super(guild.client);
17
13
  /**
18
14
  * Guild Id
19
15
  * @type {?Snowflake}
20
16
  */
21
- this.guildId = guildId;
17
+ this.guildId = guild.id;
18
+ }
19
+
20
+ /**
21
+ * Raw data
22
+ * @type {Object}
23
+ */
24
+ get raw() {
25
+ return this.#rawSetting;
22
26
  }
27
+
23
28
  /**
24
29
  * Get the guild
25
30
  * @type {?Guild}
@@ -28,13 +33,15 @@ class GuildSettingManager extends BaseManager {
28
33
  get guild() {
29
34
  return this.client.guilds.cache.get(this.guildId);
30
35
  }
36
+
31
37
  /**
32
38
  * Patch data file
33
39
  * @private
34
40
  * @param {Object} data Raw Data to patch
35
41
  */
36
42
  _patch(data = {}) {
37
- this.rawSetting = Object.assign(this.rawSetting, data);
43
+ this.#rawSetting = Object.assign(this.#rawSetting, data);
44
+ this.client.emit('debug', `[SETTING > Guild ${this.guildId}] Sync setting`);
38
45
  if ('suppress_everyone' in data) {
39
46
  /**
40
47
  * Notification setting > Suppress `@everyone` and `@here`
@@ -59,9 +66,9 @@ class GuildSettingManager extends BaseManager {
59
66
  if ('message_notifications' in data) {
60
67
  /**
61
68
  * Notification setting > Message notifications
62
- * * `0` = All messages
63
- * * `1` = Only @mentions
64
- * * `2` = Nothing
69
+ * * `0`: All messages
70
+ * * `1`: Only @mentions
71
+ * * `2`: Nothing
65
72
  * @type {?number}
66
73
  */
67
74
  this.messageNotifications = data.message_notifications;
@@ -118,9 +125,9 @@ class GuildSettingManager extends BaseManager {
118
125
  if ('notify_highlights' in data) {
119
126
  /**
120
127
  * Notification setting > Suppress highlights
121
- * * `0` = ??? (unknown)
122
- * * `1` = Enable
123
- * * `2` = Disable
128
+ * * `0`: ??? (unknown)
129
+ * * `1`: Enable
130
+ * * `2`: Disable
124
131
  * @type {?number}
125
132
  */
126
133
  this.notifyHighlights = data.notify_highlights;
@@ -2,7 +2,7 @@
2
2
 
3
3
  const { Collection } = require('@discordjs/collection');
4
4
  const CachedManager = require('./CachedManager');
5
- const { TypeError, Error } = require('../errors');
5
+ const { TypeError } = require('../errors');
6
6
  const { Message } = require('../structures/Message');
7
7
  const MessagePayload = require('../structures/MessagePayload');
8
8
  const Util = require('../util/Util');
@@ -123,38 +123,32 @@ class MessageManager extends CachedManager {
123
123
  const messageId = this.resolveId(message);
124
124
  if (!messageId) throw new TypeError('INVALID_TYPE', 'message', 'MessageResolvable');
125
125
 
126
- let messagePayload;
127
- if (options instanceof MessagePayload) {
128
- messagePayload = await options.resolveData();
129
- } else {
130
- messagePayload = await MessagePayload.create(message instanceof Message ? message : this, options).resolveData();
131
- }
132
- let { data, files } = await messagePayload.resolveFiles();
133
-
134
- if (typeof options == 'object' && typeof options.usingNewAttachmentAPI !== 'boolean') {
135
- options.usingNewAttachmentAPI = this.client.options.usingNewAttachmentAPI;
136
- }
137
-
138
- if (options?.usingNewAttachmentAPI === true) {
139
- const attachments = await Util.getAttachments(this.client, this.channel.id, ...files);
140
- const requestPromises = attachments.map(async attachment => {
141
- await Util.uploadFile(files[attachment.id].file, attachment.upload_url);
142
- return {
143
- id: attachment.id,
144
- filename: files[attachment.id].name,
145
- uploaded_filename: attachment.upload_filename,
146
- description: files[attachment.id].description,
147
- duration_secs: files[attachment.id].duration_secs,
148
- waveform: files[attachment.id].waveform,
149
- };
150
- });
151
- const attachmentsData = await Promise.all(requestPromises);
152
- attachmentsData.sort((a, b) => parseInt(a.id) - parseInt(b.id));
153
- data.attachments = attachmentsData;
154
- files = [];
155
- }
126
+ const { data, files } = await (options instanceof MessagePayload
127
+ ? options
128
+ : MessagePayload.create(message instanceof Message ? message : this, options)
129
+ )
130
+ .resolveData()
131
+ .resolveFiles();
132
+
133
+ // New API
134
+ const attachments = await Util.getUploadURL(this.client, this.channel.id, files);
135
+ const requestPromises = attachments.map(async attachment => {
136
+ await Util.uploadFile(files[attachment.id].file, attachment.upload_url);
137
+ return {
138
+ id: attachment.id,
139
+ filename: files[attachment.id].name,
140
+ uploaded_filename: attachment.upload_filename,
141
+ description: files[attachment.id].description,
142
+ duration_secs: files[attachment.id].duration_secs,
143
+ waveform: files[attachment.id].waveform,
144
+ };
145
+ });
146
+ const attachmentsData = await Promise.all(requestPromises);
147
+ attachmentsData.sort((a, b) => parseInt(a.id) - parseInt(b.id));
148
+ data.attachments = attachmentsData;
149
+ // Empty Files
156
150
 
157
- const d = await this.client.api.channels[this.channel.id].messages[messageId].patch({ data, files });
151
+ const d = await this.client.api.channels[this.channel.id].messages[messageId].patch({ data });
158
152
 
159
153
  const existing = this.cache.get(messageId);
160
154
  if (existing) {
@@ -251,12 +245,16 @@ class MessageManager extends CachedManager {
251
245
  const existing = this.cache.get(messageId);
252
246
  if (existing && !existing.partial) return existing;
253
247
  }
248
+
254
249
  // https://discord.com/api/v9/channels/:id/messages?limit=50&around=:msgid
255
250
  return new Promise((resolve, reject) => {
256
- this._fetchMany({
257
- around: messageId,
258
- limit: 50,
259
- })
251
+ this._fetchMany(
252
+ {
253
+ around: messageId,
254
+ limit: 50,
255
+ },
256
+ cache,
257
+ )
260
258
  .then(data_ =>
261
259
  data_.has(messageId) ? resolve(data_.get(messageId)) : reject(new Error('MESSAGE_ID_NOT_FOUND')),
262
260
  )
@@ -264,13 +262,6 @@ class MessageManager extends CachedManager {
264
262
  });
265
263
  }
266
264
 
267
- async _fetchMany(options = {}, cache) {
268
- const data = await this.client.api.channels[this.channel.id].messages.get({ query: options });
269
- const messages = new Collection();
270
- for (const message of data) messages.set(message.id, this._add(message, cache));
271
- return messages;
272
- }
273
-
274
265
  /**
275
266
  * @typedef {object} MessageSearchOptions
276
267
  * @property {Array<UserResolvable>} [authors] An array of author to filter by
@@ -381,13 +372,20 @@ class MessageManager extends CachedManager {
381
372
  stringQuery = stringQuery.filter(v => !v.startsWith('channel_id') && !v.startsWith('include_nsfw'));
382
373
  data = await this.client.api.channels[this.channel.id].messages[`search?${stringQuery.join('&')}`].get();
383
374
  }
384
- console.log(stringQuery);
375
+
385
376
  for await (const message of data.messages) result.set(message[0].id, new Message(this.client, message[0]));
386
377
  return {
387
378
  messages: result,
388
379
  total: data.total_results,
389
380
  };
390
381
  }
382
+
383
+ async _fetchMany(options = {}, cache) {
384
+ const data = await this.client.api.channels[this.channel.id].messages.get({ query: options });
385
+ const messages = new Collection();
386
+ for (const message of data) messages.set(message.id, this._add(message, cache));
387
+ return messages;
388
+ }
391
389
  }
392
390
 
393
391
  module.exports = MessageManager;
@@ -89,7 +89,7 @@ class PermissionOverwriteManager extends CachedManager {
89
89
  * @private
90
90
  */
91
91
  async upsert(userOrRole, options, overwriteOptions = {}, existing) {
92
- const userOrRoleId = this.channel.guild.roles.resolveId(userOrRole) ?? this.client.users.resolveId(userOrRole);
92
+ let userOrRoleId = this.channel.guild.roles.resolveId(userOrRole) ?? this.client.users.resolveId(userOrRole);
93
93
  let { type, reason } = overwriteOptions;
94
94
  if (typeof type !== 'number') {
95
95
  userOrRole = this.channel.guild.roles.resolve(userOrRole) ?? this.client.users.resolve(userOrRole);