mirror of
https://github.com/discordeno/discordeno.git
synced 2026-09-17 08:47:22 +00:00
feat(bot,rest,types,utils): Support User-Installed apps, Interaction contexts and install types (#3502)
* Support integrationTypesConfig in Application * Add support for commands with integrationTypes and contexts And deprecate the dmPermission boolean, it is being replaced by contexts * Update contexts comment to make it more clear * User-Installed apps * Add integrationType oauth parameter fixes #3517 * Add null to contexts closes #3523 * Mark oauth2 install params as nullable closes #3525 * Fix typescript errors * Add preview notices --------- Co-authored-by: Matt Hatcher <3768988+MatthewSH@users.noreply.github.com>
This commit is contained in:
@@ -31,6 +31,7 @@ import type {
|
||||
DiscordInviteStageInstance,
|
||||
DiscordMember,
|
||||
DiscordMessage,
|
||||
DiscordMessageInteractionMetadata,
|
||||
DiscordPoll,
|
||||
DiscordPollMedia,
|
||||
DiscordPresenceUpdate,
|
||||
@@ -85,7 +86,7 @@ import { transformIntegration, type Integration } from './transformers/integrati
|
||||
import { transformInteraction, transformInteractionDataOption, type Interaction, type InteractionDataOption } from './transformers/interaction.js'
|
||||
import { transformInvite, type Invite } from './transformers/invite.js'
|
||||
import { transformMember, type Member } from './transformers/member.js'
|
||||
import { transformMessage, type Message } from './transformers/message.js'
|
||||
import { transformMessage, type Message, type MessageInteractionMetadata, transformMessageInteractionMetadata } from './transformers/message.js'
|
||||
import { transformGuildOnboarding, type GuildOnboarding } from './transformers/onboarding.js'
|
||||
import { transformPoll, transformPollMedia, type Poll, type PollMedia } from './transformers/poll.js'
|
||||
import { transformPresence, type PresenceUpdate } from './transformers/presence.js'
|
||||
@@ -120,6 +121,7 @@ export interface Transformers {
|
||||
channel: (bot: Bot, payload: DiscordChannel, channel: Channel) => any
|
||||
interaction: (bot: Bot, payload: DiscordInteraction, interaction: Interaction) => any
|
||||
message: (bot: Bot, payload: DiscordMessage, message: Message) => any
|
||||
messageInteractionMetadata: (bot: Bot, payload: DiscordMessageInteractionMetadata, metadata: MessageInteractionMetadata) => any
|
||||
user: (bot: Bot, payload: DiscordUser, user: User) => any
|
||||
member: (bot: Bot, payload: DiscordMember, member: Member) => any
|
||||
role: (bot: Bot, payload: DiscordRole, role: Role) => any
|
||||
@@ -297,6 +299,8 @@ export interface Transformers {
|
||||
locale: boolean
|
||||
guildLocale: boolean
|
||||
appPermissions: boolean
|
||||
authorizingIntegrationOwners: boolean
|
||||
context: boolean
|
||||
}
|
||||
invite: {
|
||||
channelId: boolean
|
||||
@@ -345,6 +349,15 @@ export interface Transformers {
|
||||
embeds: boolean
|
||||
guildId: boolean
|
||||
id: boolean
|
||||
interactionMetadata: {
|
||||
id: boolean
|
||||
type: boolean
|
||||
userId: boolean
|
||||
authorizingIntegrationOwners: boolean
|
||||
originalResponseMessageId: boolean
|
||||
interactedMessageId: boolean
|
||||
triggeringInteractionMetadata: boolean
|
||||
}
|
||||
interaction: {
|
||||
id: boolean
|
||||
member: boolean
|
||||
@@ -560,6 +573,7 @@ export interface Transformers {
|
||||
user: (bot: Bot, payload: DiscordUser) => User
|
||||
member: (bot: Bot, payload: DiscordMember, guildId: BigString, userId: BigString) => Member
|
||||
message: (bot: Bot, payload: DiscordMessage) => Message
|
||||
messageInteractionMetadata: (bot: Bot, payload: DiscordMessageInteractionMetadata) => MessageInteractionMetadata
|
||||
role: (bot: Bot, payload: { role: DiscordRole } & { guildId: BigString }) => Role
|
||||
voiceState: (bot: Bot, payload: { voiceState: DiscordVoiceState } & { guildId: bigint }) => VoiceState
|
||||
interaction: (bot: Bot, payload: DiscordInteraction) => Interaction
|
||||
@@ -631,6 +645,9 @@ export function createTransformers(options: Partial<Transformers>, opts?: Create
|
||||
message(bot, payload, message) {
|
||||
return message
|
||||
},
|
||||
messageInteractionMetadata(bot, payload, metadata) {
|
||||
return metadata
|
||||
},
|
||||
role(bot, payload, role) {
|
||||
return role
|
||||
},
|
||||
@@ -881,6 +898,8 @@ export function createTransformers(options: Partial<Transformers>, opts?: Create
|
||||
locale: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
guildLocale: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
appPermissions: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
authorizingIntegrationOwners: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
context: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
},
|
||||
invite: {
|
||||
channelId: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
@@ -929,6 +948,15 @@ export function createTransformers(options: Partial<Transformers>, opts?: Create
|
||||
embeds: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
guildId: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
id: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
interactionMetadata: {
|
||||
id: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
type: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
userId: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
authorizingIntegrationOwners: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
originalResponseMessageId: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
interactedMessageId: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
triggeringInteractionMetadata: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
},
|
||||
interaction: {
|
||||
id: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
member: opts?.defaultDesiredPropertiesValue ?? false,
|
||||
@@ -1152,6 +1180,7 @@ export function createTransformers(options: Partial<Transformers>, opts?: Create
|
||||
invite: options.invite ?? transformInvite,
|
||||
member: options.member ?? transformMember,
|
||||
message: options.message ?? transformMessage,
|
||||
messageInteractionMetadata: options.messageInteractionMetadata ?? transformMessageInteractionMetadata,
|
||||
presence: options.presence ?? transformPresence,
|
||||
role: options.role ?? transformRole,
|
||||
user: options.user ?? transformUser,
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import {
|
||||
DiscordApplicationIntegrationType,
|
||||
iconHashToBigInt,
|
||||
type ApplicationFlags,
|
||||
type Bot,
|
||||
type DiscordApplication,
|
||||
type DiscordUser,
|
||||
type Guild,
|
||||
type OAuth2Scope,
|
||||
type Team,
|
||||
type User,
|
||||
} from '../index.js'
|
||||
@@ -38,6 +40,26 @@ export function transformApplication(bot: Bot, payload: { application: DiscordAp
|
||||
bot: payload.application.bot ? bot.transformers.user(bot, payload.application.bot as DiscordUser) : undefined,
|
||||
interactionsEndpointUrl: payload.application.interactions_endpoint_url,
|
||||
redirectUris: payload.application.redirect_uris,
|
||||
integrationTypesConfig: payload.application.integration_types_config
|
||||
? {
|
||||
[DiscordApplicationIntegrationType.GuildInstall]: payload.application.integration_types_config['0']?.oauth2_install_params
|
||||
? {
|
||||
oauth2InstallParams: {
|
||||
scopes: payload.application.integration_types_config['0'].oauth2_install_params.scopes,
|
||||
permissions: bot.transformers.snowflake(payload.application.integration_types_config['0'].oauth2_install_params.permissions),
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
[DiscordApplicationIntegrationType.UserInstall]: payload.application.integration_types_config['1']?.oauth2_install_params
|
||||
? {
|
||||
oauth2InstallParams: {
|
||||
scopes: payload.application.integration_types_config['1'].oauth2_install_params.scopes,
|
||||
permissions: bot.transformers.snowflake(payload.application.integration_types_config['1'].oauth2_install_params.permissions),
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
}
|
||||
: undefined,
|
||||
} as Application
|
||||
|
||||
return bot.transformers.customizers.application(bot, payload.application, application)
|
||||
@@ -66,4 +88,15 @@ export interface Application {
|
||||
bot?: User
|
||||
redirectUris?: string[]
|
||||
interactionsEndpointUrl?: string
|
||||
integrationTypesConfig?: Partial<Record<DiscordApplicationIntegrationType, ApplicationIntegrationTypeConfiguration>>
|
||||
}
|
||||
|
||||
export interface ApplicationIntegrationTypeConfiguration {
|
||||
/** Install params for each installation context's default in-app authorization link */
|
||||
oauth2InstallParams?: {
|
||||
/** Scopes to add the application to the server with */
|
||||
scopes: OAuth2Scope[]
|
||||
/** Permissions to request for the bot role */
|
||||
permissions: bigint
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,14 @@ import {
|
||||
type MessageComponentTypes,
|
||||
} from '@discordeno/types'
|
||||
import { Collection } from '@discordeno/utils'
|
||||
import type { Bot, Channel, Component, DiscordChannel } from '../index.js'
|
||||
import {
|
||||
type Bot,
|
||||
type Channel,
|
||||
type Component,
|
||||
DiscordApplicationIntegrationType,
|
||||
type DiscordChannel,
|
||||
type DiscordInteractionContextType,
|
||||
} from '../index.js'
|
||||
import { MessageFlags, type DiscordInteractionDataResolved } from '../typings.js'
|
||||
import type { Attachment } from './attachment.js'
|
||||
import type { Member } from './member.js'
|
||||
@@ -71,6 +78,10 @@ export interface Interaction extends BaseInteraction {
|
||||
guildLocale?: string
|
||||
/** The computed permissions for a bot or app in the context of a specific interaction (including channel overwrites) */
|
||||
appPermissions: bigint
|
||||
/** Mapping of installation contexts that the interaction was authorized for to related user or guild IDs. */
|
||||
authorizingIntegrationOwners: Partial<Record<DiscordApplicationIntegrationType, bigint>>
|
||||
/** Context where the interaction was triggered from */
|
||||
context?: DiscordInteractionContextType
|
||||
}
|
||||
|
||||
export interface BaseInteraction {
|
||||
@@ -232,6 +243,19 @@ export function transformInteraction(bot: Bot, payload: DiscordInteraction): Int
|
||||
if (props.channel && payload.channel) interaction.channel = bot.transformers.channel(bot, { channel: payload.channel as DiscordChannel, guildId })
|
||||
if (props.channelId && payload.channel_id) interaction.channelId = bot.transformers.snowflake(payload.channel_id)
|
||||
if (props.member && guildId && payload.member) interaction.member = bot.transformers.member(bot, payload.member, guildId, user.id)
|
||||
if (props.authorizingIntegrationOwners && payload.authorizing_integration_owners) {
|
||||
interaction.authorizingIntegrationOwners = {}
|
||||
|
||||
if (payload.authorizing_integration_owners['0'])
|
||||
interaction.authorizingIntegrationOwners[DiscordApplicationIntegrationType.GuildInstall] = bot.transformers.snowflake(
|
||||
payload.authorizing_integration_owners['0'],
|
||||
)
|
||||
if (payload.authorizing_integration_owners['1'])
|
||||
interaction.authorizingIntegrationOwners[DiscordApplicationIntegrationType.UserInstall] = bot.transformers.snowflake(
|
||||
payload.authorizing_integration_owners['1'],
|
||||
)
|
||||
}
|
||||
if (props.context && payload.context) interaction.context = payload.context
|
||||
if (props.data && payload.data) {
|
||||
interaction.data = {
|
||||
type: payload.data.type,
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
import type { DiscordMessage, InteractionTypes, MessageActivityTypes, MessageTypes, StickerFormatTypes } from '@discordeno/types'
|
||||
import {
|
||||
DiscordApplicationIntegrationType,
|
||||
type DiscordMessage,
|
||||
type DiscordMessageInteractionMetadata,
|
||||
type InteractionTypes,
|
||||
type MessageActivityTypes,
|
||||
type MessageTypes,
|
||||
type StickerFormatTypes,
|
||||
} from '@discordeno/types'
|
||||
import { CHANNEL_MENTION_REGEX } from '../constants.js'
|
||||
import { snowflakeToTimestamp, type Bot } from '../index.js'
|
||||
import { MessageFlags } from '../typings.js'
|
||||
@@ -189,7 +197,13 @@ export interface Message extends MessageBase {
|
||||
guildId?: bigint
|
||||
/** id of the message */
|
||||
id: bigint
|
||||
/** Sent if the message is a response to an Interaction */
|
||||
/** sent if the message is sent as a result of an interaction */
|
||||
interactionMetadata?: MessageInteractionMetadata
|
||||
/**
|
||||
* Sent if the message is a response to an Interaction
|
||||
*
|
||||
* @deprecated Deprecated in favor of {@link interactionMetadata}
|
||||
*/
|
||||
interaction?: {
|
||||
/** Id of the interaction */
|
||||
id: bigint
|
||||
@@ -281,6 +295,7 @@ export function transformMessage(bot: Bot, payload: DiscordMessage): Message {
|
||||
if (props.embeds && payload.embeds?.length) message.embeds = payload.embeds.map((embed) => bot.transformers.embed(bot, embed))
|
||||
if (props.guildId && guildId) message.guildId = guildId
|
||||
if (props.id && payload.id) message.id = bot.transformers.snowflake(payload.id)
|
||||
if (payload.interaction_metadata) message.interactionMetadata = transformMessageInteractionMetadata(bot, payload.interaction_metadata)
|
||||
if (payload.interaction) {
|
||||
const interaction = {} as NonNullable<Message['interaction']>
|
||||
let edited = false
|
||||
@@ -371,3 +386,48 @@ export function transformMessage(bot: Bot, payload: DiscordMessage): Message {
|
||||
|
||||
return bot.transformers.customizers.message(bot, payload, message)
|
||||
}
|
||||
|
||||
export function transformMessageInteractionMetadata(bot: Bot, payload: DiscordMessageInteractionMetadata): MessageInteractionMetadata {
|
||||
const props = bot.transformers.desiredProperties.message.interactionMetadata
|
||||
const metadata = {} as MessageInteractionMetadata
|
||||
|
||||
if (props.id) metadata.id = bot.transformers.snowflake(payload.id)
|
||||
if (props.authorizingIntegrationOwners) {
|
||||
metadata.authorizingIntegrationOwners = {}
|
||||
if (payload.authorizing_integration_owners['0'])
|
||||
metadata.authorizingIntegrationOwners[DiscordApplicationIntegrationType.GuildInstall] = bot.transformers.snowflake(
|
||||
payload.authorizing_integration_owners['0'],
|
||||
)
|
||||
if (payload.authorizing_integration_owners['1'])
|
||||
metadata.authorizingIntegrationOwners[DiscordApplicationIntegrationType.UserInstall] = bot.transformers.snowflake(
|
||||
payload.authorizing_integration_owners['1'],
|
||||
)
|
||||
}
|
||||
if (props.interactedMessageId && payload.interacted_message_id)
|
||||
metadata.interactedMessageId = bot.transformers.snowflake(payload.interacted_message_id)
|
||||
if (props.originalResponseMessageId && payload.original_response_message_id)
|
||||
metadata.originalResponseMessageId = bot.transformers.snowflake(payload.original_response_message_id)
|
||||
if (props.triggeringInteractionMetadata && payload.triggering_interaction_metadata)
|
||||
metadata.triggeringInteractionMetadata = transformMessageInteractionMetadata(bot, payload.triggering_interaction_metadata)
|
||||
if (props.type) metadata.type = payload.type
|
||||
if (props.userId) metadata.userId = bot.transformers.snowflake(payload.user_id)
|
||||
|
||||
return bot.transformers.customizers.messageInteractionMetadata(bot, payload, metadata)
|
||||
}
|
||||
|
||||
export interface MessageInteractionMetadata {
|
||||
/** Id of the interaction */
|
||||
id: bigint
|
||||
/** The type of interaction */
|
||||
type: InteractionTypes
|
||||
/** ID of the user who triggered the interaction */
|
||||
userId: bigint
|
||||
/** IDs for installation context(s) related to an interaction */
|
||||
authorizingIntegrationOwners: Partial<Record<DiscordApplicationIntegrationType, bigint>>
|
||||
/** ID of the original response message, present only on follow-up messages */
|
||||
originalResponseMessageId?: bigint
|
||||
/** ID of the message that contained interactive component, present only on messages created from component interactions */
|
||||
interactedMessageId?: bigint
|
||||
/** Metadata for the interaction that was used to open the modal, present only on modal submit interactions */
|
||||
triggeringInteractionMetadata?: MessageInteractionMetadata
|
||||
}
|
||||
|
||||
@@ -974,7 +974,7 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
|
||||
},
|
||||
|
||||
async editApplicationInfo(body) {
|
||||
return await rest.patch<DiscordApplication>(rest.routes.oauth2.application(), {
|
||||
return await rest.patch<DiscordApplication>(rest.routes.application(), {
|
||||
body,
|
||||
})
|
||||
},
|
||||
|
||||
@@ -628,6 +628,10 @@ export function createRoutes(): RestRoutes {
|
||||
return `/users/${userId}`
|
||||
},
|
||||
|
||||
application() {
|
||||
return '/applications/@me'
|
||||
},
|
||||
|
||||
currentUser() {
|
||||
return '/users/@me'
|
||||
},
|
||||
|
||||
@@ -255,7 +255,7 @@ export interface RestRoutes {
|
||||
tokenRevoke: () => string
|
||||
/** Route to get information about the current authorization. Requires an access token */
|
||||
currentAuthorization: () => string
|
||||
/** Route to get information about the current application. Requires an access token */
|
||||
/** Route to get information about the current application. */
|
||||
application: () => string
|
||||
/** Route to get the connection the user has. Requires the `connections` OAuth2 scope */
|
||||
connections: () => string
|
||||
@@ -273,6 +273,8 @@ export interface RestRoutes {
|
||||
}
|
||||
/** Get information about the current OAuth2 user / bot user. If used with a OAuth2 token requires the `identify` OAuth2 scope */
|
||||
currentUser: () => string
|
||||
/** Route to get and edit information about the current application. */
|
||||
application: () => string
|
||||
/** Route for handling a sticker. */
|
||||
sticker: (stickerId: BigString) => string
|
||||
/** Route for handling all voice regions. */
|
||||
|
||||
@@ -15,6 +15,7 @@ import type {
|
||||
DiscordApplicationCommandOption,
|
||||
DiscordApplicationCommandOptionChoice,
|
||||
DiscordApplicationCommandPermissions,
|
||||
DiscordApplicationIntegrationTypeConfiguration,
|
||||
DiscordApplicationRoleConnection,
|
||||
DiscordApplicationWebhook,
|
||||
DiscordArchivedThreads,
|
||||
@@ -180,6 +181,7 @@ export interface CamelizedDiscordGuildIntegrationsUpdate extends Camelize<Discor
|
||||
export interface CamelizedDiscordTypingStart extends Camelize<DiscordTypingStart> {}
|
||||
export interface CamelizedDiscordMember extends Camelize<DiscordMember> {}
|
||||
export interface CamelizedDiscordApplication extends Camelize<DiscordApplication> {}
|
||||
export interface CamelizedDiscordApplicationIntegrationTypeConfiguration extends Camelize<DiscordApplicationIntegrationTypeConfiguration> {}
|
||||
export interface CamelizedDiscordApplicationRoleConnection extends Camelize<DiscordApplicationRoleConnection> {}
|
||||
export type CamelizedDiscordTokenExchange = Camelize<DiscordTokenExchange>
|
||||
export interface CamelizedDiscordTokenExchangeAuthorizationCode extends Camelize<DiscordTokenExchangeAuthorizationCode> {}
|
||||
|
||||
@@ -373,6 +373,13 @@ export interface DiscordApplication {
|
||||
tags?: string[]
|
||||
/** settings for the application's default in-app authorization link, if enabled */
|
||||
install_params?: DiscordInstallParams
|
||||
/**
|
||||
* Default scopes and permissions for each supported installation context.
|
||||
*
|
||||
* @remarks
|
||||
* This is currently in preview.
|
||||
*/
|
||||
integration_types_config?: Partial<Record<`${DiscordApplicationIntegrationType}`, DiscordApplicationIntegrationTypeConfiguration>>
|
||||
/** the application's default custom authorization link, if enabled */
|
||||
custom_install_url?: string
|
||||
/** the application's role connection verification entry point, which when configured will render the app as a verification method in the guild role verification configuration */
|
||||
@@ -387,6 +394,28 @@ export interface DiscordApplication {
|
||||
interactions_endpoint_url?: string
|
||||
}
|
||||
|
||||
/** https://discord.com/developers/docs/resources/application#application-object-application-integration-type-configuration-object */
|
||||
export interface DiscordApplicationIntegrationTypeConfiguration {
|
||||
/**
|
||||
* Install params for each installation context's default in-app authorization link
|
||||
*
|
||||
* https://discord.com/developers/docs/resources/application#install-params-object-install-params-structure
|
||||
*/
|
||||
oauth2_install_params?: {
|
||||
/** Scopes to add the application to the server with */
|
||||
scopes: OAuth2Scope[]
|
||||
/** Permissions to request for the bot role */
|
||||
permissions: string
|
||||
}
|
||||
}
|
||||
|
||||
export enum DiscordApplicationIntegrationType {
|
||||
/** App is installable to servers */
|
||||
GuildInstall = 0,
|
||||
/** App is installable to users */
|
||||
UserInstall = 1,
|
||||
}
|
||||
|
||||
export type DiscordTokenExchange = DiscordTokenExchangeAuthorizationCode | DiscordTokenExchangeRefreshToken | DiscordTokenExchangeClientCredentials
|
||||
|
||||
export interface DiscordTokenExchangeAuthorizationCode {
|
||||
@@ -1321,7 +1350,13 @@ export interface DiscordMessage {
|
||||
* Note: This field is only returned for messages with a `type` of `19` (REPLY). If the message is a reply but the `referenced_message` field is not present, the backend did not attempt to fetch the message that was being replied to, so its state is unknown. If the field exists but is null, the referenced message was deleted.
|
||||
*/
|
||||
referenced_message?: DiscordMessage
|
||||
/** Sent if the message is a response to an Interaction */
|
||||
/** sent if the message is sent as a result of an interaction */
|
||||
interaction_metadata?: DiscordMessageInteractionMetadata
|
||||
/**
|
||||
* Sent if the message is a response to an Interaction
|
||||
*
|
||||
* @deprecated Deprecated in favor of {@link interaction_metadata}
|
||||
*/
|
||||
interaction?: DiscordMessageInteraction
|
||||
/** The thread that was started from this message, includes thread member object */
|
||||
thread?: Omit<DiscordChannel, 'member'> & { member: DiscordThreadMember }
|
||||
@@ -1550,6 +1585,24 @@ export interface DiscordMessageInteraction {
|
||||
member?: Partial<DiscordMember>
|
||||
}
|
||||
|
||||
/** https://discord.com/developers/docs/resources/channel#message-interaction-metadata-object-message-interaction-metadata-structure */
|
||||
export interface DiscordMessageInteractionMetadata {
|
||||
/** Id of the interaction */
|
||||
id: string
|
||||
/** The type of interaction */
|
||||
type: InteractionTypes
|
||||
/** ID of the user who triggered the interaction */
|
||||
user_id: string
|
||||
/** IDs for installation context(s) related to an interaction */
|
||||
authorizing_integration_owners: Partial<Record<DiscordApplicationIntegrationType, string>>
|
||||
/** ID of the original response message, present only on follow-up messages */
|
||||
original_response_message_id?: string
|
||||
/** ID of the message that contained interactive component, present only on messages created from component interactions */
|
||||
interacted_message_id?: string
|
||||
/** Metadata for the interaction that was used to open the modal, present only on modal submit interactions */
|
||||
triggering_interaction_metadata?: DiscordMessageInteractionMetadata
|
||||
}
|
||||
|
||||
export type DiscordMessageComponents = DiscordActionRow[]
|
||||
|
||||
/** https://discord.com/developers/docs/interactions/message-components#actionrow */
|
||||
@@ -1718,6 +1771,10 @@ export interface DiscordInteraction {
|
||||
app_permissions: string
|
||||
/** For monetized apps, any entitlements for the invoking user, representing access to premium SKUs */
|
||||
entitlements: DiscordEntitlement[]
|
||||
/** Mapping of installation contexts that the interaction was authorized for to related user or guild IDs. */
|
||||
authorizing_integration_owners: Partial<Record<DiscordApplicationIntegrationType, string>>
|
||||
/** Context where the interaction was triggered from */
|
||||
context?: DiscordInteractionContextType
|
||||
}
|
||||
|
||||
/** https://discord.com/developers/docs/resources/guild#guild-member-object */
|
||||
@@ -2272,7 +2329,25 @@ export interface DiscordCreateApplicationCommand {
|
||||
options?: DiscordApplicationCommandOption[]
|
||||
/** Set of permissions represented as a bit set */
|
||||
default_member_permissions?: string | null
|
||||
/** Indicates whether the command is available in DMs with the app, only for globally-scoped commands. By default, commands are visible. */
|
||||
/**
|
||||
* Installation context(s) where the command is available
|
||||
*
|
||||
* @remarks
|
||||
* This is currently in preview.
|
||||
*/
|
||||
integration_types?: DiscordApplicationIntegrationType[]
|
||||
/**
|
||||
* Interaction context(s) where the command can be used, only for globally-scoped commands. By default, all interaction context types included.
|
||||
*
|
||||
* @remarks
|
||||
* This is currently in preview.
|
||||
*/
|
||||
contexts?: DiscordInteractionContextType[] | null
|
||||
/**
|
||||
* Indicates whether the command is available in DMs with the app, only for globally-scoped commands. By default, commands are visible.
|
||||
*
|
||||
* @deprecated use {@link contexts} instead
|
||||
*/
|
||||
dm_permission?: boolean
|
||||
/** Indicates whether the command is age-restricted, defaults to false */
|
||||
nsfw?: boolean
|
||||
@@ -3248,6 +3323,16 @@ export enum DiscordMessageFlag {
|
||||
IsVoiceMessage = 1 << 13,
|
||||
}
|
||||
|
||||
/** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-interaction-context-types */
|
||||
export enum DiscordInteractionContextType {
|
||||
/** Interaction can be used within servers */
|
||||
Guild = 0,
|
||||
/** Interaction can be used within DMs with the app's bot user */
|
||||
BotDm = 1,
|
||||
/** Interaction can be used within Group DMs and DMs other than the app's bot user */
|
||||
PrivateChannel = 2,
|
||||
}
|
||||
|
||||
/** https://discord.com/developers/docs/resources/guild#bulk-guild-ban */
|
||||
export interface DiscordBulkBan {
|
||||
/** list of user ids, that were successfully banned */
|
||||
|
||||
@@ -4,6 +4,7 @@ import type {
|
||||
AutoModerationTriggerTypes,
|
||||
DiscordApplicationCommandOption,
|
||||
DiscordApplicationCommandOptionChoice,
|
||||
DiscordApplicationIntegrationType,
|
||||
DiscordAttachment,
|
||||
DiscordAutoModerationRuleTriggerMetadataPresets,
|
||||
DiscordChannel,
|
||||
@@ -11,6 +12,7 @@ import type {
|
||||
DiscordGuildOnboardingMode,
|
||||
DiscordGuildOnboardingPrompt,
|
||||
DiscordInstallParams,
|
||||
DiscordInteractionContextType,
|
||||
DiscordMessageFlag,
|
||||
DiscordPollAnswer,
|
||||
DiscordPollLayoutType,
|
||||
@@ -459,7 +461,15 @@ export interface CreateSlashApplicationCommand {
|
||||
options?: Camelize<DiscordApplicationCommandOption[]>
|
||||
/** Set of permissions represented as a bit set */
|
||||
defaultMemberPermissions?: PermissionStrings[]
|
||||
/** Indicates whether the command is available in DMs with the app, only for globally-scoped commands. By default, commands are visible. */
|
||||
/** Installation context(s) where the command is available */
|
||||
integrationTypes?: DiscordApplicationIntegrationType[]
|
||||
/** Interaction context(s) where the command can be used, only for globally-scoped commands. By default, all interaction context types included for new commands. */
|
||||
contexts?: DiscordInteractionContextType[]
|
||||
/**
|
||||
* Indicates whether the command is available in DMs with the app, only for globally-scoped commands. By default, commands are visible.
|
||||
*
|
||||
* @deprecated use {@link contexts} instead
|
||||
*/
|
||||
dmPermission?: boolean
|
||||
/** Indicates whether the command is age-restricted, defaults to `false` */
|
||||
nsfw?: boolean
|
||||
@@ -1294,6 +1304,13 @@ export interface EditApplication {
|
||||
roleConnectionsVerificationUrl?: string
|
||||
/** Settings for the app's default in-app authorization link, if enabled */
|
||||
installParams?: DiscordInstallParams
|
||||
/**
|
||||
* Default scopes and permissions for each supported installation context.
|
||||
*
|
||||
* @remarks
|
||||
* This is currently in preview.
|
||||
*/
|
||||
integrationTypesConfig?: DiscordApplicationIntegrationType
|
||||
/**
|
||||
* App's public flags
|
||||
*
|
||||
|
||||
@@ -1038,7 +1038,7 @@ export type Localization = Partial<Record<Locales, string>>
|
||||
|
||||
export type AtLeastOne<T, U = { [K in keyof T]: Pick<T, K> }> = Partial<T> & U[keyof U]
|
||||
export type CamelCase<S extends string> = S extends `${infer T}_${infer U}` ? `${T}${Capitalize<CamelCase<U>>}` : S
|
||||
export type SnakeCase<S extends string> = S extends `${infer T}${infer U}` ? `${T extends Capitalize<T> ? '_' : ''}${Lowercase<T>}${SnakeCase<U>}` : S
|
||||
export type SnakeCase<S extends string> = S extends `${infer T}${infer U}` ? `${T extends Lowercase<T> ? '' : '_'}${Lowercase<T>}${SnakeCase<U>}` : S
|
||||
|
||||
export type Camelize<T> = T extends any[]
|
||||
? T extends Array<Record<any, any>>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { BigString, OAuth2Scope, PermissionStrings } from '@discordeno/types'
|
||||
import type { BigString, DiscordApplicationIntegrationType, OAuth2Scope, PermissionStrings } from '@discordeno/types'
|
||||
import { calculateBits } from './permissions.js'
|
||||
|
||||
export function createOAuth2Link(options: CreateOAuth2LinkOptions): string {
|
||||
@@ -12,8 +12,8 @@ export function createOAuth2Link(options: CreateOAuth2LinkOptions): string {
|
||||
if (options.prompt) url += `&prompt=${options.prompt}`
|
||||
if (options.permissions) url += `&permissions=${Array.isArray(options.permissions) ? calculateBits(options.permissions) : options.permissions}`
|
||||
if (options.guildId) url += `&guild_id=${options.guildId}`
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
if (options.disableGuildSelect !== undefined) url += `&disable_guild_select=${options.disableGuildSelect}`
|
||||
if (options.integrationType) url += `&integration_type=${options.integrationType}`
|
||||
|
||||
return url
|
||||
}
|
||||
@@ -72,4 +72,15 @@ export interface CreateOAuth2LinkOptions {
|
||||
* Should be defined only in a [bot authorization flow](https://discord.com/developers/docs/topics/oauth2#bot-authorization-flow), with [advanced bot authorization](https://discord.com/developers/docs/topics/oauth2#advanced-bot-authorization) or with the `webhook.incoming` scope
|
||||
*/
|
||||
disableGuildSelect?: boolean
|
||||
/**
|
||||
* Specifies the installation context for the authorization
|
||||
*
|
||||
* @remarks
|
||||
* Should be defined only when {@link scopes} includes {@link OAuth2Scope.ApplicationsCommands}.
|
||||
*
|
||||
* When set to GuildInstall (0) the application will be authorized for installation to a server, and when set to UserInstall (1) the application will be authorized for installation to a user.
|
||||
*
|
||||
* The application must be configured in the Developer Portal to support the provided `integrationType`.
|
||||
*/
|
||||
integrationType?: DiscordApplicationIntegrationType
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user