I have a bot where a command is executed with a modal window and I have a problem with the window, when I accidentally swap, close it without entering data, and try to reopen it, then I have duplicate commands, for example creating a role, one role is created twice. I would like your help
Here is the code for the action, creating a role
case 'create':
const requiredCoins = 1;
const userBalance = await database.getUserBalance(interaction.user.id, interaction.guild.id);
if (userBalance < requiredCoins) {
await interaction.reply({
content: `У вас недостаточно монет для создания личной роли. Требуется ${requiredCoins} монет.`,
ephemeral: true,
});
return;
}
const modal = new ModalBuilder()
.setCustomId('createRoleModal')
.setTitle('Создать личную роль')
.setComponents(
new ActionRowBuilder().setComponents(
new TextInputBuilder()
.setCustomId('roleName')
.setLabel('Название роли')
.setPlaceholder('Введите название для личной роли')
.setStyle(TextInputStyle.Paragraph)
.setRequired(true)
.setMinLength(1)
.setMaxLength(100)
),
new ActionRowBuilder().setComponents(
new TextInputBuilder()
.setCustomId('roleColor')
.setLabel('Цвет роли')
.setPlaceholder('Введите HEX-код цвета для роли')
.setStyle(TextInputStyle.Paragraph)
.setRequired(true)
.setMinLength(7)
.setMaxLength(7)
)
);
await interaction.showModal(modal);
const modalSubmitInteraction = await interaction.awaitModalSubmit({
filter: (i) => {
console.log('Ожидание отправки модального окна');
console.log(i.fields);
return true;
},
time: 300000,
});
const roleName = modalSubmitInteraction.fields.getTextInputValue(
'roleName'
);
const roleColor = modalSubmitInteraction.fields.getTextInputValue(
'roleColor'
);
try {
await modalSubmitInteraction.deferUpdate();
} catch (error) {
console.error('Ошибка при обновлении интеракции:', error);
}
try {
const guild = interaction.guild;
const newRole = await createRole(roleName, roleColor, guild, interaction.user);
// Списываем монеты с баланса пользователя
await database.updateUserBalance(interaction.user.id, interaction.guild.id, userBalance - requiredCoins);
database.savePersonalRole(guild.id, interaction.user.id, newRole.id, () => {});
await modalSubmitInteraction.followUp({
content: `Личная роль "${roleName}" создана с цветом ${roleColor}.`,
ephemeral: false,
});
} catch (error) {
console.error('Ошибка при создании роли:', error);
try {
await modalSubmitInteraction.followUp({
content:
'Ошибка при создании роли. Проверьте правильность введенных данных.',
ephemeral: true,
});
} catch (followUpError) {
console.error('Ошибка при отправке follow-up сообщения:', followUpError);
}
}
break;
Here is the handler
client.on(Events.InteractionCreate, async interaction => {
//if (!interaction.isModalSubmit()) return;
console.log(interaction);
if (!interaction.isCommand()) {
if (interaction.isStringSelectMenu()) {
topCommand.handleStringSelectMenu(interaction);
}
return;
}
// Обработка закрытия модального окна
if (interaction.type === 'ModalClose') {
await interaction.reply({
content: 'Вы закрыли окно создания роли. Если это было случайно, попробуйте еще раз.',
ephemeral: true,
});
return;
}
if (!interaction.isCommand()) {
if (interaction.isModalSubmit()) {
topCommand.handleModalSubmit(interaction);
}
return;
}
if (!interaction.isChatInputCommand()) return;
const command = client.commands.get(interaction.commandName);
if (!command) return;
const { cooldowns } = client;
if (!cooldowns.has(command.name)) {
cooldowns.set(command.name, new Collection());
}
const now = Date.now();
const timestamps = cooldowns.get(command.name);
const defaultCooldownDuration = 3;
const cooldownAmount = (command.cooldown ?? defaultCooldownDuration) * 1000;
if (timestamps.has(interaction.user.id)) {
const expirationTime = timestamps.get(interaction.user.id) + cooldownAmount;
if (now < expirationTime) {
const expiredTimestamp = Math.round(expirationTime / 1000);
return interaction.reply({ content: `Пожайлуста подождите <t:${expiredTimestamp}:R> еще несколько секунд, прежде чем повторно использовать.\`${command.name}\` command.`, ephemeral: true });
}
}
timestamps.set(interaction.user.id, now);
setTimeout(() => timestamps.delete(interaction.user.id), cooldownAmount);
try {
await command.execute(interaction);
} catch (error) {
console.error(error);
await interaction.reply({ content: 'При выполнении этой команды произошла ошибка!', ephemeral: true });
}
});