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 { Buffer } = require('node:buffer');
4
4
  const BaseMessageComponent = require('./BaseMessageComponent');
5
5
  const MessageEmbed = require('./MessageEmbed');
6
- const WebEmbed = require('./WebEmbed');
6
+ const MessagePoll = require('./MessagePoll');
7
7
  const { RangeError } = require('../errors');
8
8
  const ActivityFlags = require('../util/ActivityFlags');
9
9
  const DataResolver = require('../util/DataResolver');
@@ -42,7 +42,6 @@ class MessagePayload {
42
42
  * @property {Buffer|string|Stream} attachment The original attachment that generated this file
43
43
  * @property {string} name The name of this file
44
44
  * @property {Buffer|Stream} file The file to be sent to the API
45
- * @extends {APIAttachment}
46
45
  */
47
46
 
48
47
  /**
@@ -52,15 +51,6 @@ class MessagePayload {
52
51
  this.files = null;
53
52
  }
54
53
 
55
- /**
56
- * Whether or not using new API to upload files
57
- * @type {boolean}
58
- * @readonly
59
- */
60
- get usingNewAttachmentAPI() {
61
- return Boolean(this.options?.usingNewAttachmentAPI);
62
- }
63
-
64
54
  /**
65
55
  * Whether or not the target is a {@link Webhook} or a {@link WebhookClient}
66
56
  * @type {boolean}
@@ -133,12 +123,12 @@ class MessagePayload {
133
123
  * Resolves data.
134
124
  * @returns {MessagePayload}
135
125
  */
136
- async resolveData() {
126
+ resolveData() {
137
127
  if (this.data) return this;
138
128
  const isInteraction = this.isInteraction;
139
129
  const isWebhook = this.isWebhook;
140
130
 
141
- let content = this.makeContent();
131
+ const content = this.makeContent();
142
132
  const tts = Boolean(this.options.tts);
143
133
 
144
134
  let nonce;
@@ -208,37 +198,6 @@ class MessagePayload {
208
198
  this.options.attachments = attachments;
209
199
  }
210
200
 
211
- if (this.options.embeds) {
212
- if (!Array.isArray(this.options.embeds)) {
213
- this.options.embeds = [this.options.embeds];
214
- }
215
-
216
- const webembeds = this.options.embeds.filter(e => e instanceof WebEmbed);
217
- this.options.embeds = this.options.embeds.filter(e => !(e instanceof WebEmbed));
218
-
219
- if (webembeds.length > 0) {
220
- if (!content) content = '';
221
- // Add hidden embed link
222
- content += `\n${WebEmbed.hiddenEmbed} \n`;
223
- if (webembeds.length > 1) {
224
- console.warn('[WARN] Multiple webembeds are not supported, this will be ignored.');
225
- }
226
- // Const embed = webembeds[0];
227
- for (const webE of webembeds) {
228
- const data = await webE.toMessage();
229
- content += `\n${data}`;
230
- }
231
- }
232
- // Check content
233
- if (typeof content == 'string' && content.length > 2000) {
234
- console.warn('[WARN] Content is longer than 2000 characters.');
235
- }
236
- if (typeof content == 'string' && content.length > 4000) {
237
- // Max length if user has nitro boost
238
- throw new RangeError('MESSAGE_EMBED_LINK_LENGTH');
239
- }
240
- }
241
-
242
201
  // Activity
243
202
  let activity;
244
203
  if (
@@ -247,7 +206,7 @@ class MessagePayload {
247
206
  this.options.activity.type
248
207
  ) {
249
208
  const type = ActivityFlags.resolve(this.options.activity.type);
250
- const sessionId = this.target.client.session_id;
209
+ const sessionId = this.target.client.sessionId;
251
210
  const partyId = this.options.activity.partyId;
252
211
  activity = {
253
212
  type,
@@ -272,6 +231,7 @@ class MessagePayload {
272
231
  attachments: this.options.attachments,
273
232
  sticker_ids: this.options.stickers?.map(sticker => sticker.id ?? sticker),
274
233
  thread_name: threadName,
234
+ poll: this.options.poll instanceof MessagePoll ? this.options.poll.toJSON() : this.options.poll,
275
235
  };
276
236
  return this;
277
237
  }
@@ -348,7 +308,7 @@ module.exports = MessagePayload;
348
308
 
349
309
  /**
350
310
  * A target for a message.
351
- * @typedef {TextBasedChannels|DMChannel|User|GuildMember|Webhook|WebhookClient|Interaction|InteractionWebhook|
311
+ * @typedef {TextBasedChannels|User|GuildMember|Webhook|WebhookClient|Interaction|InteractionWebhook|
352
312
  * Message|MessageManager} MessageTarget
353
313
  */
354
314
 
@@ -0,0 +1,238 @@
1
+ 'use strict';
2
+
3
+ const { Collection } = require('@discordjs/collection');
4
+ const { MessagePollLayoutTypes } = require('../util/Constants');
5
+ const Util = require('../util/Util');
6
+
7
+ /**
8
+ * Represents the poll object has a lot of levels and nested structures. It was also designed to support future extensibility, so some fields may appear to be more complex than necessary.
9
+ */
10
+ class MessagePoll {
11
+ /**
12
+ * @param {Object} data Message poll to clone or raw data
13
+ */
14
+ constructor(data = {}) {
15
+ this._patch(data);
16
+ }
17
+
18
+ _patch(data = {}) {
19
+ if (data?.constructor?.name == 'MessagePoll') data = data.toJSON();
20
+ /**
21
+ * The poll media object is a common object that backs both the question and answers. For now, `question` only supports `text`, while `answers` can have an optional `emoji`.
22
+ * @see {@link https://docs.discord.sex/resources/message#poll-media-structure}
23
+ * @typedef {Object} MessagePollMedia
24
+ * @property {?string} text The text of the field (max 300 characters for question, 55 characters for answer)
25
+ * @property {?RawEmoji} emoji The emoji of the field
26
+ */
27
+
28
+ if ('question' in data) {
29
+ /**
30
+ * The question of the poll
31
+ * @type {?MessagePollMedia}
32
+ */
33
+ this.question = this._resolvePollMedia(data.question);
34
+ } else {
35
+ this.question ??= null;
36
+ }
37
+
38
+ if (data.answers?.length) {
39
+ /**
40
+ * The answers available in the poll
41
+ * @type {Collection<number, MessagePollMedia>}
42
+ */
43
+ this.answers = new Collection();
44
+
45
+ data.answers.forEach((obj, index) => {
46
+ this.answers.set(obj?.answer_id || index + 1, this._resolvePollMedia(obj.poll_media));
47
+ });
48
+ } else {
49
+ this.answers ??= new Collection();
50
+ }
51
+
52
+ if ('layout_type' in data) {
53
+ /**
54
+ * The layout type of the poll
55
+ * @type {?MessagePollLayoutTypes}
56
+ */
57
+ this.layoutType = MessagePollLayoutTypes[data.layout_type];
58
+ } else {
59
+ this.layoutType ??= MessagePollLayoutTypes[1]; // Default type
60
+ }
61
+
62
+ if ('allow_multiselect' in data) {
63
+ /**
64
+ * Whether a user can select multiple answers
65
+ * @type {boolean}
66
+ */
67
+ this.allowMultiSelect = !!data.allow_multiselect;
68
+ } else {
69
+ this.allowMultiSelect ??= false;
70
+ }
71
+
72
+ if ('expiry' in data) {
73
+ /**
74
+ * When the poll ends
75
+ * @type {?Date}
76
+ */
77
+ this.expiry = new Date(data.expiry);
78
+ } else {
79
+ this.expiry ??= null;
80
+ }
81
+
82
+ if ('duration' in data) {
83
+ /**
84
+ * Number of hours the poll should be open for (max 32 days, default 1)
85
+ * @type {?Number}
86
+ */
87
+ this.duration = data.duration;
88
+ } else {
89
+ this.duration ??= null;
90
+ }
91
+
92
+ if ('results' in data) {
93
+ /**
94
+ * Poll Results Structure
95
+ * @see {@link https://docs.discord.sex/resources/message#poll-results-structure}
96
+ * @typedef {Object} MessagePollResult
97
+ * @property {boolean} isFinalized Whether the votes have been precisely counted
98
+ * @property {Collection<number, MessagePollResultAnswerCount>} answerCounts The counts for each answer
99
+ */
100
+ /**
101
+ * Poll Answer Count Structure
102
+ * @see {@link https://docs.discord.sex/resources/message#poll-answer-count-structure}
103
+ * @typedef {Object} MessagePollResultAnswerCount
104
+ * @property {MessagePollMedia} answer answer
105
+ * @property {number} count The number of votes for this answer
106
+ * @property {boolean} selfVoted Whether the current user voted for this answer
107
+ */
108
+ /**
109
+ * In a nutshell, this contains the number of votes for each answer.
110
+ * The `results` field may be not present in certain responses where, as an implementation detail,
111
+ * Discord does not fetch the poll results in the backend.
112
+ * This should be treated as "unknown results", as opposed to "no results".
113
+ * You can keep using the results if you have previously received them through other means.
114
+ * Due to the intricacies of counting at scale, while a poll is in progress the results may not
115
+ * be perfectly accurate. They usually are accurate, and shouldn't deviate significantly — it's
116
+ * just difficult to make guarantees. To compensate for this, after a poll is finished there is
117
+ * a background job which performs a final, accurate tally of votes. This tally concludes once
118
+ * `is_finalized` is `true`. Polls that have ended will also always contain results.
119
+ * If `answer_counts` does not contain an entry for a particular answer, then there are no votes
120
+ * for that answer.
121
+ * @type {?MessagePollResult}
122
+ */
123
+ this.results = {
124
+ isFinalized: data.results.is_finalized,
125
+ answerCounts: new Collection(),
126
+ };
127
+ data.results.answer_counts.forEach(obj => {
128
+ this.results.answerCounts.set(obj.id, {
129
+ count: obj.count,
130
+ selfVoted: obj.me_voted,
131
+ answer: this.answers.get(obj.id),
132
+ });
133
+ });
134
+ } else {
135
+ this.results ??= null;
136
+ }
137
+ }
138
+
139
+ _resolvePollMedia(obj) {
140
+ return {
141
+ text: obj.text,
142
+ emoji: Util.resolvePartialEmoji(obj.emoji),
143
+ };
144
+ }
145
+
146
+ /**
147
+ * Convert to JSON
148
+ * @returns {Object}
149
+ */
150
+ toJSON() {
151
+ const data = {
152
+ question: {
153
+ text: this.question.text,
154
+ emoji: this.question.emoji,
155
+ },
156
+ expiry: this.expiry?.toISOString(),
157
+ allow_multiselect: this.allowMultiSelect,
158
+ layout_type: typeof this.layoutType == 'number' ? this.layoutType : MessagePollLayoutTypes[this.layoutType],
159
+ answers: Array.from(this.answers.entries()).map(([id, data]) => ({
160
+ answer_id: id,
161
+ poll_media: {
162
+ text: data.text,
163
+ emoji: data.emoji,
164
+ },
165
+ })),
166
+ duration: this.duration ?? 1,
167
+ };
168
+ if (this.results) {
169
+ data.results = {
170
+ is_finalized: this.results.isFinalized,
171
+ answer_counts: Array.from(this.results.answerCounts.entries()).map(([id, data]) => ({
172
+ id: id,
173
+ count: data.count,
174
+ me_voted: data.selfVoted,
175
+ })),
176
+ };
177
+ }
178
+ return data;
179
+ }
180
+
181
+ /**
182
+ * Set question
183
+ * @param {string} text question
184
+ * @returns {MessagePoll}
185
+ */
186
+ setQuestion(text) {
187
+ this.question = {
188
+ text,
189
+ };
190
+ return this;
191
+ }
192
+
193
+ /**
194
+ * Set answers
195
+ * @param {MessagePollMedia[]} answers answers
196
+ * @returns {MessagePoll}
197
+ */
198
+ setAnswers(answers) {
199
+ this.answers.clear();
200
+ answers.forEach((obj, index) => {
201
+ this.answers.set(index + 1, this._resolvePollMedia(obj));
202
+ });
203
+ return this;
204
+ }
205
+
206
+ /**
207
+ * Add answer
208
+ * @param {MessagePollMedia} answer answer
209
+ * @returns {MessagePoll}
210
+ */
211
+ addAnswer(answer) {
212
+ this.answers.set(this.answers.size + 1, answer);
213
+ return this;
214
+ }
215
+
216
+ /**
217
+ * Set allow multi select
218
+ * @param {boolean} state state
219
+ * @returns {MessagePoll}
220
+ */
221
+ setAllowMultiSelect(state) {
222
+ this.allowMultiSelect = state;
223
+ return this;
224
+ }
225
+
226
+ /**
227
+ * Set duration
228
+ * @param {number} duration duration (hours)
229
+ * @returns {MessagePoll}
230
+ */
231
+ setDuration(duration) {
232
+ // [1, 4, 8, 24, 72, 168, 336];
233
+ this.duration = duration;
234
+ return this;
235
+ }
236
+ }
237
+
238
+ module.exports = MessagePoll;
@@ -31,7 +31,7 @@ class MessageReaction {
31
31
  this.me = data.me || data.me_burst;
32
32
 
33
33
  /**
34
- * Super reaction
34
+ * Is super reaction
35
35
  * @type {boolean}
36
36
  */
37
37
  this.isBurst = Boolean(data.me_burst || data.burst);
@@ -1,16 +1,7 @@
1
1
  'use strict';
2
2
 
3
- const { setTimeout } = require('node:timers');
4
3
  const BaseMessageComponent = require('./BaseMessageComponent');
5
- const {
6
- ChannelTypes,
7
- MessageComponentTypes,
8
- SelectMenuComponentTypes,
9
- InteractionTypes,
10
- } = require('../util/Constants');
11
- const SnowflakeUtil = require('../util/SnowflakeUtil');
12
- const { lazy } = require('../util/Util');
13
- const Message = lazy(() => require('./Message').Message);
4
+ const { ChannelTypes, MessageComponentTypes } = require('../util/Constants');
14
5
  const Util = require('../util/Util');
15
6
 
16
7
  /**
@@ -103,130 +94,6 @@ class MessageSelectMenu extends BaseMessageComponent {
103
94
  ) ?? [];
104
95
  }
105
96
 
106
- /**
107
- * Adds the channel types to the select menu
108
- * @param {...ChannelType[]} channelTypes Added channel types
109
- * @returns {MessageSelectMenu}
110
- */
111
- addChannelTypes(...channelTypes) {
112
- if (!channelTypes.every(channelType => ChannelTypes[channelType])) {
113
- throw new TypeError('INVALID_TYPE', 'channelTypes', 'Rest<ChannelTypes[]>');
114
- }
115
- this.channelTypes.push(
116
- ...channelTypes.map(channelType => (typeof channelType === 'string' ? channelType : ChannelTypes[channelType])),
117
- );
118
- return this;
119
- }
120
-
121
- /**
122
- * Sets the channel types of the select menu
123
- * @param {...ChannelType[]} channelTypes An array of new channel types
124
- * @returns {MessageSelectMenu}
125
- */
126
- setChannelTypes(...channelTypes) {
127
- if (!channelTypes.every(channelType => ChannelTypes[channelType])) {
128
- throw new TypeError('INVALID_TYPE', 'channelTypes', 'Rest<ChannelTypes[]>');
129
- }
130
- this.channelTypes = channelTypes.map(channelType =>
131
- typeof channelType === 'string' ? channelType : ChannelTypes[channelType],
132
- );
133
- return this;
134
- }
135
-
136
- /**
137
- * Sets the custom id of this select menu
138
- * @param {string} customId A unique string to be sent in the interaction when clicked
139
- * @returns {MessageSelectMenu}
140
- */
141
- setCustomId(customId) {
142
- this.customId = Util.verifyString(customId, RangeError, 'SELECT_MENU_CUSTOM_ID');
143
- return this;
144
- }
145
-
146
- /**
147
- * Sets the interactive status of the select menu
148
- * @param {boolean} [disabled=true] Whether this select menu should be disabled
149
- * @returns {MessageSelectMenu}
150
- */
151
- setDisabled(disabled = true) {
152
- this.disabled = disabled;
153
- return this;
154
- }
155
-
156
- /**
157
- * Sets the maximum number of selections allowed for this select menu
158
- * @param {number} maxValues Number of selections to be allowed
159
- * @returns {MessageSelectMenu}
160
- */
161
- setMaxValues(maxValues) {
162
- this.maxValues = maxValues;
163
- return this;
164
- }
165
-
166
- /**
167
- * Sets the minimum number of selections required for this select menu
168
- * <info>This will default the maxValues to the number of options, unless manually set</info>
169
- * @param {number} minValues Number of selections to be required
170
- * @returns {MessageSelectMenu}
171
- */
172
- setMinValues(minValues) {
173
- this.minValues = minValues;
174
- return this;
175
- }
176
-
177
- /**
178
- * Sets the placeholder of this select menu
179
- * @param {string} placeholder Custom placeholder text to display when nothing is selected
180
- * @returns {MessageSelectMenu}
181
- */
182
- setPlaceholder(placeholder) {
183
- this.placeholder = Util.verifyString(placeholder, RangeError, 'SELECT_MENU_PLACEHOLDER');
184
- return this;
185
- }
186
-
187
- /**
188
- * Sets the type of the select menu
189
- * @param {SelectMenuComponentType} type Type of the select menu
190
- * @returns {MessageSelectMenu}
191
- */
192
- setType(type) {
193
- if (!SelectMenuComponentTypes[type]) throw new TypeError('INVALID_TYPE', 'type', 'SelectMenuComponentType');
194
- this.type = BaseMessageComponent.resolveType(type);
195
- return this;
196
- }
197
-
198
- /**
199
- * Adds options to the select menu.
200
- * @param {...MessageSelectOptionData|MessageSelectOptionData[]} options The options to add
201
- * @returns {MessageSelectMenu}
202
- */
203
- addOptions(...options) {
204
- this.options.push(...this.constructor.normalizeOptions(options));
205
- return this;
206
- }
207
-
208
- /**
209
- * Sets the options of the select menu.
210
- * @param {...MessageSelectOptionData|MessageSelectOptionData[]} options The options to set
211
- * @returns {MessageSelectMenu}
212
- */
213
- setOptions(...options) {
214
- this.spliceOptions(0, this.options.length, options);
215
- return this;
216
- }
217
-
218
- /**
219
- * Removes, replaces, and inserts options in the select menu.
220
- * @param {number} index The index to start at
221
- * @param {number} deleteCount The number of options to remove
222
- * @param {...MessageSelectOptionData|MessageSelectOptionData[]} [options] The replacing option objects
223
- * @returns {MessageSelectMenu}
224
- */
225
- spliceOptions(index, deleteCount, ...options) {
226
- this.options.splice(index, deleteCount, ...this.constructor.normalizeOptions(...options));
227
- return this;
228
- }
229
-
230
97
  /**
231
98
  * Transforms the select menu into a plain object
232
99
  * @returns {APIMessageSelectMenu} The raw data of this select menu
@@ -268,124 +135,6 @@ class MessageSelectMenu extends BaseMessageComponent {
268
135
  static normalizeOptions(...options) {
269
136
  return options.flat(Infinity).map(option => this.normalizeOption(option));
270
137
  }
271
-
272
- // Add
273
- /**
274
- * Mesage select menu
275
- * @param {Message} message The message this select menu is for
276
- * @param {Array<any>} values The values of the select menu
277
- * @returns {Promise<InteractionResponse>}
278
- */
279
- async select(message, values) {
280
- if (!(message instanceof Message())) throw new Error('[UNKNOWN_MESSAGE] Please pass a valid Message');
281
- if (!Array.isArray(values)) throw new TypeError('[INVALID_VALUES] Please pass an array of values');
282
- if (!this.customId || this.disabled) {
283
- throw new Error('[INVALID_MENU] Menu does not contain Id or has been disabled');
284
- } // Disabled or null customID
285
- if (values.length < this.minValues) {
286
- throw new RangeError(`[SELECT_MENU_MIN_VALUES] The minimum number of values is ${this.minValues}`);
287
- }
288
- if (values.length > this.maxValues) {
289
- throw new RangeError(`[SELECT_MENU_MAX_VALUES] The maximum number of values is ${this.maxValues}`);
290
- }
291
- const parseValues = value => {
292
- switch (this.type) {
293
- case 'SELECT_MENU':
294
- case 'STRING_SELECT': {
295
- if (typeof value !== 'string') throw new TypeError('[INVALID_VALUE] Please pass a string value');
296
- const value_ = this.options.find(obj => obj.value === value || obj.label === value);
297
- if (!value_) throw new Error('[INVALID_VALUE] Please pass a valid value');
298
- return value_.value;
299
- }
300
- case 'USER_SELECT': {
301
- const userId = this.client.users.resolveId(value);
302
- if (!userId) throw new Error('[INVALID_VALUE] Please pass a valid user');
303
- return userId;
304
- }
305
- case 'ROLE_SELECT': {
306
- const roleId = this.client.roles.resolveId(value);
307
- if (!roleId) throw new Error('[INVALID_VALUE] Please pass a valid role');
308
- return roleId;
309
- }
310
- case 'MENTIONABLE_SELECT': {
311
- const mentionableId = this.client.users.resolveId(value) || this.client.roles.resolveId(value);
312
- if (!mentionableId) throw new Error('[INVALID_VALUE] Please pass a valid mentionable');
313
- return mentionableId;
314
- }
315
- case 'CHANNEL_SELECT': {
316
- const channel = this.client.channels.resolve(value);
317
- if (!channel) throw new Error('[INVALID_VALUE] Please pass a valid channel');
318
- if (!this.channelTypes.includes(channel.type)) {
319
- throw new Error(
320
- `[INVALID_VALUE] Please pass a valid channel type (Got: ${channel.type}, allow: ${this.channelTypes.join(
321
- ', ',
322
- )})`,
323
- );
324
- }
325
- return channel.id;
326
- }
327
- default: {
328
- throw new Error(`[INVALID_TYPE] Please pass a valid select menu type (Got ${this.type})`);
329
- }
330
- }
331
- };
332
-
333
- const nonce = SnowflakeUtil.generate();
334
- const data = {
335
- type: InteractionTypes.MESSAGE_COMPONENT,
336
- guild_id: message.guild?.id ?? null,
337
- channel_id: message.channel.id,
338
- message_id: message.id,
339
- application_id: message.applicationId ?? message.author.id,
340
- session_id: message.client.session_id,
341
- message_flags: message.flags.bitfield,
342
- data: {
343
- component_type: MessageComponentTypes[this.type],
344
- custom_id: this.customId,
345
- type: MessageComponentTypes[this.type],
346
- values: values?.length ? values.map(parseValues) : [],
347
- },
348
- nonce,
349
- };
350
-
351
- await message.client.api.interactions.post({
352
- data,
353
- });
354
- message.client._interactionCache.set(nonce, {
355
- channelId: message.channelId,
356
- guildId: message.guildId,
357
- metadata: data,
358
- });
359
- return new Promise((resolve, reject) => {
360
- const handler = data => {
361
- timeout.refresh();
362
- if (data.metadata?.nonce !== nonce) return;
363
- clearTimeout(timeout);
364
- message.client.removeListener('interactionResponse', handler);
365
- message.client.decrementMaxListeners();
366
- if (data.status) {
367
- resolve(data.metadata);
368
- } else {
369
- reject(
370
- new Error('INTERACTION_ERROR', {
371
- cause: data,
372
- }),
373
- );
374
- }
375
- };
376
- const timeout = setTimeout(() => {
377
- message.client.removeListener('interactionResponse', handler);
378
- message.client.decrementMaxListeners();
379
- reject(
380
- new Error('INTERACTION_TIMEOUT', {
381
- cause: data,
382
- }),
383
- );
384
- }, message.client.options.interactionTimeout).unref();
385
- message.client.incrementMaxListeners();
386
- message.client.on('interactionResponse', handler);
387
- });
388
- }
389
138
  }
390
139
 
391
140
  module.exports = MessageSelectMenu;