diff --git a/packages/builders/src/interactions/contextMenuCommands/ContextMenuCommandBuilder.ts b/packages/builders/src/interactions/contextMenuCommands/ContextMenuCommandBuilder.ts index 1c11391c8797..db0e9712f4f1 100644 --- a/packages/builders/src/interactions/contextMenuCommands/ContextMenuCommandBuilder.ts +++ b/packages/builders/src/interactions/contextMenuCommands/ContextMenuCommandBuilder.ts @@ -67,6 +67,8 @@ export class ContextMenuCommandBuilder { * * @remarks * By default, commands are visible. This property is only for global commands. + * @deprecated + * Use {@link ContextMenuCommandBuilder.contexts} instead. */ public readonly dm_permission: boolean | undefined = undefined; @@ -167,6 +169,7 @@ export class ContextMenuCommandBuilder { * By default, commands are visible. This method is only for global commands. * @param enabled - Whether the command should be enabled in direct messages * @see {@link https://discord.com/developers/docs/interactions/application-commands#permissions} + * @deprecated Use {@link ContextMenuCommandBuilder.setContexts} instead. */ public setDMPermission(enabled: boolean | null | undefined) { // Assert the value matches the conditions diff --git a/packages/builders/src/interactions/slashCommands/SlashCommandBuilder.ts b/packages/builders/src/interactions/slashCommands/SlashCommandBuilder.ts index 9f94c88ab566..ef6ae652eb8f 100644 --- a/packages/builders/src/interactions/slashCommands/SlashCommandBuilder.ts +++ b/packages/builders/src/interactions/slashCommands/SlashCommandBuilder.ts @@ -63,6 +63,8 @@ export class SlashCommandBuilder { * * @remarks * By default, commands are visible. This property is only for global commands. + * @deprecated + * Use {@link SlashCommandBuilder.contexts} instead. */ public readonly dm_permission: boolean | undefined = undefined; diff --git a/packages/builders/src/interactions/slashCommands/mixins/SharedSlashCommand.ts b/packages/builders/src/interactions/slashCommands/mixins/SharedSlashCommand.ts index 3908925bdea8..32b48edd459d 100644 --- a/packages/builders/src/interactions/slashCommands/mixins/SharedSlashCommand.ts +++ b/packages/builders/src/interactions/slashCommands/mixins/SharedSlashCommand.ts @@ -43,6 +43,9 @@ export class SharedSlashCommand { public readonly default_member_permissions: Permissions | null | undefined = undefined; + /** + * @deprecated Use {@link SharedSlashCommand.contexts} instead. + */ public readonly dm_permission: boolean | undefined = undefined; public readonly integration_types?: ApplicationIntegrationType[]; @@ -113,6 +116,8 @@ export class SharedSlashCommand { * By default, commands are visible. This method is only for global commands. * @param enabled - Whether the command should be enabled in direct messages * @see {@link https://discord.com/developers/docs/interactions/application-commands#permissions} + * @deprecated + * Use {@link SharedSlashCommand.setContexts} instead. */ public setDMPermission(enabled: boolean | null | undefined) { // Assert the value matches the conditions diff --git a/packages/discord.js/src/managers/ApplicationCommandManager.js b/packages/discord.js/src/managers/ApplicationCommandManager.js index 884ad9258cde..e38c2f7c8d6c 100644 --- a/packages/discord.js/src/managers/ApplicationCommandManager.js +++ b/packages/discord.js/src/managers/ApplicationCommandManager.js @@ -259,6 +259,8 @@ class ApplicationCommandManager extends CachedManager { options: command.options?.map(option => ApplicationCommand.transformOption(option)), default_member_permissions, dm_permission: command.dmPermission ?? command.dm_permission, + integration_types: command.integrationTypes ?? command.integration_types, + contexts: command.contexts, }; } } diff --git a/packages/discord.js/src/managers/PartialGroupDMMessageManager.js b/packages/discord.js/src/managers/PartialGroupDMMessageManager.js new file mode 100644 index 000000000000..b30abe733f3b --- /dev/null +++ b/packages/discord.js/src/managers/PartialGroupDMMessageManager.js @@ -0,0 +1,17 @@ +'use strict'; + +const MessageManager = require('./MessageManager'); + +/** + * Manages API methods for messages in group direct message channels and holds their cache. + * @extends {MessageManager} + */ +class PartialGroupDMMessageManager extends MessageManager { + /** + * The channel that the messages belong to + * @name PartialGroupDMMessageManager#channel + * @type {PartialGroupDMChannel} + */ +} + +module.exports = PartialGroupDMMessageManager; diff --git a/packages/discord.js/src/structures/ApplicationCommand.js b/packages/discord.js/src/structures/ApplicationCommand.js index fe45763b438d..881822b54a70 100644 --- a/packages/discord.js/src/structures/ApplicationCommand.js +++ b/packages/discord.js/src/structures/ApplicationCommand.js @@ -145,12 +145,35 @@ class ApplicationCommand extends Base { * Whether the command can be used in DMs * This property is always `null` on guild commands * @type {?boolean} + * @deprecated Use {@link ApplicationCommand#contexts} instead. */ this.dmPermission = data.dm_permission; } else { this.dmPermission ??= null; } + if ('integration_types' in data) { + /** + * Installation context(s) where the command is available + * Only for globally-scoped commands + * @type {?ApplicationIntegrationType[]} + */ + this.integrationTypes = data.integration_types; + } else { + this.integrationTypes ??= null; + } + + if ('contexts' in data) { + /** + * Interaction context(s) where the command can be used + * Only for globally-scoped commands + * @type {?InteractionContextType[]} + */ + this.contexts = data.contexts; + } else { + this.contexts ??= null; + } + if ('version' in data) { /** * Autoincrementing version identifier updated during substantial record changes @@ -394,7 +417,9 @@ class ApplicationCommand extends Base { !isEqual( command.descriptionLocalizations ?? command.description_localizations ?? {}, this.descriptionLocalizations ?? {}, - ) + ) || + !isEqual(command.integrationTypes ?? command.integration_types ?? [], this.integrationTypes ?? {}) || + !isEqual(command.contexts ?? [], this.contexts ?? []) ) { return false; } diff --git a/packages/discord.js/src/structures/BaseInteraction.js b/packages/discord.js/src/structures/BaseInteraction.js index d9a1de301dbb..db778080b460 100644 --- a/packages/discord.js/src/structures/BaseInteraction.js +++ b/packages/discord.js/src/structures/BaseInteraction.js @@ -75,9 +75,9 @@ class BaseInteraction extends Base { /** * Set of permissions the application or bot has within the channel the interaction was sent from - * @type {?Readonly} + * @type {Readonly} */ - this.appPermissions = data.app_permissions ? new PermissionsBitField(data.app_permissions).freeze() : null; + this.appPermissions = new PermissionsBitField(data.app_permissions).freeze(); /** * The permissions of the member, if one exists, in the channel this interaction was executed in diff --git a/packages/discord.js/src/structures/ClientApplication.js b/packages/discord.js/src/structures/ClientApplication.js index 3626561dc857..3149a579381a 100644 --- a/packages/discord.js/src/structures/ClientApplication.js +++ b/packages/discord.js/src/structures/ClientApplication.js @@ -15,8 +15,8 @@ const PermissionsBitField = require('../util/PermissionsBitField'); /** * @typedef {Object} ClientApplicationInstallParams - * @property {OAuth2Scopes[]} scopes The scopes to add the application to the server with - * @property {Readonly} permissions The permissions this bot will request upon joining + * @property {OAuth2Scopes[]} scopes Scopes that will be set upon adding this application + * @property {Readonly} permissions Permissions that will be requested for the integrated role */ /** @@ -68,6 +68,56 @@ class ClientApplication extends Application { this.installParams ??= null; } + /** + * OAuth2 installation parameters. + * @typedef {Object} IntegrationTypesConfigurationParameters + * @property {OAuth2Scopes[]} scopes Scopes that will be set upon adding this application + * @property {Readonly} permissions Permissions that will be requested for the integrated role + */ + + /** + * The application's supported installation context data. + * @typedef {Object} IntegrationTypesConfigurationContext + * @property {?IntegrationTypesConfigurationParameters} oauth2InstallParams + * Scopes and permissions regarding the installation context + */ + + /** + * The application's supported installation context data. + * @typedef {Object} IntegrationTypesConfiguration + * @property {IntegrationTypesConfigurationContext} [0] Scopes and permissions + * regarding the guild-installation context + * @property {IntegrationTypesConfigurationContext} [1] Scopes and permissions + * regarding the user-installation context + */ + + if ('integration_types_config' in data) { + /** + * Default scopes and permissions for each supported installation context. + * The keys are stringified variants of {@link ApplicationIntegrationType}. + * @type {?IntegrationTypesConfiguration} + */ + this.integrationTypesConfig = Object.fromEntries( + Object.entries(data.integration_types_config).map(([key, config]) => { + let oauth2InstallParams = null; + if (config.oauth2_install_params) { + oauth2InstallParams = { + scopes: config.oauth2_install_params.scopes, + permissions: new PermissionsBitField(config.oauth2_install_params.permissions).freeze(), + }; + } + + const context = { + oauth2InstallParams, + }; + + return [key, context]; + }), + ); + } else { + this.integrationTypesConfig ??= null; + } + if ('custom_install_url' in data) { /** * This application's custom installation URL @@ -96,6 +146,16 @@ class ClientApplication extends Application { this.approximateGuildCount ??= null; } + if ('approximate_user_install_count' in data) { + /** + * An approximate amount of users that have installed this application. + * @type {?number} + */ + this.approximateUserInstallCount = data.approximate_user_install_count; + } else { + this.approximateUserInstallCount ??= null; + } + if ('guild_id' in data) { /** * The id of the guild associated with this application. diff --git a/packages/discord.js/src/structures/CommandInteraction.js b/packages/discord.js/src/structures/CommandInteraction.js index 0d435deeb446..2dec1230021a 100644 --- a/packages/discord.js/src/structures/CommandInteraction.js +++ b/packages/discord.js/src/structures/CommandInteraction.js @@ -45,6 +45,21 @@ class CommandInteraction extends BaseInteraction { */ this.commandGuildId = data.data.guild_id ?? null; + /* eslint-disable max-len */ + /** + * Mapping of installation contexts that the interaction was authorized for the related user or guild ids + * @type {APIAuthorizingIntegrationOwnersMap} + * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-authorizing-integration-owners-object} + */ + this.authorizingIntegrationOwners = data.authorizing_integration_owners; + /* eslint-enable max-len */ + + /** + * Context where the interaction was triggered from + * @type {?InteractionContextType} + */ + this.context = data.context ?? null; + /** * Whether the reply to this interaction has been deferred * @type {boolean} diff --git a/packages/discord.js/src/structures/Message.js b/packages/discord.js/src/structures/Message.js index 54c279591716..0fe2f762e3ac 100644 --- a/packages/discord.js/src/structures/Message.js +++ b/packages/discord.js/src/structures/Message.js @@ -26,6 +26,7 @@ const { createComponent } = require('../util/Components'); const { NonSystemMessageTypes, MaxBulkDeletableMessageAge, UndeletableMessageTypes } = require('../util/Constants'); const MessageFlagsBitField = require('../util/MessageFlagsBitField'); const PermissionsBitField = require('../util/PermissionsBitField'); +const { _transformAPIMessageInteractionMetadata } = require('../util/Transformers.js'); const { cleanContent, resolvePartialEmoji, transformResolved } = require('../util/Util'); /** @@ -383,6 +384,33 @@ class Message extends Base { this.channel?.messages._add({ guild_id: data.message_reference?.guild_id, ...data.referenced_message }); } + if (data.interaction_metadata) { + /** + * Partial data of the interaction that a message is a result of + * @typedef {Object} MessageInteractionMetadata + * @property {Snowflake} id The interaction's id + * @property {InteractionType} type The type of the interaction + * @property {User} user The user that invoked the interaction + * @property {APIAuthorizingIntegrationOwnersMap} authorizingIntegrationOwners + * Ids for installation context(s) related to an interaction + * @property {?Snowflake} originalResponseMessageId + * Id of the original response message. Present only on follow-up messages + * @property {?Snowflake} interactedMessageId + * Id of the message that contained interactive component. + * Present only on messages created from component interactions + * @property {?MessageInteractionMetadata} triggeringInteractionMetadata + * Metadata for the interaction that was used to open the modal. Present only on modal submit interactions + */ + + /** + * Partial data of the interaction that this message is a result of + * @type {?MessageInteractionMetadata} + */ + this.interactionMetadata = _transformAPIMessageInteractionMetadata(this.client, data.interaction_metadata); + } else { + this.interactionMetadata ??= null; + } + /** * Partial data of the interaction that a message is a reply to * @typedef {Object} MessageInteraction @@ -391,6 +419,7 @@ class Message extends Base { * @property {string} commandName The name of the interaction's application command, * as well as the subcommand and subcommand group, where applicable * @property {User} user The user that invoked the interaction + * @deprecated Use {@link Message#interactionMetadata} instead. */ if (data.interaction) { diff --git a/packages/discord.js/src/structures/PartialGroupDMChannel.js b/packages/discord.js/src/structures/PartialGroupDMChannel.js index ecbb878ce46b..704c8655753c 100644 --- a/packages/discord.js/src/structures/PartialGroupDMChannel.js +++ b/packages/discord.js/src/structures/PartialGroupDMChannel.js @@ -2,6 +2,7 @@ const { BaseChannel } = require('./BaseChannel'); const { DiscordjsError, ErrorCodes } = require('../errors'); +const PartialGroupDMMessageManager = require('../managers/PartialGroupDMMessageManager'); /** * Represents a Partial Group DM Channel on Discord. @@ -37,6 +38,12 @@ class PartialGroupDMChannel extends BaseChannel { * @type {PartialRecipient[]} */ this.recipients = data.recipients; + + /** + * A manager of the messages belonging to this channel + * @type {PartialGroupDMMessageManager} + */ + this.messages = new PartialGroupDMMessageManager(this); } /** diff --git a/packages/discord.js/src/util/APITypes.js b/packages/discord.js/src/util/APITypes.js index 7f2b5922f284..89e3827eeb95 100644 --- a/packages/discord.js/src/util/APITypes.js +++ b/packages/discord.js/src/util/APITypes.js @@ -30,6 +30,16 @@ * @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIApplicationCommandOption} */ +/** + * @external ApplicationIntegrationType + * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ApplicationIntegrationType} + */ + +/** + * @external APIAuthorizingIntegrationOwnersMap + * @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIAuthorizingIntegrationOwnersMap} + */ + /** * @external APIAutoModerationAction * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIAutoModerationAction} @@ -140,6 +150,11 @@ * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIMessageComponentEmoji} */ +/** + * @external APIMessageInteractionMetadata + * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIMessageInteractionMetadata} + */ + /** * @external APIModalInteractionResponse * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIModalInteractionResponse} @@ -400,6 +415,11 @@ * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/IntegrationExpireBehavior} */ +/** + * @external InteractionContextType + * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/InteractionContextType} + */ + /** * @external InteractionType * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/InteractionType} diff --git a/packages/discord.js/src/util/Transformers.js b/packages/discord.js/src/util/Transformers.js index f4d7af0ec6ab..89d6c5e092c8 100644 --- a/packages/discord.js/src/util/Transformers.js +++ b/packages/discord.js/src/util/Transformers.js @@ -33,4 +33,25 @@ function _transformAPIAutoModerationAction(autoModerationAction) { }; } -module.exports = { toSnakeCase, _transformAPIAutoModerationAction }; +/** + * Transforms an API message interaction metadata object to a camel-cased variant. + * @param {Client} client The client + * @param {APIMessageInteractionMetadata} messageInteractionMetadata The metadata to transform + * @returns {MessageInteractionMetadata} + * @ignore + */ +function _transformAPIMessageInteractionMetadata(client, messageInteractionMetadata) { + return { + id: messageInteractionMetadata.id, + type: messageInteractionMetadata.type, + user: client.users._add(messageInteractionMetadata.user), + authorizingIntegrationOwners: messageInteractionMetadata.authorizing_integration_owners, + originalResponseMessageId: messageInteractionMetadata.original_response_message_id ?? null, + interactedMessageId: messageInteractionMetadata.interacted_message_id ?? null, + triggeringInteractionMetadata: messageInteractionMetadata.triggering_interaction_metadata + ? _transformAPIMessageInteractionMetadata(messageInteractionMetadata.triggering_interaction_metadata) + : null, + }; +} + +module.exports = { toSnakeCase, _transformAPIAutoModerationAction, _transformAPIMessageInteractionMetadata }; diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 53429f66e45b..1dc3d97ea94a 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -175,6 +175,8 @@ import { SKUType, APIEntitlement, EntitlementType, + ApplicationIntegrationType, + InteractionContextType, APIPoll, PollLayoutType, APIPollAnswer, @@ -182,6 +184,7 @@ import { SelectMenuDefaultValueType, InviteType, ReactionType, + APIAuthorizingIntegrationOwnersMap, } from 'discord-api-types/v10'; import { ChildProcess } from 'node:child_process'; import { EventEmitter } from 'node:events'; @@ -429,17 +432,20 @@ export abstract class Application extends Base { export class ApplicationCommand extends Base { private constructor(client: Client, data: RawApplicationCommandData, guild?: Guild, guildId?: Snowflake); public applicationId: Snowflake; + public contexts: InteractionContextType[] | null; public get createdAt(): Date; public get createdTimestamp(): number; public defaultMemberPermissions: Readonly | null; public description: string; public descriptionLocalizations: LocalizationMap | null; public descriptionLocalized: string | null; + /** @deprecated Use {@link ApplicationCommand.contexts} instead */ public dmPermission: boolean | null; public guild: Guild | null; public guildId: Snowflake | null; public get manager(): ApplicationCommandManager; public id: Snowflake; + public integrationTypes: ApplicationIntegrationType[] | null; public name: string; public nameLocalizations: LocalizationMap | null; public nameLocalized: string | null; @@ -541,6 +547,7 @@ export type GuildCacheMessage = CacheTypeReducer< export type BooleanCache = Cached extends 'cached' ? true : false; export abstract class CommandInteraction extends BaseInteraction { + public authorizingIntegrationOwners: APIAuthorizingIntegrationOwnersMap; public type: InteractionType.ApplicationCommand; public get command(): ApplicationCommand | ApplicationCommand<{ guild: GuildResolvable }> | null; public options: Omit< @@ -565,6 +572,7 @@ export abstract class CommandInteraction e public commandName: string; public commandType: ApplicationCommandType; public commandGuildId: Snowflake | null; + public context: InteractionContextType | null; public deferred: boolean; public ephemeral: boolean | null; public replied: boolean; @@ -1073,8 +1081,10 @@ export class ClientApplication extends Application { public cover: string | null; public flags: Readonly; public approximateGuildCount: number | null; + public approximateUserInstallCount: number | null; public tags: string[]; public installParams: ClientApplicationInstallParams | null; + public integrationTypesConfig: IntegrationTypesConfiguration | null; public customInstallURL: string | null; public owner: User | Team | null; public get partial(): boolean; @@ -1932,7 +1942,7 @@ export class BaseInteraction extends Base public type: InteractionType; public user: User; public version: number; - public appPermissions: CacheTypeReducer>; + public appPermissions: Readonly; public memberPermissions: CacheTypeReducer>; public locale: Locale; public guildLocale: CacheTypeReducer; @@ -2150,7 +2160,9 @@ export class Message extends Base { public get guild(): If; public get hasThread(): boolean; public id: Snowflake; + /** @deprecated Use {@link Message.interactionMetadata} instead. */ public interaction: MessageInteraction | null; + public interactionMetadata: MessageInteractionMetadata | null; public get member(): GuildMember | null; public mentions: MessageMentions; public nonce: string | number | null; @@ -2180,23 +2192,27 @@ export class Message extends Base { public createMessageComponentCollector( options?: MessageCollectorOptionsParams, ): InteractionCollector[ComponentType]>; - public delete(): Promise>; - public edit(content: string | MessageEditOptions | MessagePayload): Promise>; + public delete(): Promise>>; + public edit( + content: string | MessageEditOptions | MessagePayload, + ): Promise>>; public equals(message: Message, rawData: unknown): boolean; - public fetchReference(): Promise>; + public fetchReference(): Promise>>; public fetchWebhook(): Promise; - public crosspost(): Promise>; - public fetch(force?: boolean): Promise>; - public pin(reason?: string): Promise>; + public crosspost(): Promise>>; + public fetch(force?: boolean): Promise>>; + public pin(reason?: string): Promise>>; public react(emoji: EmojiIdentifierResolvable): Promise; - public removeAttachments(): Promise>; - public reply(options: string | MessagePayload | MessageReplyOptions): Promise>; + public removeAttachments(): Promise>>; + public reply( + options: string | MessagePayload | MessageReplyOptions, + ): Promise>>; public resolveComponent(customId: string): MessageActionRowComponent | null; public startThread(options: StartThreadOptions): Promise>; - public suppressEmbeds(suppress?: boolean): Promise>; + public suppressEmbeds(suppress?: boolean): Promise>>; public toJSON(): unknown; public toString(): string; - public unpin(reason?: string): Promise>; + public unpin(reason?: string): Promise>>; public inGuild(): this is Message; } @@ -2540,6 +2556,7 @@ export class PartialGroupDMChannel extends BaseChannel { public name: string | null; public icon: string | null; public recipients: PartialRecipient[]; + public messages: PartialGroupDMMessageManager; public iconURL(options?: ImageURLOptions): string | null; public toString(): ChannelMention; } @@ -4501,6 +4518,10 @@ export class DMMessageManager extends MessageManager { public channel: DMChannel; } +export class PartialGroupDMMessageManager extends MessageManager { + public channel: PartialGroupDMChannel; +} + export class GuildMessageManager extends MessageManager { public channel: GuildTextBasedChannel; public crosspost(message: MessageResolvable): Promise>; @@ -4755,6 +4776,8 @@ export interface BaseApplicationCommandData { dmPermission?: boolean; defaultMemberPermissions?: PermissionResolvable | null; nsfw?: boolean; + contexts?: readonly InteractionContextType[]; + integrationTypes?: readonly ApplicationIntegrationType[]; } export interface AttachmentData { @@ -5247,6 +5270,10 @@ export interface GuildMembersChunk { nonce: string | undefined; } +type NonPartialGroupDMChannel = Structure & { + channel: Exclude; +}; + export interface ClientEvents { applicationCommandPermissionsUpdate: [data: ApplicationCommandPermissionsUpdateData]; autoModerationActionExecution: [autoModerationActionExecution: AutoModerationActionExecution]; @@ -5289,17 +5316,17 @@ export interface ClientEvents { guildUpdate: [oldGuild: Guild, newGuild: Guild]; inviteCreate: [invite: Invite]; inviteDelete: [invite: Invite]; - messageCreate: [message: Message]; - messageDelete: [message: Message | PartialMessage]; + messageCreate: [message: NonPartialGroupDMChannel]; + messageDelete: [message: NonPartialGroupDMChannel]; messagePollVoteAdd: [pollAnswer: PollAnswer, userId: Snowflake]; messagePollVoteRemove: [pollAnswer: PollAnswer, userId: Snowflake]; messageReactionRemoveAll: [ - message: Message | PartialMessage, + message: NonPartialGroupDMChannel, reactions: ReadonlyCollection, ]; messageReactionRemoveEmoji: [reaction: MessageReaction | PartialMessageReaction]; messageDeleteBulk: [ - messages: ReadonlyCollection, + messages: ReadonlyCollection>, channel: GuildTextBasedChannel, ]; messageReactionAdd: [ @@ -6221,6 +6248,16 @@ export interface IntegrationAccount { export type IntegrationType = 'twitch' | 'youtube' | 'discord' | 'guild_subscription'; +export type IntegrationTypesConfigurationParameters = ClientApplicationInstallParams; + +export interface IntegrationTypesConfigurationContext { + oauth2InstallParams: IntegrationTypesConfigurationParameters | null; +} + +export type IntegrationTypesConfiguration = Partial< + Record +>; + export type CollectedInteraction = | StringSelectMenuInteraction | UserSelectMenuInteraction @@ -6369,6 +6406,16 @@ export interface MessageComponentCollectorOptions extends Omit, 'channel' | 'guild' | 'interactionType'> {} +export interface MessageInteractionMetadata { + id: Snowflake; + type: InteractionType; + user: User; + authorizingIntegrationOwners: APIAuthorizingIntegrationOwnersMap; + originalResponseMessageId: Snowflake | null; + interactedMessageId: Snowflake | null; + triggeringInteractionMetadata: MessageInteractionMetadata | null; +} + export interface MessageInteraction { id: Snowflake; type: InteractionType; @@ -6829,10 +6876,7 @@ export type Channel = | ForumChannel | MediaChannel; -export type TextBasedChannel = Exclude< - Extract, - PartialGroupDMChannel | ForumChannel | MediaChannel ->; +export type TextBasedChannel = Exclude, ForumChannel | MediaChannel>; export type TextBasedChannels = TextBasedChannel; diff --git a/packages/discord.js/typings/index.test-d.ts b/packages/discord.js/typings/index.test-d.ts index 78093fc55654..02011850550a 100644 --- a/packages/discord.js/typings/index.test-d.ts +++ b/packages/discord.js/typings/index.test-d.ts @@ -452,7 +452,7 @@ client.on('messageCreate', async message => { expectType>(message.mentions.members); } - expectType(message.channel); + expectType>(message.channel); expectNotType(message.channel); // @ts-expect-error @@ -1624,7 +1624,7 @@ declare const guildChannelManager: GuildChannelManager; expectType>>(messages.fetchPinned()); expectType(message.guild); expectType(message.guildId); - expectType(message.channel.messages.channel); + expectType(message.channel.messages.channel); expectType(message.mentions); expectType(message.mentions.guild); expectType | null>(message.mentions.members); @@ -2209,6 +2209,7 @@ expectType(TextBasedChannel); expectType< | ChannelType.GuildText | ChannelType.DM + | ChannelType.GroupDM | ChannelType.GuildAnnouncement | ChannelType.GuildVoice | ChannelType.GuildStageVoice