djs-selfbot-v13 3.1.6 → 3.1.7

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 (148) hide show
  1. package/README.md +31 -16
  2. package/package.json +15 -8
  3. package/src/client/BaseClient.js +3 -2
  4. package/src/client/Client.js +539 -187
  5. package/src/client/actions/Action.js +13 -18
  6. package/src/client/actions/ActionsManager.js +1 -7
  7. package/src/client/actions/AutoModerationActionExecution.js +0 -1
  8. package/src/client/actions/AutoModerationRuleCreate.js +0 -1
  9. package/src/client/actions/AutoModerationRuleDelete.js +0 -1
  10. package/src/client/actions/AutoModerationRuleUpdate.js +0 -1
  11. package/src/client/actions/InteractionCreate.js +115 -0
  12. package/src/client/actions/MessageCreate.js +4 -0
  13. package/src/client/actions/PresenceUpdate.js +16 -17
  14. package/src/client/websocket/WebSocketManager.js +31 -11
  15. package/src/client/websocket/WebSocketShard.js +38 -39
  16. package/src/client/websocket/handlers/APPLICATION_COMMAND_AUTOCOMPLETE_RESPONSE.js +23 -0
  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 +13 -16
  21. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_REMOVE.js +11 -11
  22. package/src/client/websocket/handlers/GUILD_APPLICATION_COMMANDS_UPDATE.js +11 -0
  23. package/src/client/websocket/handlers/GUILD_CREATE.js +0 -7
  24. package/src/client/websocket/handlers/GUILD_MEMBER_LIST_UPDATE.js +55 -0
  25. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUNDS_UPDATE.js +0 -0
  26. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.js +0 -0
  27. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.js +0 -0
  28. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.js +0 -0
  29. package/src/client/websocket/handlers/INTERACTION_CREATE.js +16 -0
  30. package/src/client/websocket/handlers/INTERACTION_FAILURE.js +18 -0
  31. package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +0 -1
  32. package/src/client/websocket/handlers/INTERACTION_SUCCESS.js +30 -0
  33. package/src/client/websocket/handlers/MESSAGE_ACK.js +16 -0
  34. package/src/client/websocket/handlers/READY.js +137 -47
  35. package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +5 -7
  36. package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +4 -6
  37. package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +9 -32
  38. package/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.js +0 -0
  39. package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +8 -2
  40. package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +1 -1
  41. package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +5 -1
  42. package/src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.js +0 -0
  43. package/src/client/websocket/handlers/index.js +20 -15
  44. package/src/errors/Messages.js +69 -24
  45. package/src/index.js +43 -12
  46. package/src/managers/ApplicationCommandManager.js +12 -9
  47. package/src/managers/ApplicationCommandPermissionsManager.js +11 -3
  48. package/src/managers/ChannelManager.js +4 -2
  49. package/src/managers/ClientUserSettingManager.js +279 -161
  50. package/src/managers/DeveloperPortalManager.js +104 -0
  51. package/src/managers/GuildApplicationCommandManager.js +28 -0
  52. package/src/managers/GuildBanManager.js +1 -1
  53. package/src/managers/GuildChannelManager.js +0 -2
  54. package/src/managers/GuildFolderManager.js +24 -0
  55. package/src/managers/GuildForumThreadManager.js +28 -22
  56. package/src/managers/GuildMemberManager.js +216 -40
  57. package/src/managers/GuildSettingManager.js +15 -22
  58. package/src/managers/MessageManager.js +44 -42
  59. package/src/managers/PermissionOverwriteManager.js +1 -1
  60. package/src/managers/ReactionUserManager.js +5 -5
  61. package/src/managers/RelationshipManager.js +74 -81
  62. package/src/managers/SessionManager.js +57 -0
  63. package/src/managers/ThreadManager.js +45 -12
  64. package/src/managers/ThreadMemberManager.js +1 -1
  65. package/src/managers/UserManager.js +10 -6
  66. package/src/rest/APIRequest.js +20 -42
  67. package/src/rest/CaptchaSolver.js +132 -0
  68. package/src/rest/DiscordAPIError.js +16 -17
  69. package/src/rest/RESTManager.js +21 -1
  70. package/src/rest/RequestHandler.js +21 -35
  71. package/src/structures/ApplicationCommand.js +456 -19
  72. package/src/structures/ApplicationRoleConnectionMetadata.js +0 -3
  73. package/src/structures/AutoModerationRule.js +5 -5
  74. package/src/structures/AutocompleteInteraction.js +0 -1
  75. package/src/structures/BaseGuildTextChannel.js +12 -10
  76. package/src/structures/BaseGuildVoiceChannel.js +18 -16
  77. package/src/structures/{CallState.js → Call.js} +12 -17
  78. package/src/structures/CategoryChannel.js +0 -2
  79. package/src/structures/Channel.js +3 -2
  80. package/src/structures/ClientApplication.js +204 -0
  81. package/src/structures/ClientPresence.js +8 -12
  82. package/src/structures/ClientUser.js +336 -117
  83. package/src/structures/ContextMenuInteraction.js +1 -1
  84. package/src/structures/DMChannel.js +92 -29
  85. package/src/structures/DeveloperPortalApplication.js +520 -0
  86. package/src/structures/ForumChannel.js +10 -0
  87. package/src/structures/Guild.js +271 -135
  88. package/src/structures/GuildAuditLogs.js +5 -0
  89. package/src/structures/GuildChannel.js +2 -16
  90. package/src/structures/GuildFolder.js +75 -0
  91. package/src/structures/GuildMember.js +145 -27
  92. package/src/structures/Interaction.js +62 -1
  93. package/src/structures/InteractionResponse.js +114 -0
  94. package/src/structures/Invite.js +52 -35
  95. package/src/structures/Message.js +202 -222
  96. package/src/structures/MessageAttachment.js +0 -11
  97. package/src/structures/MessageButton.js +67 -1
  98. package/src/structures/MessageEmbed.js +1 -1
  99. package/src/structures/MessageMentions.js +2 -3
  100. package/src/structures/MessagePayload.js +46 -4
  101. package/src/structures/MessageReaction.js +1 -1
  102. package/src/structures/MessageSelectMenu.js +252 -1
  103. package/src/structures/Modal.js +180 -75
  104. package/src/structures/PartialGroupDMChannel.js +433 -0
  105. package/src/structures/Presence.js +2 -2
  106. package/src/structures/RichPresence.js +34 -14
  107. package/src/structures/Role.js +2 -18
  108. package/src/structures/SelectMenuInteraction.js +151 -2
  109. package/src/structures/Session.js +81 -0
  110. package/src/structures/Team.js +49 -0
  111. package/src/structures/TextInputComponent.js +70 -0
  112. package/src/structures/ThreadChannel.js +19 -0
  113. package/src/structures/User.js +345 -117
  114. package/src/structures/UserContextMenuInteraction.js +2 -2
  115. package/src/structures/VoiceState.js +39 -74
  116. package/src/structures/WebEmbed.js +52 -38
  117. package/src/structures/Webhook.js +11 -17
  118. package/src/structures/interfaces/Application.js +23 -146
  119. package/src/structures/interfaces/TextBasedChannel.js +256 -411
  120. package/src/util/ApplicationFlags.js +1 -1
  121. package/src/util/Constants.js +284 -106
  122. package/src/util/Formatters.js +2 -16
  123. package/src/util/LimitedCollection.js +1 -1
  124. package/src/util/Options.js +68 -48
  125. package/src/util/Permissions.js +0 -5
  126. package/src/util/PurchasedFlags.js +0 -2
  127. package/src/util/RemoteAuth.js +356 -221
  128. package/src/util/Sweepers.js +1 -1
  129. package/src/util/Util.js +36 -76
  130. package/src/util/Voice.js +1456 -0
  131. package/src/util/arRPC/index.js +229 -0
  132. package/src/util/arRPC/process/detectable.json +1 -0
  133. package/src/util/arRPC/process/index.js +102 -0
  134. package/src/util/arRPC/process/native/index.js +5 -0
  135. package/src/util/arRPC/process/native/linux.js +37 -0
  136. package/src/util/arRPC/process/native/win32.js +25 -0
  137. package/src/util/arRPC/transports/ipc.js +281 -0
  138. package/src/util/arRPC/transports/websocket.js +128 -0
  139. package/typings/enums.d.ts +73 -18
  140. package/typings/index.d.ts +1249 -897
  141. package/typings/rawDataTypes.d.ts +9 -68
  142. package/src/client/websocket/handlers/USER_REQUIRED_ACTION_UPDATE.js +0 -78
  143. package/src/client/websocket/handlers/VOICE_CHANNEL_STATUS_UPDATE.js +0 -12
  144. package/src/managers/UserNoteManager.js +0 -53
  145. package/src/structures/GroupDMChannel.js +0 -387
  146. package/src/util/AttachmentFlags.js +0 -38
  147. package/src/util/InviteFlags.js +0 -29
  148. package/src/util/RoleFlags.js +0 -37
@@ -224,6 +224,7 @@ class GuildAuditLogs {
224
224
  this.applicationCommands.set(command.id, new ApplicationCommand(guild.client, command, guild));
225
225
  }
226
226
  }
227
+
227
228
  /**
228
229
  * Cached auto moderation rules.
229
230
  * @type {Collection<Snowflake, AutoModerationRule>}
@@ -486,6 +487,7 @@ class GuildAuditLogsEntry {
486
487
  count: Number(data.options.count),
487
488
  };
488
489
  break;
490
+
489
491
  case Actions.MESSAGE_PIN:
490
492
  case Actions.MESSAGE_UNPIN:
491
493
  this.extra = {
@@ -531,11 +533,13 @@ class GuildAuditLogsEntry {
531
533
  channel: guild.client.channels.cache.get(data.options?.channel_id) ?? { id: data.options?.channel_id },
532
534
  };
533
535
  break;
536
+
534
537
  case Actions.APPLICATION_COMMAND_PERMISSION_UPDATE:
535
538
  this.extra = {
536
539
  applicationId: data.options.application_id,
537
540
  };
538
541
  break;
542
+
539
543
  case Actions.AUTO_MODERATION_BLOCK_MESSAGE:
540
544
  case Actions.AUTO_MODERATION_FLAG_TO_CHANNEL:
541
545
  case Actions.AUTO_MODERATION_USER_COMMUNICATION_DISABLED:
@@ -545,6 +549,7 @@ class GuildAuditLogsEntry {
545
549
  channel: guild.client.channels.cache.get(data.options?.channel_id) ?? { id: data.options?.channel_id },
546
550
  };
547
551
  break;
552
+
548
553
  default:
549
554
  break;
550
555
  }
@@ -5,7 +5,6 @@ const { Error } = require('../errors');
5
5
  const PermissionOverwriteManager = require('../managers/PermissionOverwriteManager');
6
6
  const { VoiceBasedChannelTypes } = require('../util/Constants');
7
7
  const Permissions = require('../util/Permissions');
8
- const Util = require('../util/Util');
9
8
 
10
9
  /**
11
10
  * Represents a guild channel from any of the following:
@@ -146,21 +145,8 @@ class GuildChannel extends Channel {
146
145
  * @readonly
147
146
  */
148
147
  get position() {
149
- const selfIsCategory = this.type === 'GUILD_CATEGORY';
150
- const types = Util.getSortableGroupTypes(this.type);
151
-
152
- let count = 0;
153
- for (const channel of this.guild.channels.cache.values()) {
154
- if (!types.includes(channel.type)) continue;
155
- if (!selfIsCategory && channel.parentId !== this.parentId) continue;
156
- if (this.rawPosition === channel.rawPosition) {
157
- if (BigInt(channel.id) < BigInt(this.id)) count++;
158
- } else if (this.rawPosition > channel.rawPosition) {
159
- count++;
160
- }
161
- }
162
-
163
- return count;
148
+ const sorted = this.guild._sortedChannels(this);
149
+ return [...sorted.values()].indexOf(sorted.get(this.id));
164
150
  }
165
151
 
166
152
  /**
@@ -0,0 +1,75 @@
1
+ 'use strict';
2
+
3
+ const Base = require('./Base');
4
+
5
+ /**
6
+ * Guild Folder.
7
+ * @abstract
8
+ */
9
+ class GuildFolder extends Base {
10
+ constructor(client, data) {
11
+ super(client);
12
+ this._patch(data);
13
+ }
14
+ _patch(data) {
15
+ if ('id' in data) {
16
+ /**
17
+ * The guild folder's id
18
+ * @type {Snowflake}
19
+ */
20
+ this.id = data.id;
21
+ }
22
+
23
+ if ('name' in data) {
24
+ /**
25
+ * The guild folder's name
26
+ * @type {string}
27
+ */
28
+ this.name = data.name;
29
+ }
30
+
31
+ if ('color' in data) {
32
+ /**
33
+ * The base 10 color of the folder
34
+ * @type {number}
35
+ */
36
+ this.color = data.color;
37
+ }
38
+
39
+ if ('guild_ids' in data) {
40
+ /**
41
+ * The guild folder's guild ids
42
+ * @type {Snowflake[]}
43
+ */
44
+ this.guild_ids = data.guild_ids;
45
+ }
46
+ }
47
+ /**
48
+ * The hexadecimal version of the folder color, with a leading hashtag
49
+ * @type {string}
50
+ * @readonly
51
+ */
52
+ get hexColor() {
53
+ return `#${this.color.toString(16).padStart(6, '0')}`;
54
+ }
55
+
56
+ /**
57
+ * Guilds in the folder
58
+ * @type {Collection<Snowflake, Guild>}
59
+ * @readonly
60
+ */
61
+ get guilds() {
62
+ return this.client.guilds.cache.filter(guild => this.guild_ids.includes(guild.id));
63
+ }
64
+
65
+ toJSON() {
66
+ return {
67
+ id: this.id,
68
+ name: this.name,
69
+ color: this.color,
70
+ guild_ids: this.guild_ids,
71
+ };
72
+ }
73
+ }
74
+
75
+ module.exports = GuildFolder;
@@ -8,6 +8,7 @@ const { Error } = require('../errors');
8
8
  const GuildMemberRoleManager = require('../managers/GuildMemberRoleManager');
9
9
  const GuildMemberFlags = require('../util/GuildMemberFlags');
10
10
  const Permissions = require('../util/Permissions');
11
+ const Util = require('../util/Util');
11
12
 
12
13
  /**
13
14
  * @type {WeakSet<GuildMember>}
@@ -101,6 +102,7 @@ class GuildMember extends Base {
101
102
  this.communicationDisabledUntilTimestamp =
102
103
  data.communication_disabled_until && Date.parse(data.communication_disabled_until);
103
104
  }
105
+
104
106
  if ('flags' in data) {
105
107
  /**
106
108
  * The flags of this member
@@ -112,6 +114,51 @@ class GuildMember extends Base {
112
114
  }
113
115
  }
114
116
 
117
+ _ProfilePatch(data) {
118
+ if ('accent_color' in data) {
119
+ /**
120
+ * The member's accent color
121
+ * <info>The user must be force fetched for this property to be present or be updated</info>
122
+ * @type {?number}
123
+ */
124
+ this.accentColor = data.accent_color;
125
+ }
126
+ if ('banner' in data) {
127
+ /**
128
+ * The member's banner hash
129
+ * <info>The user must be force fetched for this property to be present or be updated</info>
130
+ * @type {?string}
131
+ */
132
+ this.banner = data.banner;
133
+ }
134
+ if ('bio' in data) {
135
+ /**
136
+ * The member's biography (About me)
137
+ * <info>The user must be force fetched for this property to be present or be updated</info>
138
+ * @type {?string}
139
+ */
140
+ this.bio = data.bio;
141
+ }
142
+ if ('theme_colors' in data) {
143
+ /**
144
+ * The member's theme colors (Profile theme) [Primary, Accent]
145
+ * <info>The user must be force fetched for this property to be present or be updated</info>
146
+ * @type {?Array<number>}
147
+ */
148
+ this.themeColors = data.theme_colors;
149
+ }
150
+ }
151
+
152
+ /**
153
+ * The hexadecimal version of the user theme color, with a leading hash [Primary, Accent]
154
+ * <info>The user must be force fetched for this property to be present or be updated</info>
155
+ * @type {?Array<string>}
156
+ * @readonly
157
+ */
158
+ get hexThemeColor() {
159
+ return this.themeColors?.map(c => `#${c.toString(16).padStart(6, '0')}`) || null;
160
+ }
161
+
115
162
  _clone() {
116
163
  const clone = super._clone();
117
164
  clone._roles = this._roles.slice();
@@ -185,6 +232,21 @@ class GuildMember extends Base {
185
232
  return this.client.rest.cdn.GuildMemberAvatar(this.guild.id, this.id, this.avatar, format, size, dynamic);
186
233
  }
187
234
 
235
+ /**
236
+ * A link to the user's banner.
237
+ * <info>This method will throw an error if called before the user is force fetched Profile.
238
+ * See {@link GuildMember#banner} for more info</info>
239
+ * @param {ImageURLOptions} [options={}] Options for the Image URL
240
+ * @returns {?string}
241
+ */
242
+ bannerURL({ format, size, dynamic } = {}) {
243
+ if (typeof this.banner === 'undefined') {
244
+ throw new Error('USER_BANNER_NOT_FETCHED');
245
+ }
246
+ if (!this.banner) return null;
247
+ return this.client.rest.cdn.GuildMemberBanner(this.guild.id, this.id, this.banner, format, size, dynamic);
248
+ }
249
+
188
250
  /**
189
251
  * A link to the member's guild avatar if they have one.
190
252
  * Otherwise, a link to their {@link User#displayAvatarURL} will be returned.
@@ -382,6 +444,79 @@ class GuildMember extends Base {
382
444
  return this.edit({ flags, reason });
383
445
  }
384
446
 
447
+ /**
448
+ * Sets the guild avatar of the logged in client.
449
+ * @param {?(BufferResolvable|Base64Resolvable)} avatar The new avatar
450
+ * @returns {Promise<GuildMember>}
451
+ */
452
+ setAvatar(avatar) {
453
+ if (this.user.id !== this.client.user.id) {
454
+ throw new Error('ONLY_ME');
455
+ }
456
+ if (this.client.user.nitroType !== 'NITRO_BOOST') {
457
+ throw new Error('NITRO_BOOST_REQUIRED', 'avatar');
458
+ }
459
+ return this.edit({ avatar });
460
+ }
461
+
462
+ /**
463
+ * Sets the guild banner of the logged in client.
464
+ * @param {?(BufferResolvable|Base64Resolvable)} banner The new banner
465
+ * @returns {Promise<GuildMember>}
466
+ */
467
+ setBanner(banner) {
468
+ if (this.user.id !== this.client.user.id) {
469
+ throw new Error('ONLY_ME');
470
+ }
471
+ if (this.client.user.nitroType !== 'NITRO_BOOST') {
472
+ throw new Error('NITRO_BOOST_REQUIRED', 'banner');
473
+ }
474
+ return this.edit({ banner });
475
+ }
476
+
477
+ /**
478
+ * Set Guild About me
479
+ * @param {string | null} bio Bio to set
480
+ * @returns {Promise<GuildMember>}
481
+ */
482
+ setAboutMe(bio = null) {
483
+ if (this.user.id !== this.client.user.id) {
484
+ throw new Error('ONLY_ME');
485
+ }
486
+ if (this.client.user.nitroType !== 'NITRO_BOOST') {
487
+ throw new Error('NITRO_BOOST_REQUIRED', 'bio');
488
+ }
489
+ return this.edit({ bio });
490
+ }
491
+
492
+ /**
493
+ * Change Theme color
494
+ * @param {ColorResolvable} primary The primary color of the user's profile
495
+ * @param {ColorResolvable} accent The accent color of the user's profile
496
+ * @returns {Promise<GuildMember>}
497
+ */
498
+ async setThemeColors(primary, accent) {
499
+ if (this.user.id !== this.client.user.id) {
500
+ throw new Error('ONLY_ME');
501
+ }
502
+ if (!primary || !accent) throw new Error('PRIMARY_COLOR or ACCENT_COLOR are required.');
503
+ // Check nitro
504
+ if (this.nitroType !== 'NITRO_BOOST') {
505
+ throw new Error('NITRO_BOOST_REQUIRED', 'themeColors');
506
+ }
507
+ primary = Util.resolveColor(primary) || this.themeColors ? this.themeColors[0] : 0;
508
+ accent = Util.resolveColor(accent) || this.themeColors ? this.themeColors[1] : 0;
509
+ const data_ = await this.client.api.guilds[this.guild.id].profile['@me'].patch({
510
+ data: {
511
+ theme_colors: [primary, accent],
512
+ },
513
+ });
514
+ this._ProfilePatch({
515
+ guild_member_profile: data_,
516
+ });
517
+ return this;
518
+ }
519
+
385
520
  /**
386
521
  * Creates a DM channel between the client and this member.
387
522
  * @param {boolean} [force=false] Whether to skip the cache check and request the API
@@ -484,6 +619,8 @@ class GuildMember extends Base {
484
619
  this.joinedTimestamp === member.joinedTimestamp &&
485
620
  this.nickname === member.nickname &&
486
621
  this.avatar === member.avatar &&
622
+ this.accentColor === member.accentColor &&
623
+ this.bio === member.bio &&
487
624
  this.pending === member.pending &&
488
625
  this.communicationDisabledUntilTimestamp === member.communicationDisabledUntilTimestamp &&
489
626
  this.flags.equals(member.flags) &&
@@ -492,6 +629,14 @@ class GuildMember extends Base {
492
629
  );
493
630
  }
494
631
 
632
+ /**
633
+ * Get profile guildMember
634
+ * @returns {Promise<User>}
635
+ */
636
+ getProfile() {
637
+ return this.user.getProfile(this.guild.id);
638
+ }
639
+
495
640
  /**
496
641
  * When concatenated with a string, this automatically returns the user's mention instead of the GuildMember object.
497
642
  * @returns {string}
@@ -514,33 +659,6 @@ class GuildMember extends Base {
514
659
  json.displayAvatarURL = this.displayAvatarURL();
515
660
  return json;
516
661
  }
517
-
518
- /**
519
- * Sets the guild avatar of the logged in client.
520
- * @param {?(BufferResolvable|Base64Resolvable)} avatar The new avatar
521
- * @returns {Promise<GuildMember>}
522
- */
523
- setAvatar(avatar) {
524
- return this.edit({ avatar });
525
- }
526
-
527
- /**
528
- * Sets the guild banner of the logged in client.
529
- * @param {?(BufferResolvable|Base64Resolvable)} banner The new banner
530
- * @returns {Promise<GuildMember>}
531
- */
532
- setBanner(banner) {
533
- return this.edit({ banner });
534
- }
535
-
536
- /**
537
- * Set Guild About me
538
- * @param {string | null} bio Bio to set
539
- * @returns {Promise<GuildMember>}
540
- */
541
- setAboutMe(bio = null) {
542
- return this.edit({ bio });
543
- }
544
662
  }
545
663
 
546
664
  /**
@@ -269,10 +269,71 @@ class Interaction extends Base {
269
269
  * Indicates whether this interaction is a {@link SelectMenuInteraction}.
270
270
  * @returns {boolean}
271
271
  */
272
+ isAnySelectMenu() {
273
+ return InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT && typeof this.values !== 'undefined';
274
+ }
275
+
276
+ /**
277
+ * Indicates whether this interaction is a {@link SelectMenuInteraction} with a `STRING_SELECT` type.
278
+ * @returns {boolean}
279
+ * @deprecated Use {@link Interaction#isStringSelect()} instead
280
+ */
272
281
  isSelectMenu() {
282
+ return this.isStringSelect();
283
+ }
284
+
285
+ /**
286
+ * Indicates whether this interaction is a {@link SelectMenuInteraction} with a `STRING_SELECT` type.
287
+ * @returns {boolean}
288
+ */
289
+ isStringSelect() {
290
+ return (
291
+ InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT &&
292
+ MessageComponentTypes[this.componentType] === MessageComponentTypes.STRING_SELECT
293
+ );
294
+ }
295
+
296
+ /**
297
+ * Indicates whether this interaction is a {@link SelectMenuInteraction} with a `USER_SELECT` type.
298
+ * @returns {boolean}
299
+ */
300
+ isUserSelect() {
301
+ return (
302
+ InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT &&
303
+ MessageComponentTypes[this.componentType] === MessageComponentTypes.USER_SELECT
304
+ );
305
+ }
306
+
307
+ /**
308
+ * Indicates whether this interaction is a {@link SelectMenuInteraction} with a `ROLE_SELECT` type.
309
+ * @returns {boolean}
310
+ */
311
+ isRoleSelect() {
312
+ return (
313
+ InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT &&
314
+ MessageComponentTypes[this.componentType] === MessageComponentTypes.ROLE_SELECT
315
+ );
316
+ }
317
+
318
+ /**
319
+ * Indicates whether this interaction is a {@link SelectMenuInteraction} with a `MENTIONABLE_SELECT` type.
320
+ * @returns {boolean}
321
+ */
322
+ isMentionableSelect() {
323
+ return (
324
+ InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT &&
325
+ MessageComponentTypes[this.componentType] === MessageComponentTypes.MENTIONABLE_SELECT
326
+ );
327
+ }
328
+
329
+ /**
330
+ * Indicates whether this interaction is a {@link SelectMenuInteraction} with a `CHANNEL_SELECT` type.
331
+ * @returns {boolean}
332
+ */
333
+ isChannelSelect() {
273
334
  return (
274
335
  InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT &&
275
- MessageComponentTypes[this.componentType] === MessageComponentTypes.SELECT_MENU
336
+ MessageComponentTypes[this.componentType] === MessageComponentTypes.CHANNEL_SELECT
276
337
  );
277
338
  }
278
339
 
@@ -0,0 +1,114 @@
1
+ 'use strict';
2
+
3
+ const { setTimeout } = require('node:timers');
4
+ const Base = require('./Base');
5
+ const { Events } = require('../util/Constants');
6
+ const SnowflakeUtil = require('../util/SnowflakeUtil');
7
+
8
+ /**
9
+ * Represents a interaction on Discord.
10
+ * @extends {Base}
11
+ */
12
+ class InteractionResponse extends Base {
13
+ constructor(client, data) {
14
+ super(client);
15
+ /**
16
+ * The id of the channel the interaction was sent in
17
+ * @type {Snowflake}
18
+ */
19
+ this.channelId = data.channelId;
20
+
21
+ /**
22
+ * The id of the guild the interaction was sent in, if any
23
+ * @type {?Snowflake}
24
+ */
25
+ this.guildId = data.guildId ?? this.channel?.guild?.id ?? null;
26
+
27
+ /**
28
+ * The interaction data was sent in
29
+ * @type {Object}
30
+ */
31
+ this.sendData = data.metadata;
32
+ this._patch(data);
33
+ }
34
+
35
+ _patch(data) {
36
+ if ('id' in data) {
37
+ /**
38
+ * The interaction response's ID
39
+ * @type {Snowflake}
40
+ */
41
+ this.id = data.id;
42
+ }
43
+ if ('nonce' in data) {
44
+ /**
45
+ * The interaction response's nonce
46
+ * @type {Snowflake}
47
+ */
48
+ this.nonce = data.nonce;
49
+ }
50
+ }
51
+ /**
52
+ * The timestamp the interaction response was created at
53
+ * @type {number}
54
+ * @readonly
55
+ */
56
+ get createdTimestamp() {
57
+ return SnowflakeUtil.timestampFrom(this.id);
58
+ }
59
+
60
+ /**
61
+ * The time the interaction response was created at
62
+ * @type {Date}
63
+ * @readonly
64
+ */
65
+ get createdAt() {
66
+ return new Date(this.createdTimestamp);
67
+ }
68
+
69
+ /**
70
+ * The channel that the interaction was sent in
71
+ * @type {TextBasedChannels}
72
+ * @readonly
73
+ */
74
+ get channel() {
75
+ return this.client.channels.resolve(this.channelId);
76
+ }
77
+
78
+ /**
79
+ * The guild the inteaaction was sent in (if in a guild channel)
80
+ * @type {?Guild}
81
+ * @readonly
82
+ */
83
+ get guild() {
84
+ return this.client.guilds.resolve(this.guildId) ?? this.channel?.guild ?? null;
85
+ }
86
+
87
+ /**
88
+ * Get Modal send from interaction
89
+ * @param {number} time Time to wait for modal
90
+ * @returns {Modal}
91
+ */
92
+ awaitModal(time) {
93
+ if (!time || typeof time !== 'number' || time < 0) throw new Error('INVALID_TIME');
94
+ return new Promise((resolve, reject) => {
95
+ const handler = modal => {
96
+ timeout.refresh();
97
+ if (modal.nonce != this.nonce || modal.id != this.id) return;
98
+ clearTimeout(timeout);
99
+ this.client.removeListener(Events.INTERACTION_MODAL_CREATE, handler);
100
+ this.client.decrementMaxListeners();
101
+ resolve(modal);
102
+ };
103
+ const timeout = setTimeout(() => {
104
+ this.client.removeListener(Events.INTERACTION_MODAL_CREATE, handler);
105
+ this.client.decrementMaxListeners();
106
+ reject(new Error('MODAL_TIMEOUT'));
107
+ }, time).unref();
108
+ this.client.incrementMaxListeners();
109
+ this.client.on(Events.INTERACTION_MODAL_CREATE, handler);
110
+ });
111
+ }
112
+ }
113
+
114
+ module.exports = InteractionResponse;
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
+ const Buffer = require('node:buffer').Buffer;
3
4
  const Base = require('./Base');
4
5
  const { GuildScheduledEvent } = require('./GuildScheduledEvent');
5
6
  const IntegrationApplication = require('./IntegrationApplication');
6
7
  const InviteStageInstance = require('./InviteStageInstance');
7
8
  const { Error } = require('../errors');
8
- const { Endpoints } = require('../util/Constants');
9
- const InviteFlags = require('../util/InviteFlags');
9
+ const { ChannelTypes, Endpoints } = require('../util/Constants');
10
10
  const Permissions = require('../util/Permissions');
11
11
 
12
12
  // TODO: Convert `inviter` and `channel` in this class to a getter.
@@ -156,8 +156,6 @@ class Invite extends Base {
156
156
  * The type of the invite target:
157
157
  * * 1: STREAM
158
158
  * * 2: EMBEDDED_APPLICATION
159
- * * 3: ROLE_SUBSCRIPTIONS
160
- * * 4: CREATOR_PAGE
161
159
  * @typedef {number} TargetType
162
160
  * @see {@link https://discord.com/developers/docs/resources/invite#invite-object-invite-target-types}
163
161
  */
@@ -172,37 +170,19 @@ class Invite extends Base {
172
170
  this.targetType ??= null;
173
171
  }
174
172
 
175
- /**
176
- * The type of the invite:
177
- * * 0: GUILD
178
- * * 1: GROUP_DM
179
- * * 2: FRIEND
180
- * @typedef {number} InviteType
181
- * @see {@link https://docs.discord.sex/resources/invite#invite-type}
182
- */
183
- if ('type' in data) {
184
- /**
185
- * The type of invite
186
- * @type {?InviteType}
187
- */
188
- this.type = data.type;
189
- } else {
190
- this.type ??= null;
191
- }
192
-
193
173
  if ('channel_id' in data) {
194
174
  /**
195
175
  * The channel's id this invite is for
196
- * @type {?Snowflake}
176
+ * @type {Snowflake}
197
177
  */
198
178
  this.channelId = data.channel_id;
199
179
  this.channel = this.client.channels.cache.get(data.channel_id);
200
180
  }
201
181
 
202
- if ('channel' in data && data.channel !== null) {
182
+ if ('channel' in data && data.channel) {
203
183
  /**
204
184
  * The channel this invite is for
205
- * @type {?Channel}
185
+ * @type {Channel}
206
186
  */
207
187
  this.channel ??= this.client.channels._add(data.channel, this.guild, { cache: false });
208
188
  this.channelId ??= data.channel.id;
@@ -243,16 +223,6 @@ class Invite extends Base {
243
223
  } else {
244
224
  this.guildScheduledEvent ??= null;
245
225
  }
246
-
247
- if ('flags' in data) {
248
- /**
249
- * The flags that are applied to the invite.
250
- * @type {?Readonly<InviteFlags>}
251
- */
252
- this.flags = new InviteFlags(data.flags).freeze();
253
- } else {
254
- this.flags ??= new InviteFlags().freeze();
255
- }
256
226
  }
257
227
 
258
228
  /**
@@ -347,6 +317,53 @@ class Invite extends Base {
347
317
  valueOf() {
348
318
  return this.code;
349
319
  }
320
+
321
+ /**
322
+ * Join this Guild using this invite.
323
+ * @param {boolean} [autoVerify] Whether to automatically verify member
324
+ * @returns {Promise<Guild>}
325
+ * @example
326
+ * await client.fetchInvite('code').then(async invite => {
327
+ * await invite.acceptInvite();
328
+ * });
329
+ */
330
+ async acceptInvite(autoVerify = false) {
331
+ if (!this.guild) throw new Error('INVITE_NO_GUILD');
332
+ if (this.client.guilds.cache.get(this.guild.id)) return this.guild;
333
+ const dataHeader = {
334
+ location: 'Join Guild',
335
+ location_guild_id: this.guild?.id,
336
+ location_channel_id: this.channelId,
337
+ location_channel_type: ChannelTypes[this.channel?.type] ?? 0,
338
+ };
339
+ await this.client.api.invites(this.code).post({
340
+ data: {
341
+ session_id: this.client.session_id,
342
+ },
343
+ headers: {
344
+ 'X-Context-Properties': Buffer.from(JSON.stringify(dataHeader), 'utf8').toString('base64'),
345
+ },
346
+ });
347
+ const guild = this.client.guilds.cache.get(this.guild.id);
348
+ /*
349
+ //
350
+ if (autoVerify) {
351
+ console.warn('Feature is under maintenance - Invite#acceptInvite(true)');
352
+ }
353
+ */
354
+ if (autoVerify) {
355
+ const getForm = await this.client.api
356
+ .guilds(this.guild.id)
357
+ ['member-verification'].get({ query: { with_guild: false, invite_code: this.code } })
358
+ .catch(() => {});
359
+ if (!getForm) return guild;
360
+ const form = Object.assign(getForm.form_fields[0], { response: true });
361
+ // Respond to the form
362
+ // https://discord.com/api/v9/guilds/:id/requests/@me
363
+ await this.client.api.guilds(this.guild.id).requests['@me'].put({ data: { form_fields: [form] } });
364
+ }
365
+ return guild;
366
+ }
350
367
  }
351
368
 
352
369
  /**