From 536c29f45cc5881e795167f159a63e5babf54212 Mon Sep 17 00:00:00 2001 From: March 7th <71698422+aiko-chan-ai@users.noreply.github.com> Date: Sat, 10 Sep 2022 18:36:16 +0700 Subject: [PATCH] feat: Appliaction - Refactor code - Add `sendContextMenu` :v --- src/structures/ApplicationCommand.js | 184 +++++++++++++++------------ typings/index.d.ts | 4 +- 2 files changed, 104 insertions(+), 84 deletions(-) diff --git a/src/structures/ApplicationCommand.js b/src/structures/ApplicationCommand.js index 412d616..cb2c8c4 100644 --- a/src/structures/ApplicationCommand.js +++ b/src/structures/ApplicationCommand.js @@ -16,7 +16,7 @@ const Message = lazy(() => require('../structures/Message').Message); * @extends {Base} */ class ApplicationCommand extends Base { - constructor(client, data, guild, guildId) { + constructor(client, data) { super(client); /** @@ -31,19 +31,6 @@ class ApplicationCommand extends Base { */ this.applicationId = data.application_id; - /** - * The guild this command is part of - * @type {?Guild} - */ - this.guild = guild ?? null; - - /** - * The guild's id this command is part of, this may be non-null when `guild` is `null` if the command - * was fetched from the `ApplicationCommandManager` - * @type {?Snowflake} - */ - this.guildId = guild?.id ?? guildId ?? null; - /** * The manager for permissions of this command on its guild or arbitrary guilds when the command is global * @type {ApplicationCommandPermissionsManager} @@ -61,7 +48,24 @@ class ApplicationCommand extends Base { this._patch(data); } + /** + * The guild this command is part of + * @type {?Guild} + */ + get guild() { + return this.client.guilds.resolve(this.guildId); + } + _patch(data) { + if ('guild_id' in data) { + /** + * The guild's id this command is part of, this may be non-null when `guild` is `null` if the command + * was fetched from the `ApplicationCommandManager` + * @type {?Snowflake} + */ + this.guildId = data.guild_id ?? null; + } + if ('name' in data) { /** * The name of this command @@ -784,67 +788,40 @@ class ApplicationCommand extends Base { attachmentsBuffer.push({ attachment: data.attachment, name: data.name, file: resource }); return id; } - const getDataPost = (guildAdd = false, dataAdd = [], nonce, autocomplete = false) => { + const getDataPost = (dataAdd = [], nonce, autocomplete = false) => { if (!Array.isArray(dataAdd) && typeof dataAdd == 'object') { dataAdd = [dataAdd]; } - if (guildAdd) { - return { - type: autocomplete ? 4 : 2, // Slash command, context menu - // Type: 4: Auto-complete - application_id: this.applicationId, - guild_id: message.guildId, - channel_id: message.channelId, - session_id: this.client.session_id, - data: { - // ApplicationCommandData - version: this.version, - id: this.id, - name: this.name, - type: ApplicationCommandTypes[this.type], - options: dataAdd, - attachments: attachments, - guild_id: message.guildId, - }, - nonce, - }; - } else { - return { - type: autocomplete ? 4 : 2, // Slash command, context menu - // Type: 4: Auto-complete - application_id: this.applicationId, - guild_id: message.guildId, - channel_id: message.channelId, - session_id: this.client.session_id, - data: { - // ApplicationCommandData - version: this.version, - id: this.id, - name: this.name, - type: ApplicationCommandTypes[this.type], - options: dataAdd, - attachments: attachments, - }, - nonce, - }; + const data = { + type: autocomplete ? 4 : 2, // Slash command, context menu + // Type: 4: Auto-complete + application_id: this.applicationId, + guild_id: message.guildId, + channel_id: message.channelId, + session_id: this.client.session_id, + data: { + // ApplicationCommandData + version: this.version, + id: this.id, + name: this.name, + type: ApplicationCommandTypes[this.type], + options: dataAdd, + attachments: attachments, + }, + nonce, + }; + if (this.guildId) { + data.data.guild_id = message.guildId; } + return data; }; const getAutoResponse = async (sendData, value) => { let nonce = SnowflakeUtil.generate(); - const data = getDataPost(false, sendData, nonce, true); - await this.client.api.interactions - .post({ - data, - files: attachmentsBuffer, - }) - .catch(async () => { - nonce = SnowflakeUtil.generate(); - const data_ = getDataPost(true, sendData, nonce); - await this.client.api.interactions.post({ - body: data_, - files: attachmentsBuffer, - }); - }); + const data = getDataPost(sendData, nonce, true); + await this.client.api.interactions.post({ + data, + files: attachmentsBuffer, + }); return new Promise(resolve => { const handler = data => { timeout.refresh(); @@ -866,20 +843,11 @@ class ApplicationCommand extends Base { }; const sendData = async (optionsData = []) => { let nonce = SnowflakeUtil.generate(); - const data = getDataPost(false, optionsData, nonce); - await this.client.api.interactions - .post({ - body: data, - files: attachmentsBuffer, - }) - .catch(async () => { - nonce = SnowflakeUtil.generate(); - const data_ = getDataPost(true, optionsData, nonce); - await this.client.api.interactions.post({ - body: data_, - files: attachmentsBuffer, - }); - }); + const data = getDataPost(optionsData, nonce); + await this.client.api.interactions.post({ + body: data, + files: attachmentsBuffer, + }); return new Promise((resolve, reject) => { const handler = data => { timeout.refresh(); @@ -927,6 +895,58 @@ class ApplicationCommand extends Base { } } } + /** + * Message Context Menu + * @param {Message} message Discord Message + * @returns {Promise} + */ + async sendContextMenu(message) { + if (!(message instanceof Message())) { + throw new TypeError('The message must be a Discord.Message'); + } + if (this.type == 'CHAT_INPUT') return false; + const nonce = SnowflakeUtil.generate(); + const data = { + type: 2, // Slash command, context menu + application_id: this.applicationId, + guild_id: message.guildId, + channel_id: message.channelId, + session_id: this.client.session_id, + data: { + // ApplicationCommandData + version: this.version, + id: this.id, + name: this.name, + type: ApplicationCommandTypes[this.type], + target_id: ApplicationCommandTypes[this.type] == 1 ? message.author.id : message.id, + }, + nonce, + }; + if (this.guildId) { + data.data.guild_id = message.guildId; + } + await this.client.api.interactions.post({ + body: data, + }); + return new Promise((resolve, reject) => { + const handler = data => { + timeout.refresh(); + if (data.metadata.nonce !== nonce) return; + clearTimeout(timeout); + this.client.removeListener('interactionResponse', handler); + this.client.decrementMaxListeners(); + if (data.status) resolve(data.metadata); + else reject(data.metadata); + }; + const timeout = setTimeout(() => { + this.client.removeListener('interactionResponse', handler); + this.client.decrementMaxListeners(); + reject(new Error('INTERACTION_TIMEOUT')); + }, 15_000).unref(); + this.client.incrementMaxListeners(); + this.client.on('interactionResponse', handler); + }); + } } module.exports = ApplicationCommand; diff --git a/typings/index.d.ts b/typings/index.d.ts index 4a761c9..908524d 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -445,7 +445,7 @@ export class DeveloperPortalManager extends BaseManager { } export class ApplicationCommand extends Base { - private constructor(client: Client, data: RawApplicationCommandData, guild?: Guild, guildId?: Snowflake); + private constructor(client: Client, data: RawApplicationCommandData); public applicationId: Snowflake; public readonly createdAt: Date; public readonly createdTimestamp: number; @@ -454,7 +454,7 @@ export class ApplicationCommand extends Base { public description: string; public descriptionLocalizations: LocalizationMap | null; public descriptionLocalized: string | null; - public guild: Guild | null; + public readonly guild: Guild | null; public guildId: Snowflake | null; public readonly manager: ApplicationCommandManager; public id: Snowflake;