Refactor modal interaction handling to use awaitModalWithDeferredReply and improve error handling in display component editor
This commit is contained in:
@@ -3,6 +3,7 @@ import {
|
|||||||
Message,
|
Message,
|
||||||
MessageComponentInteraction,
|
MessageComponentInteraction,
|
||||||
MessageFlags,
|
MessageFlags,
|
||||||
|
ModalSubmitInteraction,
|
||||||
TextChannel,
|
TextChannel,
|
||||||
} from "discord.js";
|
} from "discord.js";
|
||||||
import { ComponentType, TextInputStyle, ButtonStyle } from "discord-api-types/v10";
|
import { ComponentType, TextInputStyle, ButtonStyle } from "discord-api-types/v10";
|
||||||
@@ -336,6 +337,24 @@ async function handleButtonInteraction(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function awaitModalWithDeferredReply(
|
||||||
|
interaction: ButtonInteraction,
|
||||||
|
options: Parameters<ButtonInteraction['awaitModalSubmit']>[0] = { time: 300000 }
|
||||||
|
): Promise<ModalSubmitInteraction | null> {
|
||||||
|
try {
|
||||||
|
const modalInteraction = await interaction.awaitModalSubmit(options);
|
||||||
|
if (!modalInteraction.deferred && !modalInteraction.replied) {
|
||||||
|
await modalInteraction.deferReply({ flags: MessageFlags.Ephemeral });
|
||||||
|
}
|
||||||
|
return modalInteraction;
|
||||||
|
} catch (error) {
|
||||||
|
if (!(error instanceof Error) || !error.message.includes('Collector received no interactions')) {
|
||||||
|
logger.error({ err: error }, "Error esperando envío de modal en editor");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function handleEditTitle(
|
async function handleEditTitle(
|
||||||
interaction: ButtonInteraction,
|
interaction: ButtonInteraction,
|
||||||
editorMessage: Message,
|
editorMessage: Message,
|
||||||
@@ -364,8 +383,11 @@ async function handleEditTitle(
|
|||||||
|
|
||||||
await interaction.showModal(modal);
|
await interaction.showModal(modal);
|
||||||
|
|
||||||
|
let modalInteraction: ModalSubmitInteraction | null = null;
|
||||||
try {
|
try {
|
||||||
const modalInteraction = await interaction.awaitModalSubmit({ time: 300000 });
|
modalInteraction = await awaitModalWithDeferredReply(interaction);
|
||||||
|
if (!modalInteraction) return;
|
||||||
|
|
||||||
const newTitle = modalInteraction.components.getTextInputValue("title_input").trim();
|
const newTitle = modalInteraction.components.getTextInputValue("title_input").trim();
|
||||||
|
|
||||||
if (newTitle) {
|
if (newTitle) {
|
||||||
@@ -376,12 +398,19 @@ async function handleEditTitle(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await modalInteraction.reply({
|
await modalInteraction.editReply({
|
||||||
content: "✅ Título actualizado correctamente.",
|
content: "✅ Título actualizado correctamente."
|
||||||
flags: MessageFlags.Ephemeral
|
|
||||||
});
|
});
|
||||||
} catch {
|
} catch (error) {
|
||||||
// Modal timed out or error occurred
|
if (modalInteraction?.deferred && !modalInteraction.replied) {
|
||||||
|
await modalInteraction.editReply({
|
||||||
|
content: "❌ No se pudo actualizar el título. Inténtalo de nuevo."
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
if (error instanceof Error && error.message.includes('Collector received no interactions')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.error({ err: error }, "Error procesando modal de título");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,8 +442,11 @@ async function handleEditDescription(
|
|||||||
|
|
||||||
await interaction.showModal(modal);
|
await interaction.showModal(modal);
|
||||||
|
|
||||||
|
let modalInteraction: ModalSubmitInteraction | null = null;
|
||||||
try {
|
try {
|
||||||
const modalInteraction = await interaction.awaitModalSubmit({ time: 300000 });
|
modalInteraction = await awaitModalWithDeferredReply(interaction);
|
||||||
|
if (!modalInteraction) return;
|
||||||
|
|
||||||
const newDescription = modalInteraction.components.getTextInputValue("description_input").trim();
|
const newDescription = modalInteraction.components.getTextInputValue("description_input").trim();
|
||||||
|
|
||||||
blockState.description = newDescription || undefined;
|
blockState.description = newDescription || undefined;
|
||||||
@@ -423,12 +455,19 @@ async function handleEditDescription(
|
|||||||
components: DisplayComponentUtils.createEditorButtons(false)
|
components: DisplayComponentUtils.createEditorButtons(false)
|
||||||
});
|
});
|
||||||
|
|
||||||
await modalInteraction.reply({
|
await modalInteraction.editReply({
|
||||||
content: "✅ Descripción actualizada correctamente.",
|
content: "✅ Descripción actualizada correctamente."
|
||||||
flags: MessageFlags.Ephemeral
|
|
||||||
});
|
});
|
||||||
} catch {
|
} catch (error) {
|
||||||
// ignore
|
if (modalInteraction?.deferred && !modalInteraction.replied) {
|
||||||
|
await modalInteraction.editReply({
|
||||||
|
content: "❌ No se pudo actualizar la descripción. Inténtalo de nuevo."
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
if (error instanceof Error && error.message.includes('Collector received no interactions')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.error({ err: error }, "Error procesando modal de descripción");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,8 +499,11 @@ async function handleEditColor(
|
|||||||
|
|
||||||
await interaction.showModal(modal);
|
await interaction.showModal(modal);
|
||||||
|
|
||||||
|
let modalInteraction: ModalSubmitInteraction | null = null;
|
||||||
try {
|
try {
|
||||||
const modalInteraction = await interaction.awaitModalSubmit({ time: 300000 });
|
modalInteraction = await awaitModalWithDeferredReply(interaction);
|
||||||
|
if (!modalInteraction) return;
|
||||||
|
|
||||||
const colorValue = modalInteraction.components.getTextInputValue("color_input").trim();
|
const colorValue = modalInteraction.components.getTextInputValue("color_input").trim();
|
||||||
|
|
||||||
if (colorValue) {
|
if (colorValue) {
|
||||||
@@ -475,14 +517,12 @@ async function handleEditColor(
|
|||||||
components: DisplayComponentUtils.createEditorButtons(false)
|
components: DisplayComponentUtils.createEditorButtons(false)
|
||||||
});
|
});
|
||||||
|
|
||||||
await modalInteraction.reply({
|
await modalInteraction.editReply({
|
||||||
content: "✅ Color actualizado correctamente.",
|
content: "✅ Color actualizado correctamente."
|
||||||
flags: MessageFlags.Ephemeral
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await modalInteraction.reply({
|
await modalInteraction.editReply({
|
||||||
content: "❌ Color inválido. Usa formato HEX como #FF5733",
|
content: "❌ Color inválido. Usa formato HEX como #FF5733"
|
||||||
flags: MessageFlags.Ephemeral
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -492,13 +532,20 @@ async function handleEditColor(
|
|||||||
components: DisplayComponentUtils.createEditorButtons(false)
|
components: DisplayComponentUtils.createEditorButtons(false)
|
||||||
});
|
});
|
||||||
|
|
||||||
await modalInteraction.reply({
|
await modalInteraction.editReply({
|
||||||
content: "✅ Color removido.",
|
content: "✅ Color removido."
|
||||||
flags: MessageFlags.Ephemeral
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (error) {
|
||||||
// ignore
|
if (modalInteraction?.deferred && !modalInteraction.replied) {
|
||||||
|
await modalInteraction.editReply({
|
||||||
|
content: "❌ No se pudo actualizar el color. Inténtalo de nuevo."
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
if (error instanceof Error && error.message.includes('Collector received no interactions')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.error({ err: error }, "Error procesando modal de color");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,8 +576,11 @@ async function handleAddContent(
|
|||||||
|
|
||||||
await interaction.showModal(modal);
|
await interaction.showModal(modal);
|
||||||
|
|
||||||
|
let modalInteraction: ModalSubmitInteraction | null = null;
|
||||||
try {
|
try {
|
||||||
const modalInteraction = await interaction.awaitModalSubmit({ time: 300000 });
|
modalInteraction = await awaitModalWithDeferredReply(interaction);
|
||||||
|
if (!modalInteraction) return;
|
||||||
|
|
||||||
const content = modalInteraction.components.getTextInputValue("content_input").trim();
|
const content = modalInteraction.components.getTextInputValue("content_input").trim();
|
||||||
|
|
||||||
if (content) {
|
if (content) {
|
||||||
@@ -545,13 +595,20 @@ async function handleAddContent(
|
|||||||
components: DisplayComponentUtils.createEditorButtons(false)
|
components: DisplayComponentUtils.createEditorButtons(false)
|
||||||
});
|
});
|
||||||
|
|
||||||
await modalInteraction.reply({
|
await modalInteraction.editReply({
|
||||||
content: "✅ Contenido añadido correctamente.",
|
content: "✅ Contenido añadido correctamente."
|
||||||
flags: MessageFlags.Ephemeral
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (error) {
|
||||||
// ignore
|
if (modalInteraction?.deferred && !modalInteraction.replied) {
|
||||||
|
await modalInteraction.editReply({
|
||||||
|
content: "❌ No se pudo añadir el contenido. Inténtalo de nuevo."
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
if (error instanceof Error && error.message.includes('Collector received no interactions')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.error({ err: error }, "Error procesando modal de contenido");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,8 +662,11 @@ async function handleAddImage(
|
|||||||
|
|
||||||
await interaction.showModal(modal);
|
await interaction.showModal(modal);
|
||||||
|
|
||||||
|
let modalInteraction: ModalSubmitInteraction | null = null;
|
||||||
try {
|
try {
|
||||||
const modalInteraction = await interaction.awaitModalSubmit({ time: 300000 });
|
modalInteraction = await awaitModalWithDeferredReply(interaction);
|
||||||
|
if (!modalInteraction) return;
|
||||||
|
|
||||||
const imageUrl = modalInteraction.components.getTextInputValue("image_input").trim();
|
const imageUrl = modalInteraction.components.getTextInputValue("image_input").trim();
|
||||||
|
|
||||||
if (imageUrl && DisplayComponentUtils.isValidUrl(imageUrl)) {
|
if (imageUrl && DisplayComponentUtils.isValidUrl(imageUrl)) {
|
||||||
@@ -620,18 +680,24 @@ async function handleAddImage(
|
|||||||
components: DisplayComponentUtils.createEditorButtons(false)
|
components: DisplayComponentUtils.createEditorButtons(false)
|
||||||
});
|
});
|
||||||
|
|
||||||
await modalInteraction.reply({
|
await modalInteraction.editReply({
|
||||||
content: "✅ Imagen añadida correctamente.",
|
content: "✅ Imagen añadida correctamente."
|
||||||
flags: MessageFlags.Ephemeral
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await modalInteraction.reply({
|
await modalInteraction.editReply({
|
||||||
content: "❌ URL de imagen inválida.",
|
content: "❌ URL de imagen inválida."
|
||||||
flags: MessageFlags.Ephemeral
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (error) {
|
||||||
// ignore
|
if (modalInteraction?.deferred && !modalInteraction.replied) {
|
||||||
|
await modalInteraction.editReply({
|
||||||
|
content: "❌ No se pudo añadir la imagen. Inténtalo de nuevo."
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
if (error instanceof Error && error.message.includes('Collector received no interactions')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.error({ err: error }, "Error procesando modal de imagen");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -663,8 +729,11 @@ async function handleCoverImage(
|
|||||||
|
|
||||||
await interaction.showModal(modal);
|
await interaction.showModal(modal);
|
||||||
|
|
||||||
|
let modalInteraction: ModalSubmitInteraction | null = null;
|
||||||
try {
|
try {
|
||||||
const modalInteraction = await interaction.awaitModalSubmit({ time: 300000 });
|
modalInteraction = await awaitModalWithDeferredReply(interaction);
|
||||||
|
if (!modalInteraction) return;
|
||||||
|
|
||||||
const coverUrl = modalInteraction.components.getTextInputValue("cover_input").trim();
|
const coverUrl = modalInteraction.components.getTextInputValue("cover_input").trim();
|
||||||
|
|
||||||
if (coverUrl && DisplayComponentUtils.isValidUrl(coverUrl)) {
|
if (coverUrl && DisplayComponentUtils.isValidUrl(coverUrl)) {
|
||||||
@@ -678,12 +747,19 @@ async function handleCoverImage(
|
|||||||
components: DisplayComponentUtils.createEditorButtons(false)
|
components: DisplayComponentUtils.createEditorButtons(false)
|
||||||
});
|
});
|
||||||
|
|
||||||
await modalInteraction.reply({
|
await modalInteraction.editReply({
|
||||||
content: coverUrl ? "✅ Imagen de portada actualizada." : "✅ Imagen de portada removida.",
|
content: coverUrl ? "✅ Imagen de portada actualizada." : "✅ Imagen de portada removida."
|
||||||
flags: MessageFlags.Ephemeral
|
|
||||||
});
|
});
|
||||||
} catch {
|
} catch (error) {
|
||||||
// ignore
|
if (modalInteraction?.deferred && !modalInteraction.replied) {
|
||||||
|
await modalInteraction.editReply({
|
||||||
|
content: "❌ No se pudo actualizar la imagen de portada. Inténtalo de nuevo."
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
if (error instanceof Error && error.message.includes('Collector received no interactions')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.error({ err: error }, "Error procesando modal de portada");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user