import { AutocompleteInteraction, CacheType, ChatInputCommandInteraction, SlashCommandBuilder, } from 'discord.js'; import { addSound, buildSoundboardMessage, listSounds, playById, removeSound, } from '../soundboard'; const name = "soundboard" function register() { return new SlashCommandBuilder() .setName(name) .setDescription('Soundboard — dźwięki na wierzchu muzyki') .addSubcommand((sub) => sub .setName("add") .setDescription("Dodaj dźwięk (max 10s)") .addAttachmentOption((option) => option .setName("file") .setDescription("Krótki plik audio") .setRequired(true)) .addStringOption((option) => option .setName("description") .setDescription("Krótki opis na przycisku") .setRequired(true) .setMaxLength(40)) .addStringOption((option) => option .setName("emoji") .setDescription("Emoji do przycisku") .setRequired(true) .setMaxLength(32))) .addSubcommand((sub) => sub .setName("list") .setDescription("Pokaż soundboard do klikania")) .addSubcommand((sub) => sub .setName("play") .setDescription("Puść dźwięk z listy") .addStringOption((option) => option .setName("sound") .setDescription("Który dźwięk") .setRequired(true) .setAutocomplete(true))) .addSubcommand((sub) => sub .setName("remove") .setDescription("Usuń dźwięk") .addStringOption((option) => option .setName("sound") .setDescription("Który dźwięk") .setRequired(true) .setAutocomplete(true))) } export async function handleSoundboardAutocomplete(interaction: AutocompleteInteraction) { const focused = interaction.options.getFocused().toLowerCase(); const choices = listSounds() .filter((sound) => sound.description.toLowerCase().includes(focused) || sound.emoji.includes(focused) || sound.id.startsWith(focused) ) .slice(0, 25) .map((sound) => ({ name: `${sound.emoji} ${sound.description}`.slice(0, 100), value: sound.id, })); await interaction.respond(choices); } async function execute(interaction: ChatInputCommandInteraction) { const sub = interaction.options.getSubcommand(); try { if (sub === "add") { await interaction.deferReply(); const file = interaction.options.getAttachment("file", true); const description = interaction.options.getString("description", true); const emoji = interaction.options.getString("emoji", true); const sound = await addSound({ attachment: file, description, emoji, user: interaction.user.username, }); await interaction.editReply(`Dodane: ${sound.emoji} **${sound.description}**`); return; } if (sub === "list") { await interaction.reply(buildSoundboardMessage(0)); return; } if (sub === "play") { await interaction.deferReply({ ephemeral: true }); const id = interaction.options.getString("sound", true); const sound = await playById(id, interaction); await interaction.editReply(`${sound.emoji} ${sound.description}`); return; } if (sub === "remove") { await interaction.deferReply({ ephemeral: true }); const id = interaction.options.getString("sound", true); const removed = removeSound(id); if (!removed) { await interaction.editReply("Nie ma takiego dźwięku"); return; } await interaction.editReply(`Usunięte: ${removed.emoji} ${removed.description}`); return; } } catch (error) { console.error(error); const message = error instanceof Error ? error.message : "Coś poszło nie tak :/"; if (interaction.deferred || interaction.replied) { await interaction.editReply(message); } else { await interaction.reply({ content: message, ephemeral: true }); } } } export default { name, register, execute }