133 lines
3.8 KiB
JavaScript
133 lines
3.8 KiB
JavaScript
import { SlashCommandBuilder } from 'discord.js';
|
|
import { Interaction } from 'discord.js';
|
|
|
|
// Maps to track queues and voice connections per guild
|
|
const queueMap = new Map(); // { guildId: [track1, track2, ...] }
|
|
const connectionMap = new Map(); // { guildId: VoiceConnection }
|
|
|
|
const data = new SlashCommandBuilder()
|
|
.setName('music')
|
|
.setDescription('Perform ButlerBot music operations.')
|
|
.addSubcommand((subcommand) =>
|
|
subcommand
|
|
.setName('play')
|
|
.setDescription('Play a track.')
|
|
.addStringOption((option) =>
|
|
option
|
|
.setName('track')
|
|
.setDescription('The track to play.')
|
|
.setRequired(true)
|
|
)
|
|
.addStringOption((option) =>
|
|
option
|
|
.setName('provider')
|
|
.setDescription('The provider of the track.')
|
|
.setRequired(false)
|
|
.addChoices(
|
|
{ name: 'YouTube', value: 'youtube' },
|
|
{ name: 'Spotify', value: 'spotify' },
|
|
{ name: 'Local', value: 'local' }
|
|
)
|
|
)
|
|
)
|
|
.addSubcommand((subcommand) =>
|
|
subcommand.setName('pause').setDescription('Pause the current track.')
|
|
)
|
|
.addSubcommand((subcommand) =>
|
|
subcommand.setName('resume').setDescription('Resume the current track.')
|
|
)
|
|
.addSubcommand((subcommand) =>
|
|
subcommand.setName('skip').setDescription('Skip the current track.')
|
|
)
|
|
.addSubcommand((subcommand) =>
|
|
subcommand.setName('stop').setDescription('Stop the current track.')
|
|
)
|
|
.addSubcommand((subcommand) =>
|
|
subcommand.setName('queue').setDescription('Show the current track queue.')
|
|
)
|
|
.addSubcommand((subcommand) =>
|
|
subcommand.setName('clear').setDescription('Clear the current track queue.')
|
|
)
|
|
.addSubcommand((subcommand) =>
|
|
subcommand.setName('leave').setDescription('Leave the voice channel.')
|
|
)
|
|
.addSubcommand((subcommand) =>
|
|
subcommand.setName('join').setDescription('Join the voice channel.')
|
|
);
|
|
|
|
/**
|
|
* Handles the music command.
|
|
* @param {Interaction} interaction The interaction object.
|
|
*/
|
|
async function execute(interaction) {
|
|
await interaction.deferReply();
|
|
const subcommand = interaction.options.getSubcommand();
|
|
const guildId = interaction.guild.id;
|
|
|
|
switch (subcommand) {
|
|
case 'play':
|
|
await handlePlay(interaction, guildId);
|
|
break;
|
|
case 'pause':
|
|
await handlePause(interaction, guildId);
|
|
break;
|
|
case 'resume':
|
|
await handleResume(interaction, guildId);
|
|
break;
|
|
case 'skip':
|
|
await handleSkip(interaction, guildId);
|
|
break;
|
|
case 'stop':
|
|
await handleStop(interaction, guildId);
|
|
break;
|
|
case 'queue':
|
|
await handleQueue(interaction, guildId);
|
|
break;
|
|
case 'clear':
|
|
await handleClear(interaction, guildId);
|
|
break;
|
|
case 'leave':
|
|
await handleLeave(interaction, guildId);
|
|
break;
|
|
case 'join':
|
|
await handleJoin(interaction, guildId);
|
|
break;
|
|
default:
|
|
await interaction.editReply('Invalid music subcommand.');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handles the play subcommand.
|
|
* @param {Interaction} interaction The interaction object.
|
|
* @param {string} guildId The guild ID.
|
|
* @returns {Promise<void>}
|
|
*/
|
|
|
|
async function handlePlay(interaction, guildId) {
|
|
const track = interaction.options.getString('track');
|
|
const provider = interaction.options.getString('provider') || 'youtube';
|
|
|
|
// Check if the user is in a voice channel
|
|
const voiceChannel = interaction.member.voice.channel;
|
|
if (!voiceChannel) {
|
|
await interaction.editReply(
|
|
'You need to be in a voice channel to play music.'
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Get the queue for the guild
|
|
const queue = queueMap.get(guildId) || [];
|
|
queue.push({ track, provider });
|
|
queueMap.set(guildId, queue);
|
|
|
|
// Join the voice channel
|
|
await handleJoin(interaction, guildId);
|
|
|
|
// Play the track
|
|
await interaction.editReply(`Playing track: ${track}`);
|
|
}
|
|
|
|
export default { data, execute };
|