mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-15 11:03:30 +01:00
feat: user-installable apps (#10227)
* feat: inital user-installable apps support * docs: add deprecation warnings * feat: add equality checks * fix: possibly `null` cases * docs: tweaks * docs: add deprecations * fix(ApplicationCommandManager): amend transform command * feat: properly support `integration_types_config` * docs: add . * docs: minor changes * featBaseApplicationCommandData): update type * style: prettier * chore: fix issues * fix: correct casing Co-authored-by: Superchupu <53496941+SuperchupuDev@users.noreply.github.com> * refactor: remove console log * fix: use case that satisfies `/core` and the API * fix: `oauth2InstallParams` property is not nullable * fix: do not convert keys into strings * feat: update transforer to return the full map * feat: update transformers * feat: add `PartialGroupDMMessageManager ` Hope this is not a breaking change * docs: fix type * feat: add approximate count of users property * fix: messageCreate doesn't emit in PartialGroupDMChannel * fix: add GroupDM to TextBasedChannelTypes * feat: add NonPartialGroupDMChannel helper * fix: expect PartialGroupDMChannel * feat: narrow generic type * test: exclude PartialGroupDMChannel * feat: use structure's channel type * docs: narrow type * feat: remove transformer * refactor: remove unnecessary parse * feat: add APIAutoModerationAction transformer * fix: use the right transformer during recursive parsing of interaction metadata * docs: add external types * docs: add `Message#interactionMetadata` property docs * docs: make nullable * docs: add d-docs link * docs: use optional * fix: make `oauth2InstallParams` nullable * types: update `IntegrationTypesConfiguration` Co-authored-by: Almeida <github@almeidx.dev> * docs: update `IntegrationTypesConfigurationParameters` Co-authored-by: Almeida <github@almeidx.dev> * types: update `IntegrationTypesConfigurationParameters` * refactor: improve readability * docs: mark integrationTypesConfig nullable * refactor: requested changes --------- Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> Co-authored-by: Superchupu <53496941+SuperchupuDev@users.noreply.github.com> Co-authored-by: Vlad Frangu <me@vladfrangu.dev> Co-authored-by: Almeida <github@almeidx.dev>
This commit is contained in:
@@ -67,6 +67,8 @@ export class ContextMenuCommandBuilder {
|
|||||||
*
|
*
|
||||||
* @remarks
|
* @remarks
|
||||||
* By default, commands are visible. This property is only for global commands.
|
* 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;
|
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.
|
* By default, commands are visible. This method is only for global commands.
|
||||||
* @param enabled - Whether the command should be enabled in direct messages
|
* @param enabled - Whether the command should be enabled in direct messages
|
||||||
* @see {@link https://discord.com/developers/docs/interactions/application-commands#permissions}
|
* @see {@link https://discord.com/developers/docs/interactions/application-commands#permissions}
|
||||||
|
* @deprecated Use {@link ContextMenuCommandBuilder.setContexts} instead.
|
||||||
*/
|
*/
|
||||||
public setDMPermission(enabled: boolean | null | undefined) {
|
public setDMPermission(enabled: boolean | null | undefined) {
|
||||||
// Assert the value matches the conditions
|
// Assert the value matches the conditions
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ export class SlashCommandBuilder {
|
|||||||
*
|
*
|
||||||
* @remarks
|
* @remarks
|
||||||
* By default, commands are visible. This property is only for global commands.
|
* 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;
|
public readonly dm_permission: boolean | undefined = undefined;
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ export class SharedSlashCommand {
|
|||||||
|
|
||||||
public readonly default_member_permissions: Permissions | null | undefined = undefined;
|
public readonly default_member_permissions: Permissions | null | undefined = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link SharedSlashCommand.contexts} instead.
|
||||||
|
*/
|
||||||
public readonly dm_permission: boolean | undefined = undefined;
|
public readonly dm_permission: boolean | undefined = undefined;
|
||||||
|
|
||||||
public readonly integration_types?: ApplicationIntegrationType[];
|
public readonly integration_types?: ApplicationIntegrationType[];
|
||||||
@@ -113,6 +116,8 @@ export class SharedSlashCommand {
|
|||||||
* By default, commands are visible. This method is only for global commands.
|
* By default, commands are visible. This method is only for global commands.
|
||||||
* @param enabled - Whether the command should be enabled in direct messages
|
* @param enabled - Whether the command should be enabled in direct messages
|
||||||
* @see {@link https://discord.com/developers/docs/interactions/application-commands#permissions}
|
* @see {@link https://discord.com/developers/docs/interactions/application-commands#permissions}
|
||||||
|
* @deprecated
|
||||||
|
* Use {@link SharedSlashCommand.setContexts} instead.
|
||||||
*/
|
*/
|
||||||
public setDMPermission(enabled: boolean | null | undefined) {
|
public setDMPermission(enabled: boolean | null | undefined) {
|
||||||
// Assert the value matches the conditions
|
// Assert the value matches the conditions
|
||||||
|
|||||||
@@ -259,6 +259,8 @@ class ApplicationCommandManager extends CachedManager {
|
|||||||
options: command.options?.map(option => ApplicationCommand.transformOption(option)),
|
options: command.options?.map(option => ApplicationCommand.transformOption(option)),
|
||||||
default_member_permissions,
|
default_member_permissions,
|
||||||
dm_permission: command.dmPermission ?? command.dm_permission,
|
dm_permission: command.dmPermission ?? command.dm_permission,
|
||||||
|
integration_types: command.integrationTypes ?? command.integration_types,
|
||||||
|
contexts: command.contexts,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -145,12 +145,35 @@ class ApplicationCommand extends Base {
|
|||||||
* Whether the command can be used in DMs
|
* Whether the command can be used in DMs
|
||||||
* <info>This property is always `null` on guild commands</info>
|
* <info>This property is always `null` on guild commands</info>
|
||||||
* @type {?boolean}
|
* @type {?boolean}
|
||||||
|
* @deprecated Use {@link ApplicationCommand#contexts} instead.
|
||||||
*/
|
*/
|
||||||
this.dmPermission = data.dm_permission;
|
this.dmPermission = data.dm_permission;
|
||||||
} else {
|
} else {
|
||||||
this.dmPermission ??= null;
|
this.dmPermission ??= null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ('integration_types' in data) {
|
||||||
|
/**
|
||||||
|
* Installation context(s) where the command is available
|
||||||
|
* <info>Only for globally-scoped commands</info>
|
||||||
|
* @type {?ApplicationIntegrationType[]}
|
||||||
|
*/
|
||||||
|
this.integrationTypes = data.integration_types;
|
||||||
|
} else {
|
||||||
|
this.integrationTypes ??= null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('contexts' in data) {
|
||||||
|
/**
|
||||||
|
* Interaction context(s) where the command can be used
|
||||||
|
* <info>Only for globally-scoped commands</info>
|
||||||
|
* @type {?InteractionContextType[]}
|
||||||
|
*/
|
||||||
|
this.contexts = data.contexts;
|
||||||
|
} else {
|
||||||
|
this.contexts ??= null;
|
||||||
|
}
|
||||||
|
|
||||||
if ('version' in data) {
|
if ('version' in data) {
|
||||||
/**
|
/**
|
||||||
* Autoincrementing version identifier updated during substantial record changes
|
* Autoincrementing version identifier updated during substantial record changes
|
||||||
@@ -394,7 +417,9 @@ class ApplicationCommand extends Base {
|
|||||||
!isEqual(
|
!isEqual(
|
||||||
command.descriptionLocalizations ?? command.description_localizations ?? {},
|
command.descriptionLocalizations ?? command.description_localizations ?? {},
|
||||||
this.descriptionLocalizations ?? {},
|
this.descriptionLocalizations ?? {},
|
||||||
)
|
) ||
|
||||||
|
!isEqual(command.integrationTypes ?? command.integration_types ?? [], this.integrationTypes ?? {}) ||
|
||||||
|
!isEqual(command.contexts ?? [], this.contexts ?? [])
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,9 +75,9 @@ class BaseInteraction extends Base {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of permissions the application or bot has within the channel the interaction was sent from
|
* Set of permissions the application or bot has within the channel the interaction was sent from
|
||||||
* @type {?Readonly<PermissionsBitField>}
|
* @type {Readonly<PermissionsBitField>}
|
||||||
*/
|
*/
|
||||||
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
|
* The permissions of the member, if one exists, in the channel this interaction was executed in
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ const PermissionsBitField = require('../util/PermissionsBitField');
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} ClientApplicationInstallParams
|
* @typedef {Object} ClientApplicationInstallParams
|
||||||
* @property {OAuth2Scopes[]} scopes The scopes to add the application to the server with
|
* @property {OAuth2Scopes[]} scopes Scopes that will be set upon adding this application
|
||||||
* @property {Readonly<PermissionsBitField>} permissions The permissions this bot will request upon joining
|
* @property {Readonly<PermissionsBitField>} permissions Permissions that will be requested for the integrated role
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,6 +68,56 @@ class ClientApplication extends Application {
|
|||||||
this.installParams ??= null;
|
this.installParams ??= null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OAuth2 installation parameters.
|
||||||
|
* @typedef {Object} IntegrationTypesConfigurationParameters
|
||||||
|
* @property {OAuth2Scopes[]} scopes Scopes that will be set upon adding this application
|
||||||
|
* @property {Readonly<PermissionsBitField>} 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) {
|
if ('custom_install_url' in data) {
|
||||||
/**
|
/**
|
||||||
* This application's custom installation URL
|
* This application's custom installation URL
|
||||||
@@ -96,6 +146,16 @@ class ClientApplication extends Application {
|
|||||||
this.approximateGuildCount ??= null;
|
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) {
|
if ('guild_id' in data) {
|
||||||
/**
|
/**
|
||||||
* The id of the guild associated with this application.
|
* The id of the guild associated with this application.
|
||||||
|
|||||||
@@ -45,6 +45,21 @@ class CommandInteraction extends BaseInteraction {
|
|||||||
*/
|
*/
|
||||||
this.commandGuildId = data.data.guild_id ?? null;
|
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
|
* Whether the reply to this interaction has been deferred
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ const { createComponent } = require('../util/Components');
|
|||||||
const { NonSystemMessageTypes, MaxBulkDeletableMessageAge, UndeletableMessageTypes } = require('../util/Constants');
|
const { NonSystemMessageTypes, MaxBulkDeletableMessageAge, UndeletableMessageTypes } = require('../util/Constants');
|
||||||
const MessageFlagsBitField = require('../util/MessageFlagsBitField');
|
const MessageFlagsBitField = require('../util/MessageFlagsBitField');
|
||||||
const PermissionsBitField = require('../util/PermissionsBitField');
|
const PermissionsBitField = require('../util/PermissionsBitField');
|
||||||
|
const { _transformAPIMessageInteractionMetadata } = require('../util/Transformers.js');
|
||||||
const { cleanContent, resolvePartialEmoji, transformResolved } = require('../util/Util');
|
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 });
|
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
|
* Partial data of the interaction that a message is a reply to
|
||||||
* @typedef {Object} MessageInteraction
|
* @typedef {Object} MessageInteraction
|
||||||
@@ -391,6 +419,7 @@ class Message extends Base {
|
|||||||
* @property {string} commandName The name of the interaction's application command,
|
* @property {string} commandName The name of the interaction's application command,
|
||||||
* as well as the subcommand and subcommand group, where applicable
|
* as well as the subcommand and subcommand group, where applicable
|
||||||
* @property {User} user The user that invoked the interaction
|
* @property {User} user The user that invoked the interaction
|
||||||
|
* @deprecated Use {@link Message#interactionMetadata} instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (data.interaction) {
|
if (data.interaction) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const { BaseChannel } = require('./BaseChannel');
|
const { BaseChannel } = require('./BaseChannel');
|
||||||
const { DiscordjsError, ErrorCodes } = require('../errors');
|
const { DiscordjsError, ErrorCodes } = require('../errors');
|
||||||
|
const PartialGroupDMMessageManager = require('../managers/PartialGroupDMMessageManager');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a Partial Group DM Channel on Discord.
|
* Represents a Partial Group DM Channel on Discord.
|
||||||
@@ -37,6 +38,12 @@ class PartialGroupDMChannel extends BaseChannel {
|
|||||||
* @type {PartialRecipient[]}
|
* @type {PartialRecipient[]}
|
||||||
*/
|
*/
|
||||||
this.recipients = data.recipients;
|
this.recipients = data.recipients;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A manager of the messages belonging to this channel
|
||||||
|
* @type {PartialGroupDMMessageManager}
|
||||||
|
*/
|
||||||
|
this.messages = new PartialGroupDMMessageManager(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -30,6 +30,16 @@
|
|||||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIApplicationCommandOption}
|
* @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
|
* @external APIAutoModerationAction
|
||||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/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}
|
* @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
|
* @external APIModalInteractionResponse
|
||||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/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}
|
* @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
|
* @external InteractionType
|
||||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/InteractionType}
|
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/InteractionType}
|
||||||
|
|||||||
@@ -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 };
|
||||||
|
|||||||
82
packages/discord.js/typings/index.d.ts
vendored
82
packages/discord.js/typings/index.d.ts
vendored
@@ -175,6 +175,8 @@ import {
|
|||||||
SKUType,
|
SKUType,
|
||||||
APIEntitlement,
|
APIEntitlement,
|
||||||
EntitlementType,
|
EntitlementType,
|
||||||
|
ApplicationIntegrationType,
|
||||||
|
InteractionContextType,
|
||||||
APIPoll,
|
APIPoll,
|
||||||
PollLayoutType,
|
PollLayoutType,
|
||||||
APIPollAnswer,
|
APIPollAnswer,
|
||||||
@@ -182,6 +184,7 @@ import {
|
|||||||
SelectMenuDefaultValueType,
|
SelectMenuDefaultValueType,
|
||||||
InviteType,
|
InviteType,
|
||||||
ReactionType,
|
ReactionType,
|
||||||
|
APIAuthorizingIntegrationOwnersMap,
|
||||||
} from 'discord-api-types/v10';
|
} from 'discord-api-types/v10';
|
||||||
import { ChildProcess } from 'node:child_process';
|
import { ChildProcess } from 'node:child_process';
|
||||||
import { EventEmitter } from 'node:events';
|
import { EventEmitter } from 'node:events';
|
||||||
@@ -429,17 +432,20 @@ export abstract class Application extends Base {
|
|||||||
export class ApplicationCommand<PermissionsFetchType = {}> extends Base {
|
export class ApplicationCommand<PermissionsFetchType = {}> extends Base {
|
||||||
private constructor(client: Client<true>, data: RawApplicationCommandData, guild?: Guild, guildId?: Snowflake);
|
private constructor(client: Client<true>, data: RawApplicationCommandData, guild?: Guild, guildId?: Snowflake);
|
||||||
public applicationId: Snowflake;
|
public applicationId: Snowflake;
|
||||||
|
public contexts: InteractionContextType[] | null;
|
||||||
public get createdAt(): Date;
|
public get createdAt(): Date;
|
||||||
public get createdTimestamp(): number;
|
public get createdTimestamp(): number;
|
||||||
public defaultMemberPermissions: Readonly<PermissionsBitField> | null;
|
public defaultMemberPermissions: Readonly<PermissionsBitField> | null;
|
||||||
public description: string;
|
public description: string;
|
||||||
public descriptionLocalizations: LocalizationMap | null;
|
public descriptionLocalizations: LocalizationMap | null;
|
||||||
public descriptionLocalized: string | null;
|
public descriptionLocalized: string | null;
|
||||||
|
/** @deprecated Use {@link ApplicationCommand.contexts} instead */
|
||||||
public dmPermission: boolean | null;
|
public dmPermission: boolean | null;
|
||||||
public guild: Guild | null;
|
public guild: Guild | null;
|
||||||
public guildId: Snowflake | null;
|
public guildId: Snowflake | null;
|
||||||
public get manager(): ApplicationCommandManager;
|
public get manager(): ApplicationCommandManager;
|
||||||
public id: Snowflake;
|
public id: Snowflake;
|
||||||
|
public integrationTypes: ApplicationIntegrationType[] | null;
|
||||||
public name: string;
|
public name: string;
|
||||||
public nameLocalizations: LocalizationMap | null;
|
public nameLocalizations: LocalizationMap | null;
|
||||||
public nameLocalized: string | null;
|
public nameLocalized: string | null;
|
||||||
@@ -541,6 +547,7 @@ export type GuildCacheMessage<Cached extends CacheType> = CacheTypeReducer<
|
|||||||
export type BooleanCache<Cached extends CacheType> = Cached extends 'cached' ? true : false;
|
export type BooleanCache<Cached extends CacheType> = Cached extends 'cached' ? true : false;
|
||||||
|
|
||||||
export abstract class CommandInteraction<Cached extends CacheType = CacheType> extends BaseInteraction<Cached> {
|
export abstract class CommandInteraction<Cached extends CacheType = CacheType> extends BaseInteraction<Cached> {
|
||||||
|
public authorizingIntegrationOwners: APIAuthorizingIntegrationOwnersMap;
|
||||||
public type: InteractionType.ApplicationCommand;
|
public type: InteractionType.ApplicationCommand;
|
||||||
public get command(): ApplicationCommand | ApplicationCommand<{ guild: GuildResolvable }> | null;
|
public get command(): ApplicationCommand | ApplicationCommand<{ guild: GuildResolvable }> | null;
|
||||||
public options: Omit<
|
public options: Omit<
|
||||||
@@ -565,6 +572,7 @@ export abstract class CommandInteraction<Cached extends CacheType = CacheType> e
|
|||||||
public commandName: string;
|
public commandName: string;
|
||||||
public commandType: ApplicationCommandType;
|
public commandType: ApplicationCommandType;
|
||||||
public commandGuildId: Snowflake | null;
|
public commandGuildId: Snowflake | null;
|
||||||
|
public context: InteractionContextType | null;
|
||||||
public deferred: boolean;
|
public deferred: boolean;
|
||||||
public ephemeral: boolean | null;
|
public ephemeral: boolean | null;
|
||||||
public replied: boolean;
|
public replied: boolean;
|
||||||
@@ -1073,8 +1081,10 @@ export class ClientApplication extends Application {
|
|||||||
public cover: string | null;
|
public cover: string | null;
|
||||||
public flags: Readonly<ApplicationFlagsBitField>;
|
public flags: Readonly<ApplicationFlagsBitField>;
|
||||||
public approximateGuildCount: number | null;
|
public approximateGuildCount: number | null;
|
||||||
|
public approximateUserInstallCount: number | null;
|
||||||
public tags: string[];
|
public tags: string[];
|
||||||
public installParams: ClientApplicationInstallParams | null;
|
public installParams: ClientApplicationInstallParams | null;
|
||||||
|
public integrationTypesConfig: IntegrationTypesConfiguration | null;
|
||||||
public customInstallURL: string | null;
|
public customInstallURL: string | null;
|
||||||
public owner: User | Team | null;
|
public owner: User | Team | null;
|
||||||
public get partial(): boolean;
|
public get partial(): boolean;
|
||||||
@@ -1932,7 +1942,7 @@ export class BaseInteraction<Cached extends CacheType = CacheType> extends Base
|
|||||||
public type: InteractionType;
|
public type: InteractionType;
|
||||||
public user: User;
|
public user: User;
|
||||||
public version: number;
|
public version: number;
|
||||||
public appPermissions: CacheTypeReducer<Cached, Readonly<PermissionsBitField>>;
|
public appPermissions: Readonly<PermissionsBitField>;
|
||||||
public memberPermissions: CacheTypeReducer<Cached, Readonly<PermissionsBitField>>;
|
public memberPermissions: CacheTypeReducer<Cached, Readonly<PermissionsBitField>>;
|
||||||
public locale: Locale;
|
public locale: Locale;
|
||||||
public guildLocale: CacheTypeReducer<Cached, Locale>;
|
public guildLocale: CacheTypeReducer<Cached, Locale>;
|
||||||
@@ -2150,7 +2160,9 @@ export class Message<InGuild extends boolean = boolean> extends Base {
|
|||||||
public get guild(): If<InGuild, Guild>;
|
public get guild(): If<InGuild, Guild>;
|
||||||
public get hasThread(): boolean;
|
public get hasThread(): boolean;
|
||||||
public id: Snowflake;
|
public id: Snowflake;
|
||||||
|
/** @deprecated Use {@link Message.interactionMetadata} instead. */
|
||||||
public interaction: MessageInteraction | null;
|
public interaction: MessageInteraction | null;
|
||||||
|
public interactionMetadata: MessageInteractionMetadata | null;
|
||||||
public get member(): GuildMember | null;
|
public get member(): GuildMember | null;
|
||||||
public mentions: MessageMentions<InGuild>;
|
public mentions: MessageMentions<InGuild>;
|
||||||
public nonce: string | number | null;
|
public nonce: string | number | null;
|
||||||
@@ -2180,23 +2192,27 @@ export class Message<InGuild extends boolean = boolean> extends Base {
|
|||||||
public createMessageComponentCollector<ComponentType extends MessageComponentType>(
|
public createMessageComponentCollector<ComponentType extends MessageComponentType>(
|
||||||
options?: MessageCollectorOptionsParams<ComponentType, InGuild>,
|
options?: MessageCollectorOptionsParams<ComponentType, InGuild>,
|
||||||
): InteractionCollector<MappedInteractionTypes<InGuild>[ComponentType]>;
|
): InteractionCollector<MappedInteractionTypes<InGuild>[ComponentType]>;
|
||||||
public delete(): Promise<Message<InGuild>>;
|
public delete(): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
|
||||||
public edit(content: string | MessageEditOptions | MessagePayload): Promise<Message<InGuild>>;
|
public edit(
|
||||||
|
content: string | MessageEditOptions | MessagePayload,
|
||||||
|
): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
|
||||||
public equals(message: Message, rawData: unknown): boolean;
|
public equals(message: Message, rawData: unknown): boolean;
|
||||||
public fetchReference(): Promise<Message<InGuild>>;
|
public fetchReference(): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
|
||||||
public fetchWebhook(): Promise<Webhook>;
|
public fetchWebhook(): Promise<Webhook>;
|
||||||
public crosspost(): Promise<Message<InGuild>>;
|
public crosspost(): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
|
||||||
public fetch(force?: boolean): Promise<Message<InGuild>>;
|
public fetch(force?: boolean): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
|
||||||
public pin(reason?: string): Promise<Message<InGuild>>;
|
public pin(reason?: string): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
|
||||||
public react(emoji: EmojiIdentifierResolvable): Promise<MessageReaction>;
|
public react(emoji: EmojiIdentifierResolvable): Promise<MessageReaction>;
|
||||||
public removeAttachments(): Promise<Message<InGuild>>;
|
public removeAttachments(): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
|
||||||
public reply(options: string | MessagePayload | MessageReplyOptions): Promise<Message<InGuild>>;
|
public reply(
|
||||||
|
options: string | MessagePayload | MessageReplyOptions,
|
||||||
|
): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
|
||||||
public resolveComponent(customId: string): MessageActionRowComponent | null;
|
public resolveComponent(customId: string): MessageActionRowComponent | null;
|
||||||
public startThread(options: StartThreadOptions): Promise<PublicThreadChannel<false>>;
|
public startThread(options: StartThreadOptions): Promise<PublicThreadChannel<false>>;
|
||||||
public suppressEmbeds(suppress?: boolean): Promise<Message<InGuild>>;
|
public suppressEmbeds(suppress?: boolean): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
|
||||||
public toJSON(): unknown;
|
public toJSON(): unknown;
|
||||||
public toString(): string;
|
public toString(): string;
|
||||||
public unpin(reason?: string): Promise<Message<InGuild>>;
|
public unpin(reason?: string): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
|
||||||
public inGuild(): this is Message<true>;
|
public inGuild(): this is Message<true>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2540,6 +2556,7 @@ export class PartialGroupDMChannel extends BaseChannel {
|
|||||||
public name: string | null;
|
public name: string | null;
|
||||||
public icon: string | null;
|
public icon: string | null;
|
||||||
public recipients: PartialRecipient[];
|
public recipients: PartialRecipient[];
|
||||||
|
public messages: PartialGroupDMMessageManager;
|
||||||
public iconURL(options?: ImageURLOptions): string | null;
|
public iconURL(options?: ImageURLOptions): string | null;
|
||||||
public toString(): ChannelMention;
|
public toString(): ChannelMention;
|
||||||
}
|
}
|
||||||
@@ -4501,6 +4518,10 @@ export class DMMessageManager extends MessageManager {
|
|||||||
public channel: DMChannel;
|
public channel: DMChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class PartialGroupDMMessageManager extends MessageManager {
|
||||||
|
public channel: PartialGroupDMChannel;
|
||||||
|
}
|
||||||
|
|
||||||
export class GuildMessageManager extends MessageManager<true> {
|
export class GuildMessageManager extends MessageManager<true> {
|
||||||
public channel: GuildTextBasedChannel;
|
public channel: GuildTextBasedChannel;
|
||||||
public crosspost(message: MessageResolvable): Promise<Message<true>>;
|
public crosspost(message: MessageResolvable): Promise<Message<true>>;
|
||||||
@@ -4755,6 +4776,8 @@ export interface BaseApplicationCommandData {
|
|||||||
dmPermission?: boolean;
|
dmPermission?: boolean;
|
||||||
defaultMemberPermissions?: PermissionResolvable | null;
|
defaultMemberPermissions?: PermissionResolvable | null;
|
||||||
nsfw?: boolean;
|
nsfw?: boolean;
|
||||||
|
contexts?: readonly InteractionContextType[];
|
||||||
|
integrationTypes?: readonly ApplicationIntegrationType[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttachmentData {
|
export interface AttachmentData {
|
||||||
@@ -5247,6 +5270,10 @@ export interface GuildMembersChunk {
|
|||||||
nonce: string | undefined;
|
nonce: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NonPartialGroupDMChannel<Structure extends { channel: Channel }> = Structure & {
|
||||||
|
channel: Exclude<Structure['channel'], PartialGroupDMChannel>;
|
||||||
|
};
|
||||||
|
|
||||||
export interface ClientEvents {
|
export interface ClientEvents {
|
||||||
applicationCommandPermissionsUpdate: [data: ApplicationCommandPermissionsUpdateData];
|
applicationCommandPermissionsUpdate: [data: ApplicationCommandPermissionsUpdateData];
|
||||||
autoModerationActionExecution: [autoModerationActionExecution: AutoModerationActionExecution];
|
autoModerationActionExecution: [autoModerationActionExecution: AutoModerationActionExecution];
|
||||||
@@ -5289,17 +5316,17 @@ export interface ClientEvents {
|
|||||||
guildUpdate: [oldGuild: Guild, newGuild: Guild];
|
guildUpdate: [oldGuild: Guild, newGuild: Guild];
|
||||||
inviteCreate: [invite: Invite];
|
inviteCreate: [invite: Invite];
|
||||||
inviteDelete: [invite: Invite];
|
inviteDelete: [invite: Invite];
|
||||||
messageCreate: [message: Message];
|
messageCreate: [message: NonPartialGroupDMChannel<Message>];
|
||||||
messageDelete: [message: Message | PartialMessage];
|
messageDelete: [message: NonPartialGroupDMChannel<Message | PartialMessage>];
|
||||||
messagePollVoteAdd: [pollAnswer: PollAnswer, userId: Snowflake];
|
messagePollVoteAdd: [pollAnswer: PollAnswer, userId: Snowflake];
|
||||||
messagePollVoteRemove: [pollAnswer: PollAnswer, userId: Snowflake];
|
messagePollVoteRemove: [pollAnswer: PollAnswer, userId: Snowflake];
|
||||||
messageReactionRemoveAll: [
|
messageReactionRemoveAll: [
|
||||||
message: Message | PartialMessage,
|
message: NonPartialGroupDMChannel<Message | PartialMessage>,
|
||||||
reactions: ReadonlyCollection<string | Snowflake, MessageReaction>,
|
reactions: ReadonlyCollection<string | Snowflake, MessageReaction>,
|
||||||
];
|
];
|
||||||
messageReactionRemoveEmoji: [reaction: MessageReaction | PartialMessageReaction];
|
messageReactionRemoveEmoji: [reaction: MessageReaction | PartialMessageReaction];
|
||||||
messageDeleteBulk: [
|
messageDeleteBulk: [
|
||||||
messages: ReadonlyCollection<Snowflake, Message | PartialMessage>,
|
messages: ReadonlyCollection<Snowflake, NonPartialGroupDMChannel<Message | PartialMessage>>,
|
||||||
channel: GuildTextBasedChannel,
|
channel: GuildTextBasedChannel,
|
||||||
];
|
];
|
||||||
messageReactionAdd: [
|
messageReactionAdd: [
|
||||||
@@ -6221,6 +6248,16 @@ export interface IntegrationAccount {
|
|||||||
|
|
||||||
export type IntegrationType = 'twitch' | 'youtube' | 'discord' | 'guild_subscription';
|
export type IntegrationType = 'twitch' | 'youtube' | 'discord' | 'guild_subscription';
|
||||||
|
|
||||||
|
export type IntegrationTypesConfigurationParameters = ClientApplicationInstallParams;
|
||||||
|
|
||||||
|
export interface IntegrationTypesConfigurationContext {
|
||||||
|
oauth2InstallParams: IntegrationTypesConfigurationParameters | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IntegrationTypesConfiguration = Partial<
|
||||||
|
Record<ApplicationIntegrationType, IntegrationTypesConfigurationContext>
|
||||||
|
>;
|
||||||
|
|
||||||
export type CollectedInteraction<Cached extends CacheType = CacheType> =
|
export type CollectedInteraction<Cached extends CacheType = CacheType> =
|
||||||
| StringSelectMenuInteraction<Cached>
|
| StringSelectMenuInteraction<Cached>
|
||||||
| UserSelectMenuInteraction<Cached>
|
| UserSelectMenuInteraction<Cached>
|
||||||
@@ -6369,6 +6406,16 @@ export interface MessageComponentCollectorOptions<Interaction extends CollectedM
|
|||||||
export interface MessageChannelComponentCollectorOptions<Interaction extends CollectedMessageInteraction>
|
export interface MessageChannelComponentCollectorOptions<Interaction extends CollectedMessageInteraction>
|
||||||
extends Omit<InteractionCollectorOptions<Interaction>, 'channel' | 'guild' | 'interactionType'> {}
|
extends Omit<InteractionCollectorOptions<Interaction>, '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 {
|
export interface MessageInteraction {
|
||||||
id: Snowflake;
|
id: Snowflake;
|
||||||
type: InteractionType;
|
type: InteractionType;
|
||||||
@@ -6829,10 +6876,7 @@ export type Channel =
|
|||||||
| ForumChannel
|
| ForumChannel
|
||||||
| MediaChannel;
|
| MediaChannel;
|
||||||
|
|
||||||
export type TextBasedChannel = Exclude<
|
export type TextBasedChannel = Exclude<Extract<Channel, { type: TextChannelType }>, ForumChannel | MediaChannel>;
|
||||||
Extract<Channel, { type: TextChannelType }>,
|
|
||||||
PartialGroupDMChannel | ForumChannel | MediaChannel
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type TextBasedChannels = TextBasedChannel;
|
export type TextBasedChannels = TextBasedChannel;
|
||||||
|
|
||||||
|
|||||||
@@ -452,7 +452,7 @@ client.on('messageCreate', async message => {
|
|||||||
expectType<Collection<Snowflake, GuildMember>>(message.mentions.members);
|
expectType<Collection<Snowflake, GuildMember>>(message.mentions.members);
|
||||||
}
|
}
|
||||||
|
|
||||||
expectType<TextBasedChannel>(message.channel);
|
expectType<Exclude<TextBasedChannel, PartialGroupDMChannel>>(message.channel);
|
||||||
expectNotType<GuildTextBasedChannel>(message.channel);
|
expectNotType<GuildTextBasedChannel>(message.channel);
|
||||||
|
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
@@ -1624,7 +1624,7 @@ declare const guildChannelManager: GuildChannelManager;
|
|||||||
expectType<Promise<Collection<Snowflake, Message>>>(messages.fetchPinned());
|
expectType<Promise<Collection<Snowflake, Message>>>(messages.fetchPinned());
|
||||||
expectType<Guild | null>(message.guild);
|
expectType<Guild | null>(message.guild);
|
||||||
expectType<Snowflake | null>(message.guildId);
|
expectType<Snowflake | null>(message.guildId);
|
||||||
expectType<DMChannel | GuildTextBasedChannel>(message.channel.messages.channel);
|
expectType<DMChannel | PartialGroupDMChannel | GuildTextBasedChannel>(message.channel.messages.channel);
|
||||||
expectType<MessageMentions>(message.mentions);
|
expectType<MessageMentions>(message.mentions);
|
||||||
expectType<Guild | null>(message.mentions.guild);
|
expectType<Guild | null>(message.mentions.guild);
|
||||||
expectType<Collection<Snowflake, GuildMember> | null>(message.mentions.members);
|
expectType<Collection<Snowflake, GuildMember> | null>(message.mentions.members);
|
||||||
@@ -2209,6 +2209,7 @@ expectType<TextBasedChannel>(TextBasedChannel);
|
|||||||
expectType<
|
expectType<
|
||||||
| ChannelType.GuildText
|
| ChannelType.GuildText
|
||||||
| ChannelType.DM
|
| ChannelType.DM
|
||||||
|
| ChannelType.GroupDM
|
||||||
| ChannelType.GuildAnnouncement
|
| ChannelType.GuildAnnouncement
|
||||||
| ChannelType.GuildVoice
|
| ChannelType.GuildVoice
|
||||||
| ChannelType.GuildStageVoice
|
| ChannelType.GuildStageVoice
|
||||||
|
|||||||
Reference in New Issue
Block a user