diff --git a/src/client/Client.js b/src/client/Client.js index 28177b67..8c20286b 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -108,18 +108,7 @@ class Client extends BaseClient { * The interaction client. * @type {InteractionClient} */ - this.interactionClient = new InteractionClient( - options, - interaction => { - /** - * Emitted when an interaction is created. - * @event Client#interactionCreate - * @param {Interaction} interaction The interaction which was created. - */ - this.emit(Events.INTERACTION_CREATE, interaction); - }, - this, - ); + this.interactionClient = new InteractionClient(options, this); /** * All of the {@link User} objects that have been cached at any point, mapped by their IDs diff --git a/src/client/InteractionClient.js b/src/client/InteractionClient.js index c7d05302..631c5895 100644 --- a/src/client/InteractionClient.js +++ b/src/client/InteractionClient.js @@ -3,27 +3,29 @@ const BaseClient = require('./BaseClient'); const ApplicationCommand = require('../structures/ApplicationCommand'); const Interaction = require('../structures/Interaction'); -const { ApplicationCommandOptionType, InteractionType, InteractionResponseType } = require('../util/Constants'); +const { Events, ApplicationCommandOptionType, InteractionType, InteractionResponseType } = require('../util/Constants'); let sodium; /** * Interaction client is used for interactions. * - * ```js + * @example * const client = new InteractionClient({ * token: ABC, * publicKey: XYZ, - * }, async (interaction) => { + * }); + * + * client.on('interactionCreate', () => { * // automatically handles long responses * if (will take a long time) { - * await doSomethingLong.then((d) => { + * doSomethingLong.then((d) => { * interaction.reply({ * content: 'wow that took long', * }); * }); * } else { - * await interaction.reply('hi!'); + * interaction.reply('hi!'); * } * }); * ``` @@ -31,16 +33,25 @@ let sodium; class InteractionClient extends BaseClient { /** * @param {Options} options Options for the client. - * @param {Handler} handler Handler to handle things. * @param {undefined} client For internal use. */ - constructor(options, handler, client) { + constructor(options, client) { super(options); - this.handler = handler; - this.token = options.token; - this.publicKey = options.publicKey ? Buffer.from(options.publicKey, 'hex') : undefined; - this.clientID = options.clientID; + Object.defineProperty(this, 'token', { + value: options.token, + writable: true, + }); + + Object.defineProperty(this, 'clientID', { + value: options.clientID, + writable: true, + }); + + Object.defineProperty(this, 'publicKey', { + value: options.publicKey ? Buffer.from(options.publicKey, 'hex') : undefined, + writable: true, + }); // Compat for direct usage this.client = client || this; @@ -49,7 +60,7 @@ class InteractionClient extends BaseClient { /** * Get registered slash commands. - * @param {Snowflake?} guildID Optional guild ID. + * @param {Snowflake} [guildID] Optional guild ID. * @returns {Command[]} */ async getCommands(guildID) { @@ -92,7 +103,7 @@ class InteractionClient extends BaseClient { return new ApplicationCommand(this, c, guildID); } - async handle(data) { + handle(data) { switch (data.type) { case InteractionType.PING: return { @@ -101,7 +112,7 @@ class InteractionClient extends BaseClient { case InteractionType.APPLICATION_COMMAND: { let timedOut = false; let resolve; - const p0 = new Promise(r => { + const directPromise = new Promise(r => { resolve = r; this.client.setTimeout(() => { timedOut = true; @@ -133,13 +144,14 @@ class InteractionClient extends BaseClient { const interaction = new Interaction(this.client, data, syncHandle); - Promise.resolve(this.handler(interaction)).catch(e => { - this.client.emit('error', e); - }); + /** + * Emitted when an interaction is created. + * @event Client#interactionCreate + * @param {Interaction} interaction The interaction which was created. + */ + this.client.emit(Events.INTERACTION_CREATE, interaction); - const result = await p0; - - return result; + return directPromise; } default: throw new RangeError('Invalid interaction data'); diff --git a/src/structures/ApplicationCommand.js b/src/structures/ApplicationCommand.js index c646ff7e..560b95a8 100644 --- a/src/structures/ApplicationCommand.js +++ b/src/structures/ApplicationCommand.js @@ -17,7 +17,7 @@ class ApplicationCommand extends Base { * @type {Snowflake?} * @readonly */ - this.guildID = guildID; + this.guildID = guildID || null; this._patch(data); } diff --git a/src/structures/Interaction.js b/src/structures/Interaction.js index b97bb07a..c7e47f06 100644 --- a/src/structures/Interaction.js +++ b/src/structures/Interaction.js @@ -19,48 +19,56 @@ class Interaction extends Base { /** * The ID of this interaction. * @type {Snowflake} + * @readonly */ this.id = data.id; /** * The token of this interaction. * @type {string} + * @readonly */ this.token = data.token; /** * The ID of the invoked command. * @type {Snowflake} + * @readonly */ this.commandID = data.data.id; /** * The name of the invoked command. * @type {string} + * @readonly */ this.commandName = data.data.name; /** * The options passed to the command. * @type {Object} + * @readonly */ this.options = data.data.options; /** * The channel this interaction was sent in. - * @type {Channel} + * @type {?Channel} + * @readonly */ - this.channel = this.client.channels?.cache.get(data.channel_id); + this.channel = this.client.channels?.cache.get(data.channel_id) || null; /** * The guild this interaction was sent in, if any. * @type {?Guild} + * @readonly */ this.guild = data.guild_id ? this.client.guilds?.cache.get(data.guild_id) : null; /** * If this interaction was sent in a guild, the member which sent it. * @type {?Member} + * @readonly */ this.member = data.member ? this.guild?.members.add(data.member, false) : null; }