Skip to content
This repository has been archived by the owner on Sep 3, 2024. It is now read-only.

Commit

Permalink
feat: Added /seek command
Browse files Browse the repository at this point in the history
  • Loading branch information
mariusbegby committed Jul 16, 2023
1 parent c11fd9c commit 2a35c18
Showing 1 changed file with 168 additions and 0 deletions.
168 changes: 168 additions & 0 deletions commands/seek.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const { useQueue } = require('discord-player');
const { EmbedBuilder } = require('discord.js');
const { embedColors, embedIcons } = require('../config.json');

module.exports = {
data: new SlashCommandBuilder()
.setName('seek')
.setDescription('Seek to a specified duration in the current track.')
.setDMPermission(false)
.addStringOption((option) =>
option
.setName('duration')
.setDescription(
'Duration in format 00:00:00 (HH:mm:ss) to seek to.'
)
.setRequired(true)
),
run: async ({ interaction }) => {
if (!interaction.member.voice.channel) {
return await interaction.editReply({
embeds: [
new EmbedBuilder()
.setDescription(
`**${embedIcons.warning} Oops!**\nYou need to be in a voice channel to use this command.`
)
.setColor(embedColors.colorWarning)
]
});
}

const queue = useQueue(interaction.guild.id);

if (!queue) {
return await interaction.editReply({
embeds: [
new EmbedBuilder()
.setDescription(
`**${embedIcons.warning} Oops!**\nThere are no tracks in the queue and nothing currently playing. First add some tracks with \`/play\`!`
)
.setColor(embedColors.colorWarning)
]
});
}

if (!queue.currentTrack) {
return await interaction.editReply({
embeds: [
new EmbedBuilder()
.setDescription(
`**${embedIcons.warning} Oops!**\nThere is nothing currently playing. First add some tracks with \`/play\`!`
)
.setColor(embedColors.colorWarning)
]
});
}

const durationInput = interaction.options.getString('duration');
let durationArray = durationInput.split(':');

switch (durationArray.length) {
case 1:
durationArray.unshift('00', '00');
break;
case 2:
durationArray.unshift('00');
break;
default:
break;
}

if (durationArray.length === 0 || durationArray.length > 3) {
return await interaction.editReply({
embeds: [
new EmbedBuilder()
.setDescription(
`**${embedIcons.warning} Oops!**\nYou entered an invalid duration format, \`${durationString}\`.\n\nPlease use the format \`HH:mm:ss\`, \`mm:ss\` or \`ss\`, where \`HH\` is hours, \`mm\` is minutes and \`ss\` is seconds.\n\n**Examples:**\n` +
'- `/seek` **`1:24:12`** - Seek to 1 hour, 24 minutes and 12 seconds.\n' +
'- `/seek` **`3:27`** - Seek to 3 minutes and 27 seconds.\n' +
'- `/seek` **`42`** - Seek to 42 seconds.'
)
.setColor(embedColors.colorWarning)
]
});
}

durationArray = durationArray.map((value) => {
return value.padStart(2, '0');
});

const durationString = durationArray.join(':');

let validElements = durationArray.every((value) => {
return value.length === 2;
});

if (!validElements) {
return await interaction.editReply({
embeds: [
new EmbedBuilder()
.setDescription(
`**${embedIcons.warning} Oops!**\nYou entered an invalid duration format, \`${durationString}\`.\n\nPlease use the format \`HH:mm:ss\`, \`mm:ss\` or \`ss\`, where \`HH\` is hours, \`mm\` is minutes and \`ss\` is seconds.\n\n**Examples:**\n` +
'- `/seek` **`1:24:12`** - Seek to 1 hour, 24 minutes and 12 seconds.\n' +
'- `/seek` **`3:27`** - Seek to 3 minutes and 27 seconds.\n' +
'- `/seek` **`42`** - Seek to 42 seconds.'
)
.setColor(embedColors.colorWarning)
]
});
}

// Now array should only be 3 elements long, all with 2 characters, e.g. ['00', '00', '00'].
// Regex can now validate if this is a valid duration format. E.g. check if the first element is 0-23, second element is 0-59 and third element is 0-59.
const regex = new RegExp('([0-1][0-9]|2[0-3]):?[0-5][0-9]:?[0-5][0-9]');
const isValidDuration = regex.test(durationString);

if (!isValidDuration) {
return await interaction.editReply({
embeds: [
new EmbedBuilder()
.setDescription(
`**${embedIcons.warning} Oops!**\nYou entered an invalid duration format, \`${durationString}\`.\n\nPlease use the format \`HH:mm:ss\`, \`mm:ss\` or \`ss\`, where \`HH\` is hours, \`mm\` is minutes and \`ss\` is seconds.\n\n**Examples:**\n` +
'- `/seek` **`1:24:12`** - Seek to 1 hour, 24 minutes and 12 seconds.\n' +
'- `/seek` **`3:27`** - Seek to 3 minutes and 27 seconds.\n' +
'- `/seek` **`42`** - Seek to 42 seconds.'
)
.setColor(embedColors.colorWarning)
]
});
}

const currentTrackMaxDurationInMs = queue.currentTrack.durationMS;
const durationInMilliseconds =
durationArray[0] * 3600000 +
durationArray[1] * 60000 +
durationArray[2] * 1000;

if (durationInMilliseconds > currentTrackMaxDurationInMs - 1000) {
return await interaction.editReply({
embeds: [
new EmbedBuilder()
.setDescription(
`**${embedIcons.warning} Oops!**\nYou entered **\`${durationString}\`**, which is a duration that is longer than the duration for the current track.\n\nPlease try a duration that is less than the duration of the track (**\`${queue.currentTrack.duration}\`**).`
)
.setColor(embedColors.colorWarning)
]
});
}

queue.node.seek(durationInMilliseconds);
return await interaction.editReply({
embeds: [
new EmbedBuilder()
.setAuthor({
name:
interaction.member.nickname ||
interaction.user.username,
iconURL: interaction.user.avatarURL()
})
.setDescription(
`**${embedIcons.success} Seeking to duration**\nSeeking to **\`${durationString}\`** in current track.`
)
.setThumbnail(queue.currentTrack.thumbnail)
.setColor(embedColors.colorSuccess)
]
});
}
};

0 comments on commit 2a35c18

Please sign in to comment.