diff --git a/src/helpers/messages/edit_message.ts b/src/helpers/messages/edit_message.ts index 637133b08..a74dd1aec 100644 --- a/src/helpers/messages/edit_message.ts +++ b/src/helpers/messages/edit_message.ts @@ -2,12 +2,13 @@ import { botId } from "../../bot.ts"; import { rest } from "../../rest/rest.ts"; import { DiscordenoMessage } from "../../structures/message.ts"; import { structures } from "../../structures/mod.ts"; +import { Errors } from "../../types/discordeno/errors.ts"; import { EditMessage } from "../../types/messages/edit_message.ts"; import type { Message } from "../../types/messages/message.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; import type { PermissionStrings } from "../../types/permissions/permission_strings.ts"; import { endpoints } from "../../util/constants.ts"; import { requireBotChannelPermissions } from "../../util/permissions.ts"; +import { validateComponents } from "../../util/utils.ts"; /** Edit the message. */ export async function editMessage( @@ -20,6 +21,10 @@ export async function editMessage( if (typeof content === "string") content = { content }; + if (content.components?.length) { + validateComponents(content.components); + } + const requiredPerms: PermissionStrings[] = ["SEND_MESSAGES"]; await requireBotChannelPermissions(message.channelId, requiredPerms); diff --git a/src/helpers/messages/send_message.ts b/src/helpers/messages/send_message.ts index 6f21f6912..9840e78e8 100644 --- a/src/helpers/messages/send_message.ts +++ b/src/helpers/messages/send_message.ts @@ -4,16 +4,13 @@ import { structures } from "../../structures/mod.ts"; import { DiscordChannelTypes } from "../../types/channels/channel_types.ts"; import { Errors } from "../../types/discordeno/errors.ts"; import { DiscordAllowedMentionsTypes } from "../../types/messages/allowed_mentions_types.ts"; -import { ButtonStyles } from "../../types/messages/components/button_styles.ts"; import type { CreateMessage } from "../../types/messages/create_message.ts"; import type { Message } from "../../types/messages/message.ts"; import type { PermissionStrings } from "../../types/permissions/permission_strings.ts"; import { endpoints } from "../../util/constants.ts"; import { requireBotChannelPermissions } from "../../util/permissions.ts"; -import { snakelize } from "../../util/utils.ts"; +import { snakelize, validateComponents } from "../../util/utils.ts"; import { validateLength } from "../../util/validate_length.ts"; -import { isActionRow } from "../type_guards/is_action_row.ts"; -import { isButton } from "../type_guards/is_button.ts"; /** Send a message to the channel. Requires SEND_MESSAGES permission. */ export async function sendMessage( @@ -100,49 +97,7 @@ export async function sendMessage( } if (content.components?.length) { - let actionRowCounter = 0; - - for (const component of content.components) { - // 5 Link buttons can not have a customId - if (isButton(component)) { - if ( - component.type === ButtonStyles.Link && - component.customId - ) { - throw new Error(Errors.LINK_BUTTON_CANNOT_HAVE_CUSTOM_ID); - } - // Other buttons must have a customId - if ( - !component.customId && component.type !== ButtonStyles.Link - ) { - throw new Error(Errors.BUTTON_REQUIRES_CUSTOM_ID); - } - - if (!validateLength(component.label, { max: 80 })) { - throw new Error(Errors.COMPONENT_LABEL_TOO_BIG); - } - - if ( - component.customId && - !validateLength(component.customId, { max: 100 }) - ) { - throw new Error(Errors.COMPONENT_CUSTOM_ID_TOO_BIG); - } - } - - if (!isActionRow(component)) { - continue; - } - - actionRowCounter++; - // Max of 5 ActionRows per message - if (actionRowCounter > 5) throw new Error(Errors.TOO_MANY_ACTION_ROWS); - - // Max of 5 Buttons (or any component type) within an ActionRow - if (component.components?.length > 5) { - throw new Error(Errors.TOO_MANY_COMPONENTS); - } - } + validateComponents(content.components); } const result = await rest.runMethod( diff --git a/src/helpers/webhooks/edit_webhook_message.ts b/src/helpers/webhooks/edit_webhook_message.ts index c066d2933..6c6a0c1e4 100644 --- a/src/helpers/webhooks/edit_webhook_message.ts +++ b/src/helpers/webhooks/edit_webhook_message.ts @@ -1,10 +1,11 @@ import { rest } from "../../rest/rest.ts"; import { structures } from "../../structures/mod.ts"; +import { Errors } from "../../types/discordeno/errors.ts"; import { DiscordAllowedMentionsTypes } from "../../types/messages/allowed_mentions_types.ts"; import type { Message } from "../../types/messages/message.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; import type { EditWebhookMessage } from "../../types/webhooks/edit_webhook_message.ts"; import { endpoints } from "../../util/constants.ts"; +import { validateComponents } from "../../util/utils.ts"; export async function editWebhookMessage( webhookId: bigint, @@ -59,6 +60,10 @@ export async function editWebhookMessage( } } + if (options.components?.length) { + validateComponents(options.components); + } + const result = await rest.runMethod( "patch", options.messageId diff --git a/src/util/utils.ts b/src/util/utils.ts index d936d291b..6058d542e 100644 --- a/src/util/utils.ts +++ b/src/util/utils.ts @@ -1,11 +1,15 @@ import { encode } from "../../deps.ts"; import { eventHandlers } from "../bot.ts"; +import { isActionRow } from "../helpers/type_guards/is_action_row.ts"; +import { isButton } from "../helpers/type_guards/is_button.ts"; import { Errors } from "../types/discordeno/errors.ts"; import type { ApplicationCommandOption } from "../types/interactions/commands/application_command_option.ts"; import type { ApplicationCommandOptionChoice } from "../types/interactions/commands/application_command_option_choice.ts"; import { DiscordApplicationCommandOptionTypes } from "../types/interactions/commands/application_command_option_types.ts"; import type { CreateGlobalApplicationCommand } from "../types/interactions/commands/create_global_application_command.ts"; import type { EditGlobalApplicationCommand } from "../types/interactions/commands/edit_global_application_command.ts"; +import { ButtonStyles } from "../types/messages/components/button_styles.ts"; +import type { MessageComponents } from "../types/messages/components/message_components.ts"; import type { DiscordImageFormat } from "../types/misc/image_format.ts"; import type { DiscordImageSize } from "../types/misc/image_size.ts"; import { SLASH_COMMANDS_NAME_REGEX } from "./constants.ts"; @@ -216,3 +220,51 @@ export function hasOwnProperty( // deno-lint-ignore no-prototype-builtins return obj.hasOwnProperty(prop); } + +export function validateComponents(components: MessageComponents) { + if (components?.length) { + let actionRowCounter = 0; + + for (const component of components) { + // 5 Link buttons can not have a customId + if (isButton(component)) { + if ( + component.type === ButtonStyles.Link && + component.customId + ) { + throw new Error(Errors.LINK_BUTTON_CANNOT_HAVE_CUSTOM_ID); + } + // Other buttons must have a customId + if ( + !component.customId && component.type !== ButtonStyles.Link + ) { + throw new Error(Errors.BUTTON_REQUIRES_CUSTOM_ID); + } + + if (!validateLength(component.label, { max: 80 })) { + throw new Error(Errors.COMPONENT_LABEL_TOO_BIG); + } + + if ( + component.customId && + !validateLength(component.customId, { max: 100 }) + ) { + throw new Error(Errors.COMPONENT_CUSTOM_ID_TOO_BIG); + } + } + + if (!isActionRow(component)) { + continue; + } + + actionRowCounter++; + // Max of 5 ActionRows per message + if (actionRowCounter > 5) throw new Error(Errors.TOO_MANY_ACTION_ROWS); + + // Max of 5 Buttons (or any component type) within an ActionRow + if (component.components?.length > 5) { + throw new Error(Errors.TOO_MANY_COMPONENTS); + } + } + } +}