diff --git a/bot.ts b/bot.ts index d89c29645..c8b6e185b 100644 --- a/bot.ts +++ b/bot.ts @@ -158,6 +158,7 @@ import { transformApplicationCommandOptionChoiceToDiscordApplicationCommandOptionChoice, transformApplicationCommandOptionToDiscordApplicationCommandOption, } from "./mod.ts"; +import { transformAttachmentToDiscordAttachment } from "./transformers/reverse/attachment.ts"; export function createBot(options: CreateBotOptions): Bot { const bot = { @@ -419,6 +420,7 @@ export interface Transformers { bot: Bot, payload: ApplicationCommandOptionChoice, ) => DiscordApplicationCommandOptionChoice; + attachment: (bot: Bot, payload: Attachment) => DiscordAttachment; }; snowflake: (snowflake: string) => bigint; gatewayBot: (payload: DiscordGetGatewayBot) => GetGatewayBot; @@ -483,6 +485,7 @@ export function createTransformers(options: Partial) { transformApplicationCommandOptionToDiscordApplicationCommandOption, applicationCommandOptionChoice: options.reverse?.applicationCommandOptionChoice || transformApplicationCommandOptionChoiceToDiscordApplicationCommandOptionChoice, + attachment: options.reverse?.attachment || transformAttachmentToDiscordAttachment, }, automodRule: options.automodRule || transformAutoModerationRule, automodActionExecution: options.automodActionExecution || transformAutoModerationActionExecution, diff --git a/helpers/interactions/commands/editInteractionResponse.ts b/helpers/interactions/commands/editInteractionResponse.ts index a46e9db0d..e843b716f 100644 --- a/helpers/interactions/commands/editInteractionResponse.ts +++ b/helpers/interactions/commands/editInteractionResponse.ts @@ -1,7 +1,6 @@ import type { Bot } from "../../../bot.ts"; import { Message } from "../../../transformers/message.ts"; import { DiscordMessage } from "../../../types/discord.ts"; -import { MessageComponentTypes } from "../../../types/shared.ts"; import { EditWebhookMessage } from "../../webhooks/editWebhookMessage.ts"; /** To edit your response to a application command. If a messageId is not provided it will default to editing the original response. */ @@ -24,80 +23,10 @@ export async function editInteractionResponse( embeds: options.embeds?.map((embed) => bot.transformers.reverse.embed(bot, embed)), file: options.file, allowed_mentions: options.allowedMentions - ? { - parse: options.allowedMentions.parse, - roles: options.allowedMentions.roles?.map((id) => id.toString()), - users: options.allowedMentions.users?.map((id) => id.toString()), - replied_user: options.allowedMentions.repliedUser, - } + ? bot.transformers.reverse.allowedMentions(bot, options.allowedMentions) : undefined, - attachments: options.attachments?.map((attachment) => ({ - id: attachment.id.toString(), - filename: attachment.filename, - content_type: attachment.contentType, - size: attachment.size, - url: attachment.url, - proxy_url: attachment.proxyUrl, - height: attachment.height, - width: attachment.width, - ephemeral: attachment.ephemeral, - })), - components: options.components?.map((component) => ({ - type: component.type, - components: component.components.map((subComponent) => { - if (subComponent.type === MessageComponentTypes.InputText) { - return { - type: subComponent.type, - style: subComponent.style, - custom_id: subComponent.customId, - label: subComponent.label, - placeholder: subComponent.placeholder, - min_length: subComponent.minLength ?? subComponent.required === false ? 0 : subComponent.minLength, - max_length: subComponent.maxLength, - }; - } - - if (subComponent.type === MessageComponentTypes.SelectMenu) { - return { - type: subComponent.type, - custom_id: subComponent.customId, - placeholder: subComponent.placeholder, - min_values: subComponent.minValues, - max_values: subComponent.maxValues, - disabled: "disabled" in subComponent ? subComponent.disabled : undefined, - options: subComponent.options.map((option) => ({ - label: option.label, - value: option.value, - description: option.description, - emoji: option.emoji - ? { - id: option.emoji.id?.toString(), - name: option.emoji.name, - animated: option.emoji.animated, - } - : undefined, - default: option.default, - })), - }; - } - - return { - type: subComponent.type, - custom_id: subComponent.customId, - label: subComponent.label, - style: subComponent.style, - emoji: "emoji" in subComponent && subComponent.emoji - ? { - id: subComponent.emoji.id?.toString(), - name: subComponent.emoji.name, - animated: subComponent.emoji.animated, - } - : undefined, - url: "url" in subComponent ? subComponent.url : undefined, - disabled: "disabled" in subComponent ? subComponent.disabled : undefined, - }; - }), - })), + attachments: options.attachments?.map((attachment) => bot.transformers.reverse.attachment(bot, attachment)), + components: options.components?.map((component) => bot.transformers.reverse.component(bot, component)), message_id: options.messageId?.toString(), }, ); diff --git a/helpers/interactions/followups/editFollowupMessage.ts b/helpers/interactions/followups/editFollowupMessage.ts index 5dcb8eee7..e31927b49 100644 --- a/helpers/interactions/followups/editFollowupMessage.ts +++ b/helpers/interactions/followups/editFollowupMessage.ts @@ -1,7 +1,6 @@ import { Bot } from "../../../bot.ts"; import { Message } from "../../../transformers/message.ts"; import { DiscordMessage } from "../../../types/discord.ts"; -import { MessageComponentTypes } from "../../../types/shared.ts"; import { EditWebhookMessage } from "../../webhooks/editWebhookMessage.ts"; /** Edits a followup message for an Interaction. Functions the same as edit webhook message, however this uses your interaction token instead of bot token. Does not support ephemeral followups. */ @@ -20,80 +19,10 @@ export async function editFollowupMessage( embeds: options.embeds?.map((embed) => bot.transformers.reverse.embed(bot, embed)), file: options.file, allowed_mentions: options.allowedMentions - ? { - parse: options.allowedMentions.parse, - roles: options.allowedMentions.roles?.map((id) => id.toString()), - users: options.allowedMentions.users?.map((id) => id.toString()), - replied_user: options.allowedMentions.repliedUser, - } + ? bot.transformers.reverse.allowedMentions(bot, options.allowedMentions) : undefined, - attachments: options.attachments?.map((attachment) => ({ - id: attachment.id.toString(), - filename: attachment.filename, - content_type: attachment.contentType, - size: attachment.size, - url: attachment.url, - proxy_url: attachment.proxyUrl, - height: attachment.height, - width: attachment.width, - ephemeral: attachment.ephemeral, - })), - components: options.components?.map((component) => ({ - type: component.type, - components: component.components.map((subComponent) => { - if (subComponent.type === MessageComponentTypes.InputText) { - return { - type: subComponent.type, - style: subComponent.style, - custom_id: subComponent.customId, - label: subComponent.label, - placeholder: subComponent.placeholder, - min_length: subComponent.minLength ?? subComponent.required === false ? 0 : subComponent.minLength, - max_length: subComponent.maxLength, - }; - } - - if (subComponent.type === MessageComponentTypes.SelectMenu) { - return { - type: subComponent.type, - custom_id: subComponent.customId, - placeholder: subComponent.placeholder, - min_values: subComponent.minValues, - max_values: subComponent.maxValues, - disabled: "disabled" in subComponent ? subComponent.disabled : undefined, - options: subComponent.options.map((option) => ({ - label: option.label, - value: option.value, - description: option.description, - emoji: option.emoji - ? { - id: option.emoji.id?.toString(), - name: option.emoji.name, - animated: option.emoji.animated, - } - : undefined, - default: option.default, - })), - }; - } - - return { - type: subComponent.type, - custom_id: subComponent.customId, - label: subComponent.label, - style: subComponent.style, - emoji: subComponent.emoji - ? { - id: subComponent.emoji.id?.toString(), - name: subComponent.emoji.name, - animated: subComponent.emoji.animated, - } - : undefined, - url: subComponent.url, - disabled: subComponent.disabled, - }; - }), - })), + attachments: options.attachments?.map((attachment) => bot.transformers.reverse.attachment(bot, attachment)), + components: options.components?.map((component) => bot.transformers.reverse.component(bot, component)), message_id: messageId?.toString(), }, ); diff --git a/helpers/messages/editMessage.ts b/helpers/messages/editMessage.ts index dd49d3ffa..4017313cc 100644 --- a/helpers/messages/editMessage.ts +++ b/helpers/messages/editMessage.ts @@ -4,7 +4,6 @@ import { Embed } from "../../transformers/embed.ts"; import { Message } from "../../transformers/message.ts"; import { DiscordMessage } from "../../types/discord.ts"; import { AllowedMentions, FileContent, MessageComponents } from "../../types/discordeno.ts"; -import { MessageComponentTypes } from "../../types/shared.ts"; /** Edit the message. */ export async function editMessage( @@ -20,79 +19,12 @@ export async function editMessage( { content: content.content, embeds: content.embeds?.map((embed) => bot.transformers.reverse.embed(bot, embed)), - allowed_mentions: { - parse: content.allowedMentions?.parse, - roles: content.allowedMentions?.roles?.map((id) => id.toString()), - users: content.allowedMentions?.users?.map((id) => id.toString()), - replied_user: content.allowedMentions?.repliedUser, - }, - attachments: content.attachments?.map((attachment) => ({ - id: attachment.id.toString(), - filename: attachment.filename, - content_type: attachment.contentType, - size: attachment.size, - url: attachment.url, - proxy_url: attachment.proxyUrl, - height: attachment.height, - width: attachment.width, - })), + allowed_mentions: content.allowedMentions + ? bot.transformers.reverse.allowedMentions(bot, content.allowedMentions) + : undefined, + attachments: content.attachments?.map((attachment) => bot.transformers.reverse.attachment(bot, attachment)), file: content.file, - components: content.components?.map((component) => ({ - type: component.type, - components: component.components.map((subComponent) => { - if (subComponent.type === MessageComponentTypes.InputText) { - return { - type: subComponent.type, - style: subComponent.style, - custom_id: subComponent.customId, - label: subComponent.label, - placeholder: subComponent.placeholder, - min_length: subComponent.minLength ?? subComponent.required === false ? 0 : subComponent.minLength, - max_length: subComponent.maxLength, - }; - } - - if (subComponent.type === MessageComponentTypes.SelectMenu) { - return { - type: subComponent.type, - custom_id: subComponent.customId, - placeholder: subComponent.placeholder, - min_values: subComponent.minValues, - max_values: subComponent.maxValues, - disabled: "disabled" in subComponent ? subComponent.disabled : undefined, - options: subComponent.options.map((option) => ({ - label: option.label, - value: option.value, - description: option.description, - emoji: option.emoji - ? { - id: option.emoji.id?.toString(), - name: option.emoji.name, - animated: option.emoji.animated, - } - : undefined, - default: option.default, - })), - }; - } - - return { - type: subComponent.type, - custom_id: subComponent.customId, - label: subComponent.label, - style: subComponent.style, - emoji: "emoji" in subComponent && subComponent.emoji - ? { - id: subComponent.emoji.id?.toString(), - name: subComponent.emoji.name, - animated: subComponent.emoji.animated, - } - : undefined, - url: "url" in subComponent ? subComponent.url : undefined, - disabled: "disabled" in subComponent ? subComponent.disabled : undefined, - }; - }), - })), + components: content.components?.map((component) => bot.transformers.reverse.component(bot, component)), }, ); diff --git a/helpers/webhooks/editWebhookMessage.ts b/helpers/webhooks/editWebhookMessage.ts index d1ce5df7f..c67dc466c 100644 --- a/helpers/webhooks/editWebhookMessage.ts +++ b/helpers/webhooks/editWebhookMessage.ts @@ -4,7 +4,6 @@ import { Embed } from "../../transformers/embed.ts"; import { Message } from "../../transformers/message.ts"; import { DiscordMessage } from "../../types/discord.ts"; import { AllowedMentions, FileContent, MessageComponents } from "../../types/discordeno.ts"; -import { MessageComponentTypes } from "../../types/shared.ts"; export async function editWebhookMessage( bot: Bot, @@ -23,80 +22,10 @@ export async function editWebhookMessage( embeds: options.embeds?.map((embed) => bot.transformers.reverse.embed(bot, embed)), file: options.file, allowed_mentions: options.allowedMentions - ? { - parse: options.allowedMentions.parse, - roles: options.allowedMentions.roles?.map((id) => id.toString()), - users: options.allowedMentions.users?.map((id) => id.toString()), - replied_user: options.allowedMentions.repliedUser, - } + ? bot.transformers.reverse.allowedMentions(bot, options.allowedMentions) : undefined, - attachments: options.attachments?.map((attachment) => ({ - id: attachment.id.toString(), - filename: attachment.filename, - content_type: attachment.contentType, - size: attachment.size, - url: attachment.url, - proxy_url: attachment.proxyUrl, - height: attachment.height, - width: attachment.width, - ephemeral: attachment.ephemeral, - })), - components: options.components?.map((component) => ({ - type: component.type, - components: component.components.map((subComponent) => { - if (subComponent.type === MessageComponentTypes.InputText) { - return { - type: subComponent.type, - style: subComponent.style, - custom_id: subComponent.customId, - label: subComponent.label, - placeholder: subComponent.placeholder, - min_length: subComponent.minLength ?? subComponent.required === false ? 0 : subComponent.minLength, - max_length: subComponent.maxLength, - }; - } - - if (subComponent.type === MessageComponentTypes.SelectMenu) { - return { - type: subComponent.type, - custom_id: subComponent.customId, - placeholder: subComponent.placeholder, - min_values: subComponent.minValues, - max_values: subComponent.maxValues, - disabled: "disabled" in subComponent ? subComponent.disabled : undefined, - options: subComponent.options.map((option) => ({ - label: option.label, - value: option.value, - description: option.description, - emoji: option.emoji - ? { - id: option.emoji.id?.toString(), - name: option.emoji.name, - animated: option.emoji.animated, - } - : undefined, - default: option.default, - })), - }; - } - - return { - type: subComponent.type, - custom_id: subComponent.customId, - label: subComponent.label, - style: subComponent.style, - emoji: "emoji" in subComponent && subComponent.emoji - ? { - id: subComponent.emoji.id?.toString(), - name: subComponent.emoji.name, - animated: subComponent.emoji.animated, - } - : undefined, - url: "url" in subComponent ? subComponent.url : undefined, - disabled: "disabled" in subComponent ? subComponent.disabled : undefined, - }; - }), - })), + attachments: options.attachments?.map((attachment) => bot.transformers.reverse.attachment(bot, attachment)), + components: options.components?.map((component) => bot.transformers.reverse.component(bot, component)), message_id: options.messageId?.toString(), }, ); diff --git a/plugins/permissions/src/attachments.ts b/plugins/permissions/src/attachments.ts new file mode 100644 index 000000000..21a5ee0fd --- /dev/null +++ b/plugins/permissions/src/attachments.ts @@ -0,0 +1,9 @@ +import { Attachment, Bot } from "../deps.ts"; + +export function validateAttachments(bot: Bot, attachments: Attachment[]) { + attachments.forEach((attachment) => { + if (attachment.description && !bot.utils.validateLength(attachment.description, { min: 0, max: 1024 })) { + throw new Error("Attachment description length must be less than 1024 characters"); + } + }); +} diff --git a/plugins/permissions/src/interactions/commands.ts b/plugins/permissions/src/interactions/commands.ts index 6a92757c0..999e8e0af 100644 --- a/plugins/permissions/src/interactions/commands.ts +++ b/plugins/permissions/src/interactions/commands.ts @@ -7,6 +7,7 @@ import { CONTEXT_MENU_COMMANDS_NAME_REGEX, SLASH_COMMANDS_NAME_REGEX, } from "../../deps.ts"; +import { validateAttachments } from "../attachments.ts"; export function validateApplicationCommandOptions( bot: BotWithCache, @@ -176,6 +177,8 @@ export function editInteractionResponse(bot: BotWithCache) { } } + if (options.attachments) validateAttachments(bot, options.attachments); + return await editInteractionResponseOld(token, options); }; } diff --git a/plugins/permissions/src/interactions/editFollowupMessage.ts b/plugins/permissions/src/interactions/editFollowupMessage.ts index 0917417d8..baba1a725 100644 --- a/plugins/permissions/src/interactions/editFollowupMessage.ts +++ b/plugins/permissions/src/interactions/editFollowupMessage.ts @@ -1,4 +1,5 @@ import { AllowedMentionsTypes, BotWithCache } from "../../deps.ts"; +import { validateAttachments } from "../attachments.ts"; export default function editFollowupMessage(bot: BotWithCache) { const editFollowupMessageOld = bot.helpers.editFollowupMessage; @@ -56,6 +57,8 @@ export default function editFollowupMessage(bot: BotWithCache) { } } + if (options.attachments) validateAttachments(bot, options.attachments); + return await editFollowupMessageOld(token, messageId, options); }; } diff --git a/plugins/permissions/src/messages/create.ts b/plugins/permissions/src/messages/create.ts index ad9d29cd2..960b08b64 100644 --- a/plugins/permissions/src/messages/create.ts +++ b/plugins/permissions/src/messages/create.ts @@ -1,4 +1,5 @@ import { AllowedMentionsTypes, BotWithCache, ChannelTypes, PermissionStrings } from "../../deps.ts"; +import { validateAttachments } from "../attachments.ts"; import { validateComponents } from "../components.ts"; import { requireBotChannelPermissions } from "../permissions.ts"; @@ -165,6 +166,8 @@ export function editMessage(bot: BotWithCache) { ); } + if (content.attachments) validateAttachments(bot, content.attachments); + return editMessageOld(channelId, messageId, content); }; } diff --git a/plugins/permissions/src/webhooks/message.ts b/plugins/permissions/src/webhooks/message.ts index a3167736f..c96b08fc1 100644 --- a/plugins/permissions/src/webhooks/message.ts +++ b/plugins/permissions/src/webhooks/message.ts @@ -1,4 +1,5 @@ import { AllowedMentionsTypes, BotWithCache } from "../../deps.ts"; +import { validateAttachments } from "../attachments.ts"; import { validateComponents } from "../components.ts"; export function editWebhookMessage(bot: BotWithCache) { @@ -62,6 +63,8 @@ export function editWebhookMessage(bot: BotWithCache) { if (options.components) validateComponents(bot, options.components); + if (options.attachments) validateAttachments(bot, options.attachments); + return await editWebhookMessageOld(webhookId, webhookToken, options); }; } diff --git a/transformers/attachment.ts b/transformers/attachment.ts index 370f56dab..55fa1ae62 100644 --- a/transformers/attachment.ts +++ b/transformers/attachment.ts @@ -13,6 +13,7 @@ export function transformAttachment(bot: Bot, payload: DiscordAttachment) { height: payload.height ?? undefined, width: payload.width ?? undefined, ephemeral: payload.ephemeral, + description: payload.description, }; return attachment as Optionalize; diff --git a/transformers/reverse/attachment.ts b/transformers/reverse/attachment.ts index 374713cd2..56e145481 100644 --- a/transformers/reverse/attachment.ts +++ b/transformers/reverse/attachment.ts @@ -13,5 +13,6 @@ export function transformAttachmentToDiscordAttachment(bot: Bot, payload: Attach height: payload.height, width: payload.width, ephemeral: payload.ephemeral, + description: payload.description, }; } diff --git a/types/discord.ts b/types/discord.ts index 505d6b43d..caccf8abc 100644 --- a/types/discord.ts +++ b/types/discord.ts @@ -436,6 +436,8 @@ export interface DiscordAttachment { /** Attachment id */ id: string; + /** description for the file (max 1024 characters) */ + description?: string; /** Height of file (if image) */ height?: number | null; /** Width of file (if image) */