diff --git a/.gitignore b/.gitignore index 5623f0cfb08d..a7b124b84d65 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ docs/docs.json .tmp/ .idea/ .DS_Store +.yarn/ diff --git a/src/structures/BaseCommandInteraction.js b/src/structures/BaseCommandInteraction.js index 0ddaf6bfee48..a24a5f0c893b 100644 --- a/src/structures/BaseCommandInteraction.js +++ b/src/structures/BaseCommandInteraction.js @@ -3,6 +3,7 @@ const { Collection } = require('@discordjs/collection'); const Interaction = require('./Interaction'); const InteractionWebhook = require('./InteractionWebhook'); +const MessageAttachment = require('./MessageAttachment'); const InteractionResponses = require('./interfaces/InteractionResponses'); const { ApplicationCommandOptionTypes } = require('../util/Constants'); @@ -76,6 +77,7 @@ class BaseCommandInteraction extends Interaction { * @property {Collection} [roles] The resolved roles * @property {Collection} [channels] The resolved channels * @property {Collection} [messages] The resolved messages + * @property {Collection} [attachments] The resolved attachments */ /** @@ -84,7 +86,7 @@ class BaseCommandInteraction extends Interaction { * @returns {CommandInteractionResolvedData} * @private */ - transformResolved({ members, users, channels, roles, messages }) { + transformResolved({ members, users, channels, roles, messages, attachments }) { const result = {}; if (members) { @@ -123,6 +125,14 @@ class BaseCommandInteraction extends Interaction { } } + if (attachments) { + result.attachments = new Collection(); + for (const attachment of Object.values(attachments)) { + const patched = new MessageAttachment(attachment.url, attachment.filename, attachment); + result.attachments.set(attachment.id, patched); + } + } + return result; } @@ -139,6 +149,7 @@ class BaseCommandInteraction extends Interaction { * @property {GuildMember|APIGuildMember} [member] The resolved member * @property {GuildChannel|ThreadChannel|APIChannel} [channel] The resolved channel * @property {Role|APIRole} [role] The resolved role + * @property {MessageAttachment} [attachment] The resolved attachment */ /** @@ -169,6 +180,9 @@ class BaseCommandInteraction extends Interaction { const role = resolved.roles?.[option.value]; if (role) result.role = this.guild?.roles._add(role) ?? role; + + const attachment = resolved.attachments?.[option.value]; + if (attachment) result.attachment = new MessageAttachment(attachment.url, attachment.filename, attachment); } return result; diff --git a/src/structures/CommandInteractionOptionResolver.js b/src/structures/CommandInteractionOptionResolver.js index c83fd8e2f00e..10da7b9957ac 100644 --- a/src/structures/CommandInteractionOptionResolver.js +++ b/src/structures/CommandInteractionOptionResolver.js @@ -251,6 +251,17 @@ class CommandInteractionOptionResolver { if (!focusedOption) throw new TypeError('AUTOCOMPLETE_INTERACTION_OPTION_NO_FOCUSED_OPTION'); return getFull ? focusedOption : focusedOption.value; } + + /** + * Gets an attachment option. + * @param {string} name The name of the option. + * @param {boolean} [required=false] Whether to throw an error if the option is not found. + * @returns {?MessageAttachment} The value of the option, or null if not set and not required. + */ + getAttachment(name, required = false) { + const option = this._getTypedOption(name, 'ATTACHMENT', ['attachment'], required); + return option?.attachment ?? null; + } } module.exports = CommandInteractionOptionResolver; diff --git a/src/util/Constants.js b/src/util/Constants.js index 11c455ec1a31..14b0e526c906 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -1040,6 +1040,7 @@ exports.ApplicationCommandOptionTypes = createEnum([ 'ROLE', 'MENTIONABLE', 'NUMBER', + 'ATTACHMENT', ]); /** diff --git a/typings/enums.d.ts b/typings/enums.d.ts index f8efb4a170f5..d67d310eb5f2 100644 --- a/typings/enums.d.ts +++ b/typings/enums.d.ts @@ -27,6 +27,7 @@ export const enum ApplicationCommandOptionTypes { ROLE = 8, MENTIONABLE = 9, NUMBER = 10, + ATTACHMENT = 11, } export const enum ApplicationCommandPermissionTypes { diff --git a/typings/index.d.ts b/typings/index.d.ts index b6adc8950050..4c6659f08abf 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -335,6 +335,7 @@ export abstract class BaseCommandInteraction; public channelId: Snowflake; public commandId: Snowflake; @@ -798,6 +799,11 @@ export class CommandInteractionOptionResolver['message']> | null; public getFocused(getFull: true): ApplicationCommandOptionChoice; public getFocused(getFull?: boolean): string | number; + public getAttachment(name: string, required: true): NonNullable['attachment']>; + public getAttachment( + name: string, + required?: boolean, + ): NonNullable['attachment']> | null; } export class ContextMenuInteraction extends BaseCommandInteraction { @@ -4102,6 +4108,7 @@ export interface CommandInteractionOption channel?: CacheTypeReducer; role?: CacheTypeReducer; message?: GuildCacheMessage; + attachment?: MessageAttachment; } export interface CommandInteractionResolvedData { @@ -4110,6 +4117,7 @@ export interface CommandInteractionResolvedData>; channels?: Collection>; messages?: Collection>; + attachments?: Collection; } export interface ConstantsClientApplicationAssetTypes {