discord-multipurpose-bot/commands/music/skip.js
Ayden cb5a906850
Some checks are pending
Docker / build (push) Waiting to run
Feat/Add Music Commands (#1)
* add simple music functionality

* update workflow

* update Dockerfile

* update Dockerfile

* update Dockerfile

* update Dockerfile

* add few more music commands

* add lyrics command

* update lyrics command

* add loop, and add categories to all commands

* change discord status

* seperate distube and change startup console theme

* Update README

* UPDATE LICENSE file

* fix docker compose image, add better error handling for distube and update tagging workflow

* switch to node-alpine image for docker

* switch to node-alpine image for docker

* update ascii

* music commands imporvements, implement live lyrics, some guards and bot leaving on empty

* use ffmpeg package rather than ffmpeg-static
2025-09-21 01:26:18 +01:00

140 lines
4.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const { SlashCommandBuilder } = require("discord.js");
const { requireVC, requireQueue } = require("../../utils/musicGuards");
module.exports = {
data: new SlashCommandBuilder()
.setName("skip")
.setDescription(
"Skips the current song (or jump to a specific upcoming track)."
)
.addIntegerOption((o) =>
o
.setName("to")
.setDescription(
"Queue index to jump to (as shown in /queue). 1 = next song."
)
.setMinValue(1)
),
category: "Music",
async execute(interaction, client) {
try {
await interaction.deferReply();
requireVC(interaction);
const queue = requireQueue(client, interaction);
const toIndex = interaction.options.getInteger("to"); // 1-based (1 = next)
const total = queue.songs.length;
const upcomingCount = Math.max(0, total - 1);
if (upcomingCount === 0 && !queue.autoplay) {
// Nothing to skip to, and autoplay is off -> stop and leave
try {
queue.stop();
} catch {}
client.distube.voices.leave(interaction.guildId);
try {
const live = require("../../utils/liveLyricsManager");
await live.stop(interaction.guildId, { deleteThread: true });
} catch {}
return interaction.followUp(
"🏁 No more songs — stopped and left the voice channel."
);
}
// If user specified a target index (jump)
if (toIndex != null) {
if (toIndex > upcomingCount) {
// Jumping past the end
// Clear all upcoming; then behave like “no more songs”
queue.songs.splice(1); // remove all upcoming
if (!queue.autoplay) {
try {
queue.stop();
} catch {}
client.distube.voices.leave(interaction.guildId);
try {
const live = require("../../utils/liveLyricsManager");
await live.stop(interaction.guildId, { deleteThread: true });
} catch {}
return interaction.followUp(
`⏭️ Skipped past the end (${toIndex}). Queue empty — stopped and left.`
);
}
// Autoplay on: try to skip and let autoplay find a related track
try {
queue.skip(); // will trigger autoplay resolution
} catch {}
try {
const live = require("../../utils/liveLyricsManager");
await live.stop(interaction.guildId, { deleteThread: true });
} catch {}
return interaction.followUp(
`⏭️ Skipped past the end (${toIndex}). Autoplay will pick something.`
);
}
// Remove the tracks between current and target (keep current at index 0)
// Example: toIndex=1 -> remove none, well just skip once below.
if (toIndex > 1) {
// delete from position 1..(toIndex-1)
queue.songs.splice(1, toIndex - 1);
}
// Now the desired target is at index 1, skip once to play it
try {
queue.skip();
} catch (e) {
// If skip throws but autoplay is on, let autoplay do its thing
if (!queue.autoplay) throw e;
}
// Stop any active live-lyrics thread for the current song
try {
const live = require("../../utils/liveLyricsManager");
await live.stop(interaction.guildId, { deleteThread: true });
} catch {}
return interaction.followUp(
`⏭️ Jumped to track **#${toIndex}** in the queue.`
);
}
// Simple “skip next”
try {
queue.skip();
} catch (e) {
// If theres no next but autoplay is on, allow autoplay
if (!queue.autoplay) {
// Fallback: nothing to skip to
try {
queue.stop();
} catch {}
client.distube.voices.leave(interaction.guildId);
try {
const live = require("../../utils/liveLyricsManager");
await live.stop(interaction.guildId, { deleteThread: true });
} catch {}
return interaction.followUp(
"🏁 No more songs — stopped and left the voice channel."
);
}
}
try {
const live = require("../../utils/liveLyricsManager");
await live.stop(interaction.guildId, { deleteThread: true });
} catch {}
return interaction.followUp("⏭️ Skipped the current song!");
} catch (e) {
console.error("skip command failed:", e);
const msg = e?.message || "❌ Failed to skip.";
if (interaction.deferred || interaction.replied) {
return interaction.followUp({ content: msg, ephemeral: true });
}
return interaction.reply({ content: msg, ephemeral: true });
}
},
};