feat(helpers,types)!: slash command localization (#2129)

* feat(helpers,types): slash command localization
Discord has documented the slash command localization feature now.
This adds the full functionality for those to Discordeno.

Additionally a `Locales` has also been added to allow for better typing.

Reference: https://github.com/discord/discord-api-docs/pull/4653

* suggestion

* better locales type

* f

* fix serializing

* stupid direct pushes

* b
This commit is contained in:
ITOH
2022-03-27 17:02:27 +02:00
committed by GitHub
parent 23ebfac286
commit 34a358f8bf
8 changed files with 134 additions and 21 deletions
@@ -1,5 +1,5 @@
import type { Bot } from "../../../bot.ts";
import { ApplicationCommandOption, ApplicationCommandTypes } from "../../../mod.ts";
import { ApplicationCommandOption, ApplicationCommandTypes, Localization } from "../../../mod.ts";
import { DiscordApplicationCommand, DiscordApplicationCommandOption } from "../../../types/discord.ts";
/**
@@ -24,12 +24,16 @@ export async function createApplicationCommand(
guildId
? bot.constants.endpoints.COMMANDS_GUILD(bot.applicationId, guildId)
: bot.constants.endpoints.COMMANDS(bot.applicationId),
isContextApplicationCommand(options) ? { name: options.name, type: options.type } : {
name: options.name,
description: options.description,
type: options.type,
options: options.options ? makeOptionsForCommand(options.options) : undefined,
},
isContextApplicationCommand(options)
? { name: options.name, name_localizations: options.nameLocalizations, type: options.type }
: {
name: options.name,
name_localizations: options.nameLocalizations,
description: options.description,
description_localizations: options.descriptionLocalizations,
type: options.type,
options: options.options ? makeOptionsForCommand(options.options) : undefined,
},
);
return bot.transformers.applicationCommand(bot, result);
@@ -39,9 +43,15 @@ export function makeOptionsForCommand(options: ApplicationCommandOption[]): Disc
return options.map((option) => ({
type: option.type,
name: option.name,
name_localizations: option.nameLocalizations,
description: option.description,
description_localizations: option.descriptionLocalizations,
required: option.required,
choices: option.choices,
choices: option.choices?.map((choice) => ({
name: choice.name,
name_localizations: choice.nameLocalizations,
value: choice.value,
})),
options: option.options ? makeOptionsForCommand(option.options) : undefined,
channel_types: option.channelTypes,
autocomplete: option.autocomplete,
@@ -50,12 +60,16 @@ export function makeOptionsForCommand(options: ApplicationCommandOption[]): Disc
}));
}
/** https://discord.com/developers/docs/interactions/slash-commands#create-global-application-command-json-params */
/** https://discord.com/developers/docs/interactions/application-commands#endpoints-json-params */
export interface CreateApplicationCommand {
/** 1-31 character name matching lowercase `^[\w-]{1,32}$` */
name: string;
/** Localization object for the `name` field. Values follow the same restrictions as `name` */
nameLocalizations?: Localization;
/** 1-100 character description */
description: string;
/** Localization object for the `description` field. Values follow the same restrictions as `description` */
descriptionLocalizations?: Localization;
/** The type of the command */
type?: ApplicationCommandTypes;
/** The parameters for the command */
@@ -64,10 +78,12 @@ export interface CreateApplicationCommand {
defaultPermission?: boolean;
}
/** https://discord.com/developers/docs/interactions/slash-commands#create-global-application-command-json-params */
/** https://discord.com/developers/docs/interactions/application-commands#endpoints-json-params */
export interface CreateContextApplicationCommand {
/** 1-31 character name matching lowercase `^[\w-]{1,32}$` */
name: string;
/** Localization object for the `name` field. Values follow the same restrictions as `name` */
nameLocalizations?: Localization;
/** The type of the command */
type: ApplicationCommandTypes.Message | ApplicationCommandTypes.User;
}
@@ -2,14 +2,30 @@ import type { Bot } from "../../../bot.ts";
import { DiscordApplicationCommand } from "../../../types/discord.ts";
/** Fetches the global command for the given Id. If a guildId is provided, the guild command will be fetched. */
export async function getApplicationCommand(bot: Bot, commandId: bigint, guildId?: bigint) {
export async function getApplicationCommand(bot: Bot, commandId: bigint, options?: GetApplicationCommand) {
let url = `${
options?.guildId
? bot.constants.endpoints.COMMANDS_GUILD_ID(bot.applicationId, options.guildId, commandId)
: bot.constants.endpoints.COMMANDS_ID(bot.applicationId, commandId)
}?`;
if (options?.withLocalizations !== undefined) {
url += `with_localizations=${options.withLocalizations}`;
}
const result = await bot.rest.runMethod<DiscordApplicationCommand>(
bot.rest,
"get",
guildId
? bot.constants.endpoints.COMMANDS_GUILD_ID(bot.applicationId, guildId, commandId)
: bot.constants.endpoints.COMMANDS_ID(bot.applicationId, commandId),
url,
);
return bot.transformers.applicationCommand(bot, result);
}
/** https://discord.com/developers/docs/interactions/application-commands#endpoints-query-string-params */
export interface GetApplicationCommand {
/** Guild ID of the guild in which the command is available if it is a guild-specific command */
guildId?: bigint;
/** Whether to include full localization object (`name_localizations` and `description_localizations`) in the returned objects, instead of the `name_localized` and `description_localized` fields. Default false */
withLocalizations?: boolean;
}