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.
- package/README.md +31 -16
- package/package.json +15 -8
- package/src/client/BaseClient.js +3 -2
- package/src/client/Client.js +539 -187
- package/src/client/actions/Action.js +13 -18
- package/src/client/actions/ActionsManager.js +1 -7
- package/src/client/actions/AutoModerationActionExecution.js +0 -1
- package/src/client/actions/AutoModerationRuleCreate.js +0 -1
- package/src/client/actions/AutoModerationRuleDelete.js +0 -1
- package/src/client/actions/AutoModerationRuleUpdate.js +0 -1
- package/src/client/actions/InteractionCreate.js +115 -0
- package/src/client/actions/MessageCreate.js +4 -0
- package/src/client/actions/PresenceUpdate.js +16 -17
- package/src/client/websocket/WebSocketManager.js +31 -11
- package/src/client/websocket/WebSocketShard.js +38 -39
- package/src/client/websocket/handlers/APPLICATION_COMMAND_AUTOCOMPLETE_RESPONSE.js +23 -0
- package/src/client/websocket/handlers/CALL_CREATE.js +3 -3
- package/src/client/websocket/handlers/CALL_DELETE.js +2 -2
- package/src/client/websocket/handlers/CALL_UPDATE.js +2 -2
- package/src/client/websocket/handlers/CHANNEL_RECIPIENT_ADD.js +13 -16
- package/src/client/websocket/handlers/CHANNEL_RECIPIENT_REMOVE.js +11 -11
- package/src/client/websocket/handlers/GUILD_APPLICATION_COMMANDS_UPDATE.js +11 -0
- package/src/client/websocket/handlers/GUILD_CREATE.js +0 -7
- package/src/client/websocket/handlers/GUILD_MEMBER_LIST_UPDATE.js +55 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUNDS_UPDATE.js +0 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.js +0 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.js +0 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.js +0 -0
- package/src/client/websocket/handlers/INTERACTION_CREATE.js +16 -0
- package/src/client/websocket/handlers/INTERACTION_FAILURE.js +18 -0
- package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +0 -1
- package/src/client/websocket/handlers/INTERACTION_SUCCESS.js +30 -0
- package/src/client/websocket/handlers/MESSAGE_ACK.js +16 -0
- package/src/client/websocket/handlers/READY.js +137 -47
- package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +5 -7
- package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +4 -6
- package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +9 -32
- package/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.js +0 -0
- package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +8 -2
- package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +1 -1
- package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +5 -1
- package/src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.js +0 -0
- package/src/client/websocket/handlers/index.js +20 -15
- package/src/errors/Messages.js +69 -24
- package/src/index.js +43 -12
- package/src/managers/ApplicationCommandManager.js +12 -9
- package/src/managers/ApplicationCommandPermissionsManager.js +11 -3
- package/src/managers/ChannelManager.js +4 -2
- package/src/managers/ClientUserSettingManager.js +279 -161
- package/src/managers/DeveloperPortalManager.js +104 -0
- package/src/managers/GuildApplicationCommandManager.js +28 -0
- package/src/managers/GuildBanManager.js +1 -1
- package/src/managers/GuildChannelManager.js +0 -2
- package/src/managers/GuildFolderManager.js +24 -0
- package/src/managers/GuildForumThreadManager.js +28 -22
- package/src/managers/GuildMemberManager.js +216 -40
- package/src/managers/GuildSettingManager.js +15 -22
- package/src/managers/MessageManager.js +44 -42
- package/src/managers/PermissionOverwriteManager.js +1 -1
- package/src/managers/ReactionUserManager.js +5 -5
- package/src/managers/RelationshipManager.js +74 -81
- package/src/managers/SessionManager.js +57 -0
- package/src/managers/ThreadManager.js +45 -12
- package/src/managers/ThreadMemberManager.js +1 -1
- package/src/managers/UserManager.js +10 -6
- package/src/rest/APIRequest.js +20 -42
- package/src/rest/CaptchaSolver.js +132 -0
- package/src/rest/DiscordAPIError.js +16 -17
- package/src/rest/RESTManager.js +21 -1
- package/src/rest/RequestHandler.js +21 -35
- package/src/structures/ApplicationCommand.js +456 -19
- package/src/structures/ApplicationRoleConnectionMetadata.js +0 -3
- package/src/structures/AutoModerationRule.js +5 -5
- package/src/structures/AutocompleteInteraction.js +0 -1
- package/src/structures/BaseGuildTextChannel.js +12 -10
- package/src/structures/BaseGuildVoiceChannel.js +18 -16
- package/src/structures/{CallState.js → Call.js} +12 -17
- package/src/structures/CategoryChannel.js +0 -2
- package/src/structures/Channel.js +3 -2
- package/src/structures/ClientApplication.js +204 -0
- package/src/structures/ClientPresence.js +8 -12
- package/src/structures/ClientUser.js +336 -117
- package/src/structures/ContextMenuInteraction.js +1 -1
- package/src/structures/DMChannel.js +92 -29
- package/src/structures/DeveloperPortalApplication.js +520 -0
- package/src/structures/ForumChannel.js +10 -0
- package/src/structures/Guild.js +271 -135
- package/src/structures/GuildAuditLogs.js +5 -0
- package/src/structures/GuildChannel.js +2 -16
- package/src/structures/GuildFolder.js +75 -0
- package/src/structures/GuildMember.js +145 -27
- package/src/structures/Interaction.js +62 -1
- package/src/structures/InteractionResponse.js +114 -0
- package/src/structures/Invite.js +52 -35
- package/src/structures/Message.js +202 -222
- package/src/structures/MessageAttachment.js +0 -11
- package/src/structures/MessageButton.js +67 -1
- package/src/structures/MessageEmbed.js +1 -1
- package/src/structures/MessageMentions.js +2 -3
- package/src/structures/MessagePayload.js +46 -4
- package/src/structures/MessageReaction.js +1 -1
- package/src/structures/MessageSelectMenu.js +252 -1
- package/src/structures/Modal.js +180 -75
- package/src/structures/PartialGroupDMChannel.js +433 -0
- package/src/structures/Presence.js +2 -2
- package/src/structures/RichPresence.js +34 -14
- package/src/structures/Role.js +2 -18
- package/src/structures/SelectMenuInteraction.js +151 -2
- package/src/structures/Session.js +81 -0
- package/src/structures/Team.js +49 -0
- package/src/structures/TextInputComponent.js +70 -0
- package/src/structures/ThreadChannel.js +19 -0
- package/src/structures/User.js +345 -117
- package/src/structures/UserContextMenuInteraction.js +2 -2
- package/src/structures/VoiceState.js +39 -74
- package/src/structures/WebEmbed.js +52 -38
- package/src/structures/Webhook.js +11 -17
- package/src/structures/interfaces/Application.js +23 -146
- package/src/structures/interfaces/TextBasedChannel.js +256 -411
- package/src/util/ApplicationFlags.js +1 -1
- package/src/util/Constants.js +284 -106
- package/src/util/Formatters.js +2 -16
- package/src/util/LimitedCollection.js +1 -1
- package/src/util/Options.js +68 -48
- package/src/util/Permissions.js +0 -5
- package/src/util/PurchasedFlags.js +0 -2
- package/src/util/RemoteAuth.js +356 -221
- package/src/util/Sweepers.js +1 -1
- package/src/util/Util.js +36 -76
- package/src/util/Voice.js +1456 -0
- package/src/util/arRPC/index.js +229 -0
- package/src/util/arRPC/process/detectable.json +1 -0
- package/src/util/arRPC/process/index.js +102 -0
- package/src/util/arRPC/process/native/index.js +5 -0
- package/src/util/arRPC/process/native/linux.js +37 -0
- package/src/util/arRPC/process/native/win32.js +25 -0
- package/src/util/arRPC/transports/ipc.js +281 -0
- package/src/util/arRPC/transports/websocket.js +128 -0
- package/typings/enums.d.ts +73 -18
- package/typings/index.d.ts +1249 -897
- package/typings/rawDataTypes.d.ts +9 -68
- package/src/client/websocket/handlers/USER_REQUIRED_ACTION_UPDATE.js +0 -78
- package/src/client/websocket/handlers/VOICE_CHANNEL_STATUS_UPDATE.js +0 -12
- package/src/managers/UserNoteManager.js +0 -53
- package/src/structures/GroupDMChannel.js +0 -387
- package/src/util/AttachmentFlags.js +0 -38
- package/src/util/InviteFlags.js +0 -29
- package/src/util/RoleFlags.js +0 -37
|
@@ -1,26 +1,22 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const process = require('node:process');
|
|
4
|
-
const { setTimeout } = require('node:timers');
|
|
5
4
|
const { Collection } = require('@discordjs/collection');
|
|
6
5
|
const Base = require('./Base');
|
|
7
6
|
const BaseMessageComponent = require('./BaseMessageComponent');
|
|
7
|
+
const ClientApplication = require('./ClientApplication');
|
|
8
|
+
const InteractionCollector = require('./InteractionCollector');
|
|
8
9
|
const MessageAttachment = require('./MessageAttachment');
|
|
10
|
+
const MessageButton = require('./MessageButton');
|
|
9
11
|
const Embed = require('./MessageEmbed');
|
|
10
12
|
const Mentions = require('./MessageMentions');
|
|
11
13
|
const MessagePayload = require('./MessagePayload');
|
|
14
|
+
const MessageSelectMenu = require('./MessageSelectMenu');
|
|
12
15
|
const ReactionCollector = require('./ReactionCollector');
|
|
13
16
|
const { Sticker } = require('./Sticker');
|
|
14
|
-
const Application = require('./interfaces/Application');
|
|
15
17
|
const { Error } = require('../errors');
|
|
16
18
|
const ReactionManager = require('../managers/ReactionManager');
|
|
17
|
-
const {
|
|
18
|
-
InteractionTypes,
|
|
19
|
-
MessageTypes,
|
|
20
|
-
SystemMessageTypes,
|
|
21
|
-
MessageComponentTypes,
|
|
22
|
-
Events,
|
|
23
|
-
} = require('../util/Constants');
|
|
19
|
+
const { InteractionTypes, MessageTypes, SystemMessageTypes, MaxBulkDeletableMessageAge } = require('../util/Constants');
|
|
24
20
|
const MessageFlags = require('../util/MessageFlags');
|
|
25
21
|
const Permissions = require('../util/Permissions');
|
|
26
22
|
const SnowflakeUtil = require('../util/SnowflakeUtil');
|
|
@@ -260,9 +256,9 @@ class Message extends Base {
|
|
|
260
256
|
if ('application' in data) {
|
|
261
257
|
/**
|
|
262
258
|
* Supplemental application information for group activities
|
|
263
|
-
* @type {?
|
|
259
|
+
* @type {?ClientApplication}
|
|
264
260
|
*/
|
|
265
|
-
this.groupActivityApplication = new
|
|
261
|
+
this.groupActivityApplication = new ClientApplication(this.client, data.application);
|
|
266
262
|
} else {
|
|
267
263
|
this.groupActivityApplication ??= null;
|
|
268
264
|
}
|
|
@@ -537,6 +533,65 @@ class Message extends Base {
|
|
|
537
533
|
});
|
|
538
534
|
}
|
|
539
535
|
|
|
536
|
+
/**
|
|
537
|
+
* @typedef {CollectorOptions} MessageComponentCollectorOptions
|
|
538
|
+
* @property {MessageComponentType} [componentType] The type of component to listen for
|
|
539
|
+
* @property {number} [max] The maximum total amount of interactions to collect
|
|
540
|
+
* @property {number} [maxComponents] The maximum number of components to collect
|
|
541
|
+
* @property {number} [maxUsers] The maximum number of users to interact
|
|
542
|
+
*/
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Creates a message component interaction collector.
|
|
546
|
+
* @param {MessageComponentCollectorOptions} [options={}] Options to send to the collector
|
|
547
|
+
* @returns {InteractionCollector}
|
|
548
|
+
* @example
|
|
549
|
+
* // Create a message component interaction collector
|
|
550
|
+
* const filter = (interaction) => interaction.customId === 'button' && interaction.user.id === 'someId';
|
|
551
|
+
* const collector = message.createMessageComponentCollector({ filter, time: 15_000 });
|
|
552
|
+
* collector.on('collect', i => console.log(`Collected ${i.customId}`));
|
|
553
|
+
* collector.on('end', collected => console.log(`Collected ${collected.size} items`));
|
|
554
|
+
*/
|
|
555
|
+
createMessageComponentCollector(options = {}) {
|
|
556
|
+
return new InteractionCollector(this.client, {
|
|
557
|
+
...options,
|
|
558
|
+
interactionType: InteractionTypes.MESSAGE_COMPONENT,
|
|
559
|
+
message: this,
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* An object containing the same properties as CollectorOptions, but a few more:
|
|
565
|
+
* @typedef {Object} AwaitMessageComponentOptions
|
|
566
|
+
* @property {CollectorFilter} [filter] The filter applied to this collector
|
|
567
|
+
* @property {number} [time] Time to wait for an interaction before rejecting
|
|
568
|
+
* @property {MessageComponentType} [componentType] The type of component interaction to collect
|
|
569
|
+
*/
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Collects a single component interaction that passes the filter.
|
|
573
|
+
* The Promise will reject if the time expires.
|
|
574
|
+
* @param {AwaitMessageComponentOptions} [options={}] Options to pass to the internal collector
|
|
575
|
+
* @returns {Promise<MessageComponentInteraction>}
|
|
576
|
+
* @example
|
|
577
|
+
* // Collect a message component interaction
|
|
578
|
+
* const filter = (interaction) => interaction.customId === 'button' && interaction.user.id === 'someId';
|
|
579
|
+
* message.awaitMessageComponent({ filter, time: 15_000 })
|
|
580
|
+
* .then(interaction => console.log(`${interaction.customId} was clicked!`))
|
|
581
|
+
* .catch(console.error);
|
|
582
|
+
*/
|
|
583
|
+
awaitMessageComponent(options = {}) {
|
|
584
|
+
const _options = { ...options, max: 1 };
|
|
585
|
+
return new Promise((resolve, reject) => {
|
|
586
|
+
const collector = this.createMessageComponentCollector(_options);
|
|
587
|
+
collector.once('end', (interactions, reason) => {
|
|
588
|
+
const interaction = interactions.first();
|
|
589
|
+
if (interaction) resolve(interaction);
|
|
590
|
+
else reject(new Error('INTERACTION_COLLECTOR_ERROR', reason));
|
|
591
|
+
});
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
|
|
540
595
|
/**
|
|
541
596
|
* Whether the message is editable by the client user
|
|
542
597
|
* @type {boolean}
|
|
@@ -598,7 +653,14 @@ class Message extends Base {
|
|
|
598
653
|
* channel.bulkDelete(messages.filter(message => message.bulkDeletable));
|
|
599
654
|
*/
|
|
600
655
|
get bulkDeletable() {
|
|
601
|
-
return
|
|
656
|
+
return (
|
|
657
|
+
(this.inGuild() &&
|
|
658
|
+
this.client.user.bot &&
|
|
659
|
+
Date.now() - this.createdTimestamp < MaxBulkDeletableMessageAge &&
|
|
660
|
+
this.deletable &&
|
|
661
|
+
this.channel?.permissionsFor(this.client.user).has(Permissions.FLAGS.MANAGE_MESSAGES, false)) ??
|
|
662
|
+
false
|
|
663
|
+
);
|
|
602
664
|
}
|
|
603
665
|
|
|
604
666
|
/**
|
|
@@ -660,7 +722,7 @@ class Message extends Base {
|
|
|
660
722
|
* @property {MessageAttachment[]} [attachments] An array of attachments to keep,
|
|
661
723
|
* all attachments will be kept if omitted
|
|
662
724
|
* @property {FileOptions[]|BufferResolvable[]|MessageAttachment[]} [files] Files to add to the message
|
|
663
|
-
* @property {MessageActionRow
|
|
725
|
+
* @property {Array<(MessageActionRow|MessageActionRowOptions)>} [components]
|
|
664
726
|
* Action rows containing interactive components for the message (buttons, select menus)
|
|
665
727
|
*/
|
|
666
728
|
|
|
@@ -730,7 +792,7 @@ class Message extends Base {
|
|
|
730
792
|
/**
|
|
731
793
|
* Adds a reaction to the message.
|
|
732
794
|
* @param {EmojiIdentifierResolvable} emoji The emoji to react with
|
|
733
|
-
* @param {boolean} [burst=false] Super Reactions
|
|
795
|
+
* @param {boolean} [burst=false] Super Reactions (Discord Nitro only)
|
|
734
796
|
* @returns {Promise<MessageReaction>}
|
|
735
797
|
* @example
|
|
736
798
|
* // React to a message with a unicode emoji
|
|
@@ -749,9 +811,9 @@ class Message extends Base {
|
|
|
749
811
|
|
|
750
812
|
return this.client.actions.MessageReactionAdd.handle(
|
|
751
813
|
{
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
814
|
+
user: this.client.user,
|
|
815
|
+
channel: this.channel,
|
|
816
|
+
message: this,
|
|
755
817
|
emoji: Util.resolvePartialEmoji(emoji),
|
|
756
818
|
me_burst: burst,
|
|
757
819
|
},
|
|
@@ -962,238 +1024,157 @@ class Message extends Base {
|
|
|
962
1024
|
reactions: false,
|
|
963
1025
|
});
|
|
964
1026
|
}
|
|
1027
|
+
// Added
|
|
1028
|
+
/**
|
|
1029
|
+
* Marks the message as unread.
|
|
1030
|
+
* @returns {Promise<boolean>}
|
|
1031
|
+
*/
|
|
1032
|
+
async markUnread() {
|
|
1033
|
+
await this.client.api.channels[this.channelId].messages[this.id].ack.post({
|
|
1034
|
+
data: {
|
|
1035
|
+
manual: true,
|
|
1036
|
+
mention_count: 1,
|
|
1037
|
+
},
|
|
1038
|
+
});
|
|
1039
|
+
return true;
|
|
1040
|
+
}
|
|
965
1041
|
|
|
966
|
-
// TypeScript
|
|
967
1042
|
/**
|
|
968
|
-
*
|
|
969
|
-
* @
|
|
970
|
-
* @readonly
|
|
1043
|
+
* Marks the message as read.
|
|
1044
|
+
* @returns {Promise<boolean>}
|
|
971
1045
|
*/
|
|
972
|
-
|
|
1046
|
+
async markRead() {
|
|
1047
|
+
await this.client.api.channels[this.channelId].messages[this.id].ack.post({
|
|
1048
|
+
data: {
|
|
1049
|
+
token: null,
|
|
1050
|
+
},
|
|
1051
|
+
});
|
|
973
1052
|
return true;
|
|
974
1053
|
}
|
|
975
1054
|
|
|
976
1055
|
/**
|
|
977
|
-
* Click specific button with X and Y
|
|
978
1056
|
* @typedef {Object} MessageButtonLocation
|
|
979
|
-
* @property {number}
|
|
980
|
-
* @property {number}
|
|
1057
|
+
* @property {number} row Index of the row
|
|
1058
|
+
* @property {number} col Index of the column
|
|
981
1059
|
*/
|
|
982
1060
|
|
|
983
1061
|
/**
|
|
984
1062
|
* Click specific button or automatically click first button if no button is specified.
|
|
985
|
-
* @param {MessageButtonLocation|string
|
|
986
|
-
* @returns {Promise<
|
|
1063
|
+
* @param {MessageButton|MessageButtonLocation|string} button Button ID
|
|
1064
|
+
* @returns {Promise<InteractionResponse>}
|
|
987
1065
|
* @example
|
|
988
|
-
*
|
|
989
|
-
*
|
|
990
|
-
*
|
|
991
|
-
*
|
|
992
|
-
*
|
|
993
|
-
*
|
|
994
|
-
*
|
|
995
|
-
*
|
|
996
|
-
*
|
|
997
|
-
* [0
|
|
998
|
-
*
|
|
999
|
-
*
|
|
1000
|
-
*
|
|
1066
|
+
* client.on('messageCreate', async message => {
|
|
1067
|
+
* if (message.components.length) {
|
|
1068
|
+
* // Find first button and click it
|
|
1069
|
+
* await message.clickButton();
|
|
1070
|
+
* // Click with button ID
|
|
1071
|
+
* await message.clickButton('button-id');
|
|
1072
|
+
* // Click with button location
|
|
1073
|
+
* await message.clickButton({ row: 0, col: 0 });
|
|
1074
|
+
* // Click with class MessageButton
|
|
1075
|
+
* const button = message.components[0].components[0];
|
|
1076
|
+
* await message.clickButton(button);
|
|
1077
|
+
* // Click with class MessageButton (2)
|
|
1078
|
+
* button.click(message);
|
|
1079
|
+
* }
|
|
1001
1080
|
* });
|
|
1002
|
-
* // Click button with customId (Ex button 5)
|
|
1003
|
-
* message.clickButton('button5');
|
|
1004
|
-
* // Click button 1
|
|
1005
|
-
* message.clickButton();
|
|
1006
1081
|
*/
|
|
1007
1082
|
clickButton(button) {
|
|
1008
|
-
if (
|
|
1009
|
-
button = this.components
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
} else if (typeof button
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
button = this.components[button.Y]?.components[button.X];
|
|
1083
|
+
if (!button) {
|
|
1084
|
+
button = this.components.flatMap(row => row.components).find(b => b.type === 'BUTTON')?.customId;
|
|
1085
|
+
} else if (button instanceof MessageButton) {
|
|
1086
|
+
button = button.customId;
|
|
1087
|
+
} else if (typeof button === 'object') {
|
|
1088
|
+
if (!('row' in button) || !('col' in button)) throw new TypeError('INVALID_BUTTON_LOCATION');
|
|
1089
|
+
button = this.components[button.row]?.components[button.col]?.customId;
|
|
1016
1090
|
}
|
|
1017
|
-
button = button.toJSON();
|
|
1018
1091
|
if (!button) throw new TypeError('BUTTON_NOT_FOUND');
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
const data = {
|
|
1022
|
-
type: InteractionTypes.MESSAGE_COMPONENT,
|
|
1023
|
-
nonce,
|
|
1024
|
-
guild_id: this.guildId,
|
|
1025
|
-
channel_id: this.channelId,
|
|
1026
|
-
message_id: this.id,
|
|
1027
|
-
application_id: this.applicationId ?? this.author.id,
|
|
1028
|
-
session_id: this.client.sessionId,
|
|
1029
|
-
message_flags: this.flags.bitfield,
|
|
1030
|
-
data: {
|
|
1031
|
-
component_type: MessageComponentTypes.BUTTON,
|
|
1032
|
-
custom_id: button.custom_id,
|
|
1033
|
-
},
|
|
1034
|
-
};
|
|
1035
|
-
this.client.api.interactions.post({
|
|
1036
|
-
data,
|
|
1037
|
-
});
|
|
1038
|
-
return new Promise((resolve, reject) => {
|
|
1039
|
-
const timeoutMs = 5_000;
|
|
1040
|
-
// Waiting for MsgCreate / ModalCreate
|
|
1041
|
-
const handler = data => {
|
|
1042
|
-
// UnhandledPacket
|
|
1043
|
-
if (data.d?.nonce == nonce && data.t == 'INTERACTION_SUCCESS') {
|
|
1044
|
-
// Interaction#deferUpdate
|
|
1045
|
-
this.client.removeListener(Events.MESSAGE_CREATE, handler);
|
|
1046
|
-
this.client.removeListener(Events.UNHANDLED_PACKET, handler);
|
|
1047
|
-
this.client.removeListener(Events.INTERACTION_MODAL_CREATE, handler);
|
|
1048
|
-
resolve(this);
|
|
1049
|
-
}
|
|
1050
|
-
if (data.nonce !== nonce) return;
|
|
1051
|
-
clearTimeout(timeout);
|
|
1052
|
-
this.client.removeListener(Events.MESSAGE_CREATE, handler);
|
|
1053
|
-
this.client.removeListener(Events.UNHANDLED_PACKET, handler);
|
|
1054
|
-
this.client.removeListener(Events.INTERACTION_MODAL_CREATE, handler);
|
|
1055
|
-
this.client.decrementMaxListeners();
|
|
1056
|
-
resolve(data);
|
|
1057
|
-
};
|
|
1058
|
-
const timeout = setTimeout(() => {
|
|
1059
|
-
this.client.removeListener(Events.MESSAGE_CREATE, handler);
|
|
1060
|
-
this.client.removeListener(Events.UNHANDLED_PACKET, handler);
|
|
1061
|
-
this.client.removeListener(Events.INTERACTION_MODAL_CREATE, handler);
|
|
1062
|
-
this.client.decrementMaxListeners();
|
|
1063
|
-
reject(new Error('INTERACTION_FAILED'));
|
|
1064
|
-
}, timeoutMs).unref();
|
|
1065
|
-
this.client.incrementMaxListeners();
|
|
1066
|
-
this.client.on(Events.MESSAGE_CREATE, handler);
|
|
1067
|
-
this.client.on(Events.UNHANDLED_PACKET, handler);
|
|
1068
|
-
this.client.on(Events.INTERACTION_MODAL_CREATE, handler);
|
|
1069
|
-
});
|
|
1092
|
+
button = this.components.flatMap(row => row.components).find(b => b.customId === button && b.type === 'BUTTON');
|
|
1093
|
+
return button ? button.click(this) : Promise.reject(new TypeError('BUTTON_NOT_FOUND'));
|
|
1070
1094
|
}
|
|
1071
|
-
|
|
1072
1095
|
/**
|
|
1073
|
-
* Select specific menu
|
|
1074
|
-
* @param {number|
|
|
1075
|
-
* @param {Array<
|
|
1076
|
-
* @returns {Promise<
|
|
1096
|
+
* Select specific menu or First Menu
|
|
1097
|
+
* @param {MessageSelectMenu|string|number|Array<any>} menuID MenuId / MessageSelectMenu / Row of Menu / Array of Values (first menu)
|
|
1098
|
+
* @param {Array<any>} options Array of Values
|
|
1099
|
+
* @returns {Promise<InteractionResponse>}
|
|
1100
|
+
* @example
|
|
1101
|
+
* client.on('messageCreate', async message => {
|
|
1102
|
+
* if (message.components.length) {
|
|
1103
|
+
* // Row
|
|
1104
|
+
* await message.selectMenu(1, [message.channel]); // row 1, type: Channel, multi: false
|
|
1105
|
+
* // Id
|
|
1106
|
+
* await message.selectMenu('menu-id', ['uid1', client.user, message.member]); // MenuId, type: User, multi: true
|
|
1107
|
+
* // First Menu
|
|
1108
|
+
* await message.selectMenu(['role-id']); // First Menu, type: role, multi: false
|
|
1109
|
+
* // class MessageSelectMenu
|
|
1110
|
+
* const menu = message.components[0].components[0];
|
|
1111
|
+
* await message.selectMenu(menu, ['option1', 'option2']);
|
|
1112
|
+
* // MessageSelectMenu (2)
|
|
1113
|
+
* menu.select(message, ['option1', 'option2']);
|
|
1114
|
+
* }
|
|
1115
|
+
* });
|
|
1077
1116
|
*/
|
|
1078
|
-
selectMenu(
|
|
1079
|
-
|
|
1080
|
-
if (
|
|
1081
|
-
|
|
1117
|
+
selectMenu(menuID, options = []) {
|
|
1118
|
+
if (!this.components[0]) throw new TypeError('MESSAGE_NO_COMPONENTS');
|
|
1119
|
+
if (menuID instanceof MessageSelectMenu) {
|
|
1120
|
+
//
|
|
1121
|
+
} else if (/[0-4]/.test(menuID)) {
|
|
1122
|
+
menuID = this.components[menuID]?.components[0];
|
|
1082
1123
|
} else {
|
|
1083
|
-
|
|
1124
|
+
const menuAll = this.components
|
|
1084
1125
|
.flatMap(row => row.components)
|
|
1085
|
-
.
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1126
|
+
.filter(b =>
|
|
1127
|
+
[
|
|
1128
|
+
'STRING_SELECT',
|
|
1129
|
+
'USER_SELECT',
|
|
1130
|
+
'ROLE_SELECT',
|
|
1131
|
+
'MENTIONABLE_SELECT',
|
|
1132
|
+
'CHANNEL_SELECT',
|
|
1133
|
+
'SELECT_MENU',
|
|
1134
|
+
].includes(b.type),
|
|
1090
1135
|
);
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
throw new RangeError(`[SELECT_MENU_MAX_VALUES] The maximum number of values is ${selectMenu.maxValues}`);
|
|
1097
|
-
}
|
|
1098
|
-
values = values.map(value => {
|
|
1099
|
-
switch (selectMenu.type) {
|
|
1100
|
-
case 'STRING_SELECT': {
|
|
1101
|
-
return selectMenu.options.find(obj => obj.value === value || obj.label === value).value;
|
|
1102
|
-
}
|
|
1103
|
-
case 'USER_SELECT': {
|
|
1104
|
-
return this.client.users.resolveId(value);
|
|
1105
|
-
}
|
|
1106
|
-
case 'ROLE_SELECT': {
|
|
1107
|
-
return this.guild.roles.resolveId(value);
|
|
1108
|
-
}
|
|
1109
|
-
case 'MENTIONABLE_SELECT': {
|
|
1110
|
-
return this.client.users.resolveId(value) || this.guild.roles.resolveId(value);
|
|
1111
|
-
}
|
|
1112
|
-
case 'CHANNEL_SELECT': {
|
|
1113
|
-
return this.client.channels.resolveId(value);
|
|
1114
|
-
}
|
|
1115
|
-
default: {
|
|
1116
|
-
return value;
|
|
1117
|
-
}
|
|
1136
|
+
if (menuAll.length == 0) throw new TypeError('MENU_NOT_FOUND');
|
|
1137
|
+
if (menuID) {
|
|
1138
|
+
menuID = menuAll.find(b => b.customId === menuID);
|
|
1139
|
+
} else {
|
|
1140
|
+
menuID = menuAll[0];
|
|
1118
1141
|
}
|
|
1119
|
-
}
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
type: InteractionTypes.MESSAGE_COMPONENT,
|
|
1123
|
-
guild_id: this.guildId,
|
|
1124
|
-
channel_id: this.channelId,
|
|
1125
|
-
message_id: this.id,
|
|
1126
|
-
application_id: this.applicationId ?? this.author.id,
|
|
1127
|
-
session_id: this.client.sessionId,
|
|
1128
|
-
message_flags: this.flags.bitfield,
|
|
1129
|
-
data: {
|
|
1130
|
-
component_type: MessageComponentTypes[selectMenu.type],
|
|
1131
|
-
custom_id: selectMenu.customId,
|
|
1132
|
-
type: MessageComponentTypes[selectMenu.type],
|
|
1133
|
-
values,
|
|
1134
|
-
},
|
|
1135
|
-
nonce,
|
|
1136
|
-
};
|
|
1137
|
-
this.client.api.interactions.post({
|
|
1138
|
-
data,
|
|
1139
|
-
});
|
|
1140
|
-
return new Promise((resolve, reject) => {
|
|
1141
|
-
const timeoutMs = 5_000;
|
|
1142
|
-
// Waiting for MsgCreate / ModalCreate
|
|
1143
|
-
const handler = data => {
|
|
1144
|
-
// UnhandledPacket
|
|
1145
|
-
if (data.d?.nonce == nonce && data.t == 'INTERACTION_SUCCESS') {
|
|
1146
|
-
// Interaction#deferUpdate
|
|
1147
|
-
this.client.removeListener(Events.MESSAGE_CREATE, handler);
|
|
1148
|
-
this.client.removeListener(Events.UNHANDLED_PACKET, handler);
|
|
1149
|
-
this.client.removeListener(Events.INTERACTION_MODAL_CREATE, handler);
|
|
1150
|
-
resolve(this);
|
|
1151
|
-
}
|
|
1152
|
-
if (data.nonce !== nonce) return;
|
|
1153
|
-
clearTimeout(timeout);
|
|
1154
|
-
this.client.removeListener(Events.MESSAGE_CREATE, handler);
|
|
1155
|
-
this.client.removeListener(Events.UNHANDLED_PACKET, handler);
|
|
1156
|
-
this.client.removeListener(Events.INTERACTION_MODAL_CREATE, handler);
|
|
1157
|
-
this.client.decrementMaxListeners();
|
|
1158
|
-
resolve(data);
|
|
1159
|
-
};
|
|
1160
|
-
const timeout = setTimeout(() => {
|
|
1161
|
-
this.client.removeListener(Events.MESSAGE_CREATE, handler);
|
|
1162
|
-
this.client.removeListener(Events.UNHANDLED_PACKET, handler);
|
|
1163
|
-
this.client.removeListener(Events.INTERACTION_MODAL_CREATE, handler);
|
|
1164
|
-
this.client.decrementMaxListeners();
|
|
1165
|
-
reject(new Error('INTERACTION_FAILED'));
|
|
1166
|
-
}, timeoutMs).unref();
|
|
1167
|
-
this.client.incrementMaxListeners();
|
|
1168
|
-
this.client.on(Events.MESSAGE_CREATE, handler);
|
|
1169
|
-
this.client.on(Events.UNHANDLED_PACKET, handler);
|
|
1170
|
-
this.client.on(Events.INTERACTION_MODAL_CREATE, handler);
|
|
1171
|
-
});
|
|
1142
|
+
}
|
|
1143
|
+
if (!menuID.type.includes('SELECT')) throw new TypeError('MENU_NOT_FOUND');
|
|
1144
|
+
return menuID.select(this, Array.isArray(menuID) ? menuID : options);
|
|
1172
1145
|
}
|
|
1173
|
-
|
|
1146
|
+
//
|
|
1174
1147
|
/**
|
|
1175
|
-
*
|
|
1176
|
-
* @
|
|
1148
|
+
* Send context Menu v2
|
|
1149
|
+
* @param {Snowflake} botId Bot id
|
|
1150
|
+
* @param {string} commandName Command name in Context Menu
|
|
1151
|
+
* @returns {Promise<InteractionResponse>}
|
|
1177
1152
|
*/
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1153
|
+
async contextMenu(botId, commandName) {
|
|
1154
|
+
if (!botId) throw new Error('Bot ID is required');
|
|
1155
|
+
const user = await this.client.users.fetch(botId).catch(() => {});
|
|
1156
|
+
if (!user || !user.bot || !user.application) {
|
|
1157
|
+
throw new Error('BotID is not a bot or does not have an application slash command');
|
|
1158
|
+
}
|
|
1159
|
+
if (!commandName || typeof commandName !== 'string') {
|
|
1160
|
+
throw new Error('Command name is required');
|
|
1161
|
+
}
|
|
1162
|
+
let contextCMD;
|
|
1163
|
+
const data = await this.channel.searchInteraction(botId, 'MESSAGE');
|
|
1164
|
+
for (const command of data.application_commands) {
|
|
1165
|
+
user.application?.commands?._add(command, true);
|
|
1166
|
+
}
|
|
1167
|
+
contextCMD = user.application?.commands?.cache.find(c => c.name == commandName && c.type === 'MESSAGE');
|
|
1168
|
+
if (!contextCMD) {
|
|
1169
|
+
throw new Error(
|
|
1170
|
+
'INTERACTION_SEND_FAILURE',
|
|
1171
|
+
`Command ${commandName} is not found (with search)\nList command avalible: ${user.application?.commands?.cache
|
|
1172
|
+
.filter(a => a.type == 'MESSAGE')
|
|
1173
|
+
.map(a => a.name)
|
|
1174
|
+
.join(', ')}`,
|
|
1175
|
+
);
|
|
1176
|
+
}
|
|
1177
|
+
return contextCMD.sendContextMenu(this, true);
|
|
1197
1178
|
}
|
|
1198
1179
|
|
|
1199
1180
|
/**
|
|
@@ -1202,7 +1183,6 @@ class Message extends Base {
|
|
|
1202
1183
|
* @param {Object} [elements={}] Metadata
|
|
1203
1184
|
* @returns {Promise<{ report_id: Snowflake }>}
|
|
1204
1185
|
* @example
|
|
1205
|
-
* // GET https://discord.com/api/v9/reporting/menu/message?variant=4
|
|
1206
1186
|
* // Report Category
|
|
1207
1187
|
* // - <hidden>MESSAGE_WELCOME (3)</hidden>
|
|
1208
1188
|
* // - Something else (28)
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const AttachmentFlags = require('../util/AttachmentFlags');
|
|
4
3
|
const Util = require('../util/Util');
|
|
5
4
|
|
|
6
5
|
/**
|
|
@@ -170,16 +169,6 @@ class MessageAttachment {
|
|
|
170
169
|
} else {
|
|
171
170
|
this.waveform ??= null;
|
|
172
171
|
}
|
|
173
|
-
|
|
174
|
-
if ('flags' in data) {
|
|
175
|
-
/**
|
|
176
|
-
* The flags of this attachment
|
|
177
|
-
* @type {Readonly<AttachmentFlags>}
|
|
178
|
-
*/
|
|
179
|
-
this.flags = new AttachmentFlags(data.flags).freeze();
|
|
180
|
-
} else {
|
|
181
|
-
this.flags ??= new AttachmentFlags().freeze();
|
|
182
|
-
}
|
|
183
172
|
}
|
|
184
173
|
|
|
185
174
|
/**
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const { setTimeout } = require('node:timers');
|
|
3
4
|
const BaseMessageComponent = require('./BaseMessageComponent');
|
|
4
5
|
const { RangeError } = require('../errors');
|
|
5
|
-
const { MessageButtonStyles, MessageComponentTypes } = require('../util/Constants');
|
|
6
|
+
const { MessageButtonStyles, MessageComponentTypes, InteractionTypes } = require('../util/Constants');
|
|
7
|
+
const SnowflakeUtil = require('../util/SnowflakeUtil');
|
|
6
8
|
const Util = require('../util/Util');
|
|
9
|
+
const { lazy } = require('../util/Util');
|
|
10
|
+
const Message = lazy(() => require('../structures/Message').Message);
|
|
7
11
|
|
|
8
12
|
/**
|
|
9
13
|
* Represents a button message component.
|
|
@@ -160,6 +164,68 @@ class MessageButton extends BaseMessageComponent {
|
|
|
160
164
|
static resolveStyle(style) {
|
|
161
165
|
return typeof style === 'string' ? style : MessageButtonStyles[style];
|
|
162
166
|
}
|
|
167
|
+
// Patch Click
|
|
168
|
+
/**
|
|
169
|
+
* Click the button
|
|
170
|
+
* @param {Message} message Discord Message
|
|
171
|
+
* @returns {Promise<InteractionResponse>}
|
|
172
|
+
*/
|
|
173
|
+
async click(message) {
|
|
174
|
+
const nonce = SnowflakeUtil.generate();
|
|
175
|
+
if (!(message instanceof Message())) throw new Error('[UNKNOWN_MESSAGE] Please pass a valid Message');
|
|
176
|
+
if (!this.customId || this.style == MessageButtonStyles.LINK || this.disabled) return false;
|
|
177
|
+
const data = {
|
|
178
|
+
type: InteractionTypes.MESSAGE_COMPONENT,
|
|
179
|
+
nonce,
|
|
180
|
+
guild_id: message.guild?.id ?? null,
|
|
181
|
+
channel_id: message.channel.id,
|
|
182
|
+
message_id: message.id,
|
|
183
|
+
application_id: message.applicationId ?? message.author.id,
|
|
184
|
+
session_id: message.client.session_id,
|
|
185
|
+
message_flags: message.flags.bitfield,
|
|
186
|
+
data: {
|
|
187
|
+
component_type: MessageComponentTypes.BUTTON,
|
|
188
|
+
custom_id: this.customId,
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
await message.client.api.interactions.post({
|
|
192
|
+
data,
|
|
193
|
+
});
|
|
194
|
+
message.client._interactionCache.set(nonce, {
|
|
195
|
+
channelId: message.channelId,
|
|
196
|
+
guildId: message.guildId,
|
|
197
|
+
metadata: data,
|
|
198
|
+
});
|
|
199
|
+
return new Promise((resolve, reject) => {
|
|
200
|
+
const handler = data => {
|
|
201
|
+
timeout.refresh();
|
|
202
|
+
if (data.metadata?.nonce !== nonce) return;
|
|
203
|
+
clearTimeout(timeout);
|
|
204
|
+
message.client.removeListener('interactionResponse', handler);
|
|
205
|
+
message.client.decrementMaxListeners();
|
|
206
|
+
if (data.status) {
|
|
207
|
+
resolve(data.metadata);
|
|
208
|
+
} else {
|
|
209
|
+
reject(
|
|
210
|
+
new Error('INTERACTION_ERROR', {
|
|
211
|
+
cause: data,
|
|
212
|
+
}),
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
const timeout = setTimeout(() => {
|
|
217
|
+
message.client.removeListener('interactionResponse', handler);
|
|
218
|
+
message.client.decrementMaxListeners();
|
|
219
|
+
reject(
|
|
220
|
+
new Error('INTERACTION_TIMEOUT', {
|
|
221
|
+
cause: data,
|
|
222
|
+
}),
|
|
223
|
+
);
|
|
224
|
+
}, message.client.options.interactionTimeout).unref();
|
|
225
|
+
message.client.incrementMaxListeners();
|
|
226
|
+
message.client.on('interactionResponse', handler);
|
|
227
|
+
});
|
|
228
|
+
}
|
|
163
229
|
}
|
|
164
230
|
|
|
165
231
|
module.exports = MessageButton;
|
|
@@ -8,7 +8,7 @@ let deprecationEmittedForSetAuthor = false;
|
|
|
8
8
|
let deprecationEmittedForSetFooter = false;
|
|
9
9
|
let deprecationEmittedForAddField = false;
|
|
10
10
|
|
|
11
|
-
// TODO: Remove the deprecated code for `setAuthor()` and `
|
|
11
|
+
// TODO: Remove the deprecated code for `setAuthor()`, `setFooter()` and `addField()`.
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Represents an embed in a message (image/video preview, rich embed, etc.)
|
|
@@ -211,13 +211,12 @@ class MessageMentions {
|
|
|
211
211
|
*/
|
|
212
212
|
has(data, { ignoreDirect = false, ignoreRoles = false, ignoreRepliedUser = false, ignoreEveryone = false } = {}) {
|
|
213
213
|
const user = this.client.users.resolve(data);
|
|
214
|
-
|
|
215
214
|
if (!ignoreEveryone && user && this.everyone) return true;
|
|
216
215
|
|
|
217
216
|
const userWasRepliedTo = user && this.repliedUser?.id === user.id;
|
|
218
217
|
|
|
219
218
|
if (!ignoreRepliedUser && userWasRepliedTo && this.users.has(user.id)) return true;
|
|
220
|
-
|
|
219
|
+
if (!ignoreRepliedUser && this.users.has(this.repliedUser?.id) && this.repliedUser?.id === user?.id) return true;
|
|
221
220
|
if (!ignoreDirect) {
|
|
222
221
|
if (user && (!ignoreRepliedUser || this.parsedUsers.has(user.id)) && this.users.has(user.id)) return true;
|
|
223
222
|
|
|
@@ -227,7 +226,7 @@ class MessageMentions {
|
|
|
227
226
|
const channel = this.client.channels.resolve(data);
|
|
228
227
|
if (channel && this.channels.has(channel.id)) return true;
|
|
229
228
|
}
|
|
230
|
-
|
|
229
|
+
if (user && !ignoreEveryone && this.everyone) return true;
|
|
231
230
|
if (!ignoreRoles) {
|
|
232
231
|
const member = this.guild?.members.resolve(data);
|
|
233
232
|
if (member) {
|