forked from discordjs/discord.js
-
Notifications
You must be signed in to change notification settings - Fork 7
/
CommandInteraction.js
144 lines (122 loc) · 4.5 KB
/
CommandInteraction.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
'use strict';
const Interaction = require('./Interaction');
const InteractionResponses = require('./interfaces/InteractionResponses');
const WebhookClient = require('../client/WebhookClient');
const Collection = require('../util/Collection');
const { ApplicationCommandOptionTypes } = require('../util/Constants');
/**
* Represents a command interaction.
* @extends {Interaction}
* @implements {InteractionResponses}
*/
class CommandInteraction extends Interaction {
constructor(client, data) {
super(client, data);
/**
* The channel this interaction was sent in
* @type {?TextChannel|NewsChannel|DMChannel}
* @name CommandInteraction#channel
* @readonly
*/
/**
* The ID of the invoked application command
* @type {Snowflake}
*/
this.commandID = data.data.id;
/**
* The name of the invoked application command
* @type {string}
*/
this.commandName = data.data.name;
/**
* Whether the reply to this interaction has been deferred
* @type {boolean}
*/
this.deferred = false;
/**
* The options passed to the command.
* @type {Collection<string, CommandInteractionOption>}
*/
this.options = this._createOptionsCollection(data.data.options, data.data.resolved);
/**
* Whether this interaction has already been replied to
* @type {boolean}
*/
this.replied = false;
/**
* An associated webhook client, can be used to create deferred replies
* @type {WebhookClient}
*/
this.webhook = new WebhookClient(this.applicationID, this.token, this.client.options);
}
/**
* The invoked application command, if it was fetched before
* @type {?ApplicationCommand}
*/
get command() {
const id = this.commandID;
return this.guild?.commands.cache.get(id) ?? this.client.application.commands.cache.get(id) ?? null;
}
/**
* Represents an option of a received command interaction.
* @typedef {Object} CommandInteractionOption
* @property {string} name The name of the option
* @property {ApplicationCommandOptionType} type The type of the option
* @property {string|number|boolean} [value] The value of the option
* @property {Collection<string, CommandInteractionOption>} [options] Additional options if this option is a
* subcommand (group)
* @property {User} [user] The resolved user
* @property {GuildMember|Object} [member] The resolved member
* @property {GuildChannel|Object} [channel] The resolved channel
* @property {Role|Object} [role] The resolved role
*/
/**
* Transforms an option received from the API.
* @param {Object} option The received option
* @param {Object} resolved The resolved interaction data
* @returns {CommandInteractionOption}
* @private
*/
transformOption(option, resolved) {
const result = {
name: option.name,
type: ApplicationCommandOptionTypes[option.type],
};
if ('value' in option) result.value = option.value;
if ('options' in option) result.options = this._createOptionsCollection(option.options, resolved);
const user = resolved?.users?.[option.value];
if (user) result.user = this.client.users.add(user);
const member = resolved?.members?.[option.value];
if (member) result.member = this.guild?.members.add({ user, ...member }) ?? member;
const channel = resolved?.channels?.[option.value];
if (channel) result.channel = this.client.channels.add(channel, this.guild) ?? channel;
const role = resolved?.roles?.[option.value];
if (role) result.role = this.guild?.roles.add(role) ?? role;
return result;
}
/**
* Creates a collection of options from the received options array.
* @param {Object[]} options The received options
* @param {Object} resolved The resolved interaction data
* @returns {Collection<string, CommandInteractionOption>}
* @private
*/
_createOptionsCollection(options, resolved) {
const optionsCollection = new Collection();
if (typeof options === 'undefined') return optionsCollection;
for (const option of options) {
optionsCollection.set(option.name, this.transformOption(option, resolved));
}
return optionsCollection;
}
// These are here only for documentation purposes - they are implemented by InteractionResponses
/* eslint-disable no-empty-function */
defer() {}
reply() {}
fetchReply() {}
editReply() {}
deleteReply() {}
followUp() {}
}
InteractionResponses.applyToClass(CommandInteraction, ['deferUpdate', 'update']);
module.exports = CommandInteraction;