diff --git a/.eslintrc.js b/.eslintrc.js index 0ebed05..6536e05 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -32,5 +32,6 @@ module.exports = { 'no-multiple-empty-lines': ['error', { max: 1, maxEOF: 0 }], 'no-duplicate-imports': ['error', { includeExports: true }], 'eol-last': ['error', 'never'], + 'linebreak-style': 0, }, }; \ No newline at end of file diff --git a/commands/leave.js b/commands/leave.js new file mode 100644 index 0000000..e07c233 --- /dev/null +++ b/commands/leave.js @@ -0,0 +1,30 @@ +// leaveCommand.js +const { getVoiceConnection } = require('@discordjs/voice'); +const { intervalMap } = require('../utils/nowPlayingMessage'); // Import the intervalMap from the nowPlayingMessage module +const ConsolerLogger = require('../utils/logger'); + +const logger = new ConsolerLogger(); +async function leaveCommand(interaction) { + await interaction.deferReply(); + + try { + const guildId = interaction.guild.id; + const connection = getVoiceConnection(guildId); + + if (!connection) { + return interaction.followUp('I am not currently in a voice channel.'); + } + + // Clear the interval for updating the progress bar + const interval = intervalMap.get(guildId); + clearInterval(interval); + + connection.destroy(); + return interaction.followUp('I have left the voice channel.'); + } catch (error) { + logger.error(error); + return interaction.followUp('An error occurred while trying to leave the voice channel.'); + } +} + +module.exports.leaveCommand = leaveCommand; \ No newline at end of file diff --git a/commands/play.js b/commands/play.js index 92cb15b..39ed5c1 100644 --- a/commands/play.js +++ b/commands/play.js @@ -27,10 +27,11 @@ async function playCommand(interaction) { if (musicQueue.getQueue(interaction.guild.id).length > 0) { musicQueue.removeFromQueue(interaction.guild.id); + musicQueue.addToQueue(interaction.guild.id, song, true); + } else { + musicQueue.addToQueue(interaction.guild.id, song); } - musicQueue.addToQueue(interaction.guild.id, song); - musicPlayer( interaction.guild.id, connection, diff --git a/commands/previous.js b/commands/previous.js new file mode 100644 index 0000000..c543cf3 --- /dev/null +++ b/commands/previous.js @@ -0,0 +1,39 @@ +const { joinVoiceChannel } = require('@discordjs/voice'); +const musicQueue = require('../musicQueue'); +const { musicPlayer } = require('../utils/musicPlayer'); + +function previousCommand(interaction) { + // Get the server queue + const serverQueue = musicQueue.getQueue(interaction.guild.id); + + const voiceChannel = interaction.member.voice.channel; + + if (!voiceChannel) { + return interaction.followUp( + 'You must be in a voice channel to use this command.', + ); + } + + const connection = joinVoiceChannel({ + channelId: voiceChannel.id, + guildId: interaction.guild.id, + adapterCreator: interaction.guild.voiceAdapterCreator, + selfDeaf: false, + selfMute: false, + }); + + // Check if there is a previous song in the queue + if (serverQueue.previous === undefined) { + return interaction.reply('There is no previous song to go back to!'); + } + + // Add the previous song back to the front of the queue + musicQueue.addToQueue(interaction.guild.id, serverQueue.previous, true); + + // Play the previous song + musicPlayer(interaction.guild.id, connection, interaction); + + return interaction.reply('Went back to the previous song!'); +} + +module.exports.previousCommand = previousCommand; \ No newline at end of file diff --git a/commands/skip.js b/commands/skip.js new file mode 100644 index 0000000..739e071 --- /dev/null +++ b/commands/skip.js @@ -0,0 +1,40 @@ +const { joinVoiceChannel } = require('@discordjs/voice'); +const musicQueue = require('../musicQueue'); +const { musicPlayer } = require('../utils/musicPlayer'); + +async function skipCommand(interaction) { + // Get the server queue + interaction.deferReply(); + const serverQueue = musicQueue.getQueue(interaction.guild.id); + + const voiceChannel = interaction.member.voice.channel; + + if (!voiceChannel) { + return interaction.followUp( + 'You must be in a voice channel to use this command.', + ); + } + + const connection = joinVoiceChannel({ + channelId: voiceChannel.id, + guildId: interaction.guild.id, + adapterCreator: interaction.guild.voiceAdapterCreator, + selfDeaf: false, + selfMute: false, + }); + + // Check if there are any songs in the queue + if (serverQueue.length === 0) { + return interaction.reply('There are no songs in the queue to skip!'); + } + + // Remove the current song from the queue + musicQueue.removeFromQueue(interaction.guild.id); + + // Play the next song + await musicPlayer(interaction.guild.id, connection, interaction); + + return interaction.reply('Skipped to the next song!'); +} + +module.exports.skipCommand = skipCommand; \ No newline at end of file diff --git a/index.js b/index.js index 78f9545..ac41a20 100644 --- a/index.js +++ b/index.js @@ -7,12 +7,17 @@ const { queueCommand } = require('./commands/queue'); const { stopCommand } = require('./commands/stop'); const { pauseCommand, unpauseCommand } = require('./commands/pauseResume'); const { toggleLoopCommand } = require('./commands/loop'); +const { skipCommand } = require('./commands/skip'); +const { leaveCommand } = require('./commands/leave'); +const { previousCommand } = require('./commands/previous'); const { ReAuth } = require('./reAuthenticate'); +const ConsolerLogger = require('./utils/logger'); const { clientId } = process.parsed; const { token } = process.parsed; -const client = new Client({ +const logger = new ConsolerLogger(); +const botClient = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, @@ -22,14 +27,14 @@ const client = new Client({ ], }); -client.on('ready', async () => { - console.log(`Logged in as ${client.user.tag}!`); - client.user.setActivity('Use /play to play music.'); +botClient.on('ready', async () => { + logger.info(`Logged in as ${botClient.user.tag}!`); + botClient.user.setActivity('League of Legends', 0); await registerCommands(clientId, token); }); -client.on('voiceStateUpdate', (oldState) => { +botClient.on('voiceStateUpdate', (oldState) => { const voiceChannel = oldState.channel; if (voiceChannel && voiceChannel.members.size === 1) { const connection = getVoiceConnection(voiceChannel.guild.id); @@ -40,13 +45,13 @@ client.on('voiceStateUpdate', (oldState) => { } }); -client.on('interactionCreate', async (interaction) => { +botClient.on('interactionCreate', async (interaction) => { if (!interaction.isCommand()) return; const { commandName } = interaction; if (commandName === 'play') { - await playCommand(interaction, client); + await playCommand(interaction, botClient); } else if (commandName === 'queue') { await queueCommand(interaction); } else if (commandName === 'pause') { @@ -57,13 +62,21 @@ client.on('interactionCreate', async (interaction) => { await toggleLoopCommand(interaction); } else if (commandName === 'stop') { await stopCommand(interaction); + } else if (commandName === 'leave') { + await leaveCommand(interaction); + } else if (commandName === 'skip') { + await skipCommand(interaction); + } else if (commandName === 'previous') { + await previousCommand(interaction); } }); -client.on('messageCreate', async (message) => { +botClient.on('messageCreate', async (message) => { if (message.content === 'reauth') { await ReAuth(); } }); -client.login(token); \ No newline at end of file +botClient.login(token); + +module.exports.botClient = { botClient }; \ No newline at end of file diff --git a/maintenance.js b/maintenance.js index 5c74ea6..a48e21f 100644 --- a/maintenance.js +++ b/maintenance.js @@ -1,44 +1,47 @@ +/* eslint-disable no-shadow */ const { exec } = require('child_process'); const schedule = require('node-schedule'); +const ConsolerLogger = require('./utils/logger'); -const repoUrl = 'https://github.com/Myxelium/Lunaris/'; const localRepoPath = '/home/pi/Lunaris/'; const processName = 'index.js'; +const logger = new ConsolerLogger(); + schedule.scheduleJob('0 1 * * *', () => { - exec(`cd ${localRepoPath} && git fetch`, (error, stdout, stderr) => { - if (error) { - console.error(`exec error: ${error}`); - return; - } - exec(`cd ${localRepoPath} && git rev-list HEAD...origin/master --count`, (error, stdout, stderr) => { - if (error) { - console.error(`exec error: ${error}`); - return; - } - if (parseInt(stdout) > 0) { - exec(`pm2 stop ${processName}`, (error, stdout, stderr) => { - if (error) { - console.error(`exec error: ${error}`); - return; - } - exec(`cd ${localRepoPath} && git pull`, (error, stdout, stderr) => { - if (error) { - console.error(`exec error: ${error}`); - return; - } - const now = new Date(); - console.log(`Repository updated at ${now.toLocaleString()}`); - exec(`pm2 start ${processName}`, (error, stdout, stderr) => { - if (error) { - console.error(`exec error: ${error}`); - return; - } - console.log(`${processName} started`); - }); - }); - }); - } - }); - }); -}); + exec(`cd ${localRepoPath} && git fetch`, (error) => { + if (error) { + logger.error(`exec error: ${error}`); + return; + } + exec(`cd ${localRepoPath} && git rev-list HEAD...origin/master --count`, (error, stdout) => { + if (error) { + logger.error(`exec error: ${error}`); + return; + } + if (parseInt(stdout, 10) > 0) { + exec(`pm2 stop ${processName}`, (error) => { + if (error) { + logger.error(`exec error: ${error}`); + return; + } + exec(`cd ${localRepoPath} && git pull`, (error) => { + if (error) { + logger.error(`exec error: ${error}`); + return; + } + const now = new Date(); + logger.log(`Repository updated at ${now.toLocaleString()}`); + exec(`pm2 start ${processName}`, (error) => { + if (error) { + logger.error(`exec error: ${error}`); + return; + } + logger.log(`${processName} started`); + }); + }); + }); + } + }); + }); +}); \ No newline at end of file diff --git a/musicQueue.js b/musicQueue.js index c56d07d..a017da8 100644 --- a/musicQueue.js +++ b/musicQueue.js @@ -6,12 +6,18 @@ class MusicQueue { this.looping = new Map(); } - addToQueue(guildId, song) { + addToQueue(guildId, song, front = false) { if (!this.queue.has(guildId)) { this.queue.set(guildId, []); } - this.queue.get(guildId).push(song); + if (front) { + // Add the song to the front of the queue + this.queue.get(guildId).unshift(song); + } else { + // Add the song to the end of the queue + this.queue.get(guildId).push(song); + } } async removeFromQueue(guildId) { @@ -38,6 +44,15 @@ class MusicQueue { return this.queue.get(guildId); } + async addToQueueFirst(guildId, song) { + if (!this.queue.has(guildId)) { + this.queue.set(guildId, []); + } + + this.removeFromQueue(guildId); + this.queue.get(guildId).unshift(song); + } + enableLooping(guildId) { this.looping.set(guildId, true); } diff --git a/music_sources/spotify.js b/music_sources/spotify.js index 1ee94ed..c942e7f 100644 --- a/music_sources/spotify.js +++ b/music_sources/spotify.js @@ -1,14 +1,44 @@ +/* eslint-disable no-restricted-syntax */ +/* eslint-disable no-await-in-loop */ +// const playdl = require('play-dl'); +// const youtube = require('./youtube'); + const playdl = require('play-dl'); -// TODO ADD SPOTIFY SUPPORT -async function getStream(query) { +const youtube = require('./youtube'); +const musicQueue = require('../musicQueue'); // Import the musicQueue module + +async function getStream(query, guildId) { + // Check if the query is a Spotify playlist + if (playdl.sp_validate(query) === 'playlist') { + let firstTrack = {}; + // Get the playlist information + const playlistInfo = await playdl.spotify(query); + + // Loop through the tracks in the playlist + // Get the tracks from the fetched_tracks Map + const tracks = playlistInfo.fetched_tracks.get('1'); + + // Loop through the tracks in the playlist + for (const track of tracks) { + // save the first track in the queue + if (tracks.indexOf(track) === 0) { + firstTrack = await youtube.getStream(`${track.name} ${track.artists[0].name}`); + } else { + // Get a stream for the track using the youtube module + const song = await youtube.getStream(`${track.name} ${track.artists[0].name}`); + + // Add the song to the music queue + musicQueue.addToQueue(guildId, song); + } + } + + // Return null to indicate that a playlist was queued + return firstTrack; + } + + // Handle single tracks as before const trackInfo = await playdl.spotify(query); - - const searched = await play.search(`${trackInfo.name}`, { - limit: 1, - }); - - const stream = await play.stream(searched[0].url); - return stream; + return youtube.getStream(`${trackInfo.name} ${trackInfo.artists[0].name}`); } module.exports.getStream = getStream; \ No newline at end of file diff --git a/music_sources/youtube.js b/music_sources/youtube.js index ff7ac87..60fffc3 100644 --- a/music_sources/youtube.js +++ b/music_sources/youtube.js @@ -1,5 +1,8 @@ const ytsr = require('ytsr'); const playdl = require('play-dl'); +const ConsolerLogger = require('../utils/logger'); + +const logger = new ConsolerLogger(); async function getStream(query) { try { @@ -35,7 +38,15 @@ async function getStream(query) { : await playdl.video_info( `https://www.youtube.com/watch?v=${videoId}`, ); - console.log('\x1b[36m', ' Id: ', videoId, 'Alternative search:', usingYtsr); + + logger.info('Search request', { file: 'Youtube.JS', + Id: videoId, + alternativeSearch: usingYtsr, + length: usingYtsr + ? infoResult.items[0].duration + : infoResult.video_details.durationInSec / 60, + SearchQuery: query }); + return { title: (usingYtsr @@ -52,7 +63,7 @@ async function getStream(query) { userInput: query, }; } catch (error) { - console.log('\x1b[31m', error); + logger.error(error); return null; } } diff --git a/reAuthenticate.js b/reAuthenticate.js index 06ccab7..b286ddf 100644 --- a/reAuthenticate.js +++ b/reAuthenticate.js @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ const play = require('play-dl'); async function ReAuth() { @@ -8,10 +9,10 @@ async function ReAuth() { }, }); - console.log(`Soudncloud Client ID: ${clientID}`); + console.log(`Soundcloud Client ID: ${clientID}`); }); play.authorization(); } -module.exports.ReAuth = ReAuth; +module.exports.ReAuth = ReAuth; \ No newline at end of file diff --git a/utils/getMusicStream.js b/utils/getMusicStream.js index 83da29d..b4bebcd 100644 --- a/utils/getMusicStream.js +++ b/utils/getMusicStream.js @@ -14,7 +14,8 @@ async function getMusicStream(query) { stream = await spotify.getStream(query); songTitle = stream.title; songDuration = stream.duration; - stream = stream.stream; + stream = stream?.stream; + type = StreamType.Opus; } else if (query.includes('soundcloud.com')) { stream = await soundcloud.getStream(query); songTitle = stream.title; diff --git a/utils/logger.js b/utils/logger.js new file mode 100644 index 0000000..b74bacf --- /dev/null +++ b/utils/logger.js @@ -0,0 +1,57 @@ +/* eslint-disable no-console */ +function loggerDate() { + const date = new Date(); + const year = date.getFullYear(); + const month = date.getMonth() + 1; + const day = date.getDate(); + + const hours = date.getHours(); + const minutes = date.getMinutes(); + const seconds = date.getSeconds(); + + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; +} + +class ConsolerLogger { + constructor() { + this.colors = { + info: '\x1b[36m%s\x1b[0m', + success: '\x1b[32m%s\x1b[0m', + warning: '\x1b[33m%s\x1b[0m', + error: '\x1b[31m%s\x1b[0m', + register: '\x1b[35m', + add: '\x1b[36m', + log: '\x1b[37m', + }; + } + + info(...messages) { + console.log(this.colors.info, loggerDate(), ...messages); + } + + success(...messages) { + console.log(this.colors.success, loggerDate(), ...messages); + } + + warning(...messages) { + console.log(this.colors.warning, loggerDate(), ...messages); + } + + error(...messages) { + console.log(this.colors.error, loggerDate(), ...messages); + } + + register(...messages) { + console.log(this.colors.register, loggerDate(), ...messages); + } + + add(...messages) { + console.log(this.colors.add, loggerDate(), ...messages); + } + + log(...messages) { + console.log(this.colors.log, loggerDate(), ...messages); + } +} + +module.exports = ConsolerLogger; \ No newline at end of file diff --git a/utils/musicPlayer.js b/utils/musicPlayer.js index a328f51..6d6587d 100644 --- a/utils/musicPlayer.js +++ b/utils/musicPlayer.js @@ -10,80 +10,23 @@ const process = require('dotenv').config(); const { clientId } = process.parsed; -const { EmbedBuilder } = require('discord.js'); const musicQueue = require('../musicQueue'); -const { progressBar } = require('./progress'); +const { nowPlayingMessage, intervalMap, currentInteractionIds } = require('./nowPlayingMessage'); +const ConsolerLogger = require('./logger'); -const currentInteractionIds = new Map(); -const currentInteractions = new Map(); const oldConnections = []; const timeoutTimer = new Map(); - -// TODO FIX THIS SHIT!!! ISSUES WITH DISPLAYING NAME AND STATUS WHEN UPDATING -function nowPLayingMessage(interaction, song, oldInteractionId) { - progressBar(0, 0, true); - - if (interaction.commandName === 'play') { - interaction.followUp('~🎵~').then((message) => { - const songTitle = song.title; - // const embed = new EmbedBuilder() - // .setColor('#E0B0FF') - // .setTitle(`Now playing: ${songTitle}`) - // .setDescription( - // progressBar(song.duration, 10).progressBarString, - // ); - const embed = new EmbedBuilder() - .setColor('#E0B0FF') - .setTitle(`Now playing: ${songTitle}`); - - message.edit({ - embeds: [embed], - }); - - const inter = setInterval(async () => { - const { progressBarString, isDone } = progressBar( - song.duration, - 10, - ); - if (isDone || message.id !== oldInteractionId) { - // clearInterval(inter); - return; - } - - if (message.id != null && interaction.guild.id !== oldInteractionId) { - interaction.channel.messages.fetch().then(async (channel) => { - const filter = channel.filter((msg) => msg.author.id === clientId); - const latestMessage = await interaction.channel.messages.fetch(filter.first().id); - latestMessage.edit({ - embeds: [embed.setTitle(`Now playing: ${songTitle}`)], - }); - }); - } - }, 2000); - - currentInteractionIds.set(interaction.guild.id, interaction); - currentInteractions.set(interaction.guild.id, interaction.id); - }); - } -} +const logger = new ConsolerLogger(); async function musicPlayer(guildId, connection, interaction) { try { - const oldInteractions = await currentInteractions.get(interaction.guild.id); const oldInteractionId = await currentInteractionIds.get(interaction.guild.id); const serverQueue = musicQueue.getQueue(guildId); const oldConnection = oldConnections .find((guidConnection) => guidConnection[0] === interaction.guild.id); - - if (serverQueue.length === 0) { - oldConnection[1].destroy(); - } - const song = serverQueue[0]; - if (song.stream === undefined) { - musicQueue.removeFromQueue(guildId); - musicPlayer(guildId, connection); + if (!song || song.stream === undefined) { return; } @@ -97,30 +40,44 @@ async function musicPlayer(guildId, connection, interaction) { }, }); - player.play(resource); + if (!resource.ended) { + player.play(resource); + } else { + logger.warning('Song ended prematurely.', song.title); + } connection.subscribe(player); - nowPLayingMessage(interaction, song, oldInteractions); + nowPlayingMessage(interaction, song); oldConnections.push([interaction.guild.id, connection]); + // Add an event listener for the Idle event of the audio player player.on(AudioPlayerStatus.Idle, async () => { - console.log('Song ended:', song.title); - if (serverQueue.length !== 1) { - await musicQueue.removeFromQueue(guildId); - musicPlayer(guildId, connection, interaction); - } + logger.info(`Song ended: ${song.title}`, 'Started by:', interaction.user.username); + // Check if the audio resource has ended + if (resource.ended) { + // If the audio resource has ended, play the next song - // timeoutTimer.set(guildId, setTimeout(async () => { - // await musicQueue.removeFromQueue(guildId); - // connection.destroy(); - // }, 10000)); + if (serverQueue.length !== 0) { + await musicQueue.removeFromQueue(guildId); + musicPlayer(guildId, connection, interaction); + logger.info(`Playing next song...${serverQueue}`); + } else { + // If there are no more songs in the queue, destroy the connection + connection.destroy(); + logger.info('Connection destroyed.'); + // Clear the interval for updating the progress bar + const interval = intervalMap.get(interaction.guild.id); + clearInterval(interval); + } + } }); player.on(AudioPlayerStatus.Playing, () => { - console.log('pausing timer'); + logger.info(`Playing: ${song.title}, Started by: ${interaction.user.username}`); clearTimeout( + logger.info('Previous song timer cleared.'), timeoutTimer.get(guildId), ); }); @@ -130,13 +87,15 @@ async function musicPlayer(guildId, connection, interaction) { const { lastMessage } = oldInteractionId.channel; const filter = channel.filter((message) => message.author.id === clientId && message.id !== lastMessage.id); setTimeout(() => { - oldInteractionId.channel.bulkDelete(filter); + logger.info('Removing old messages...'); + oldInteractionId.channel.bulkDelete(filter) + .catch((error) => logger.error(error)); }, 1000); }); } } catch (error) { - console.error(error); - interaction.followUp('There was an error playing the song.'); + logger.error(error); + interaction.followUp('There was an error playing the song.', { ephemeral: true }); } } diff --git a/utils/nowPlayingMessage.js b/utils/nowPlayingMessage.js new file mode 100644 index 0000000..8118361 --- /dev/null +++ b/utils/nowPlayingMessage.js @@ -0,0 +1,68 @@ +const process = require('dotenv').config(); + +const { clientId } = process.parsed; +const { EmbedBuilder } = require('discord.js'); +const { progressBar } = require('./progress'); + +const currentInteractionIds = new Map(); +const currentInteractions = new Map(); +const messageTimerMap = new Map(); +const intervalMap = new Map(); // Add a new map to keep track of interval IDs + +function nowPlayingMessage(interaction, song, prematureEnd = false) { + const timeoutIDs = messageTimerMap.get(interaction.guild.id); + if (timeoutIDs) { + timeoutIDs.forEach((timeoutID) => clearTimeout(timeoutID)); + } + + if (interaction.commandName === 'play') { + interaction.followUp('~🎵~').then((message) => { + const songTitle = song.title; + const embed = new EmbedBuilder() + .setColor('#E0B0FF') + .setTitle(`Now playing: ${songTitle}`) + .setDescription( + progressBar(song.duration, 10).progressBarString, + ); + + message.edit({ + embeds: [embed], + }); + + const inter = setInterval(async () => { + const messageString = progressBar( + song.duration, + 10, + ); + + if (message.id != null) { + interaction.channel.messages.fetch().then(async (channel) => { + const filter = channel.filter((msg) => msg.author.id === clientId); + const latestMessage = await interaction.channel.messages.fetch(filter.first().id); + latestMessage.edit({ + embeds: [embed.setDescription(messageString.progressBarString)], + }); + }); + } + }, 1000); + + // Store the interval ID in the intervalMap + intervalMap.set(interaction.guild.id, inter); + + // Store the timeoutID in an array associated with the key + if (!messageTimerMap.has(interaction.guild.id) || !prematureEnd) { + messageTimerMap.set(interaction.guild.id, []); + } + + messageTimerMap.get(interaction.guild.id).push(inter); + progressBar(0, 0, true); + + currentInteractionIds.set(interaction.guild.id, interaction); + currentInteractions.set(interaction.guild.id, interaction.id); + }); + } +} + +module.exports.nowPlayingMessage = nowPlayingMessage; +module.exports.intervalMap = intervalMap; +module.exports.currentInteractionIds = currentInteractionIds; \ No newline at end of file diff --git a/utils/progress.js b/utils/progress.js index 896f576..d8b1ba1 100644 --- a/utils/progress.js +++ b/utils/progress.js @@ -30,8 +30,9 @@ const progressBar = (totalInMilliseconds, size, reset = false) => { totalTimeText = totalTimeText.slice(3); } - const progressBarString = `${elapsedTimeText} \`\`\`${progressText}${emptyProgressText}\`\`\` ${totalTimeText}`; // Creating and returning the bar + const progressBarString = `${elapsedTimeText} \`${progressText}${emptyProgressText}\` ${totalTimeText}`; // Creating and returning the bar return { progressBarString, isDone: percentage === 1 }; }; + module.exports.progressBar = progressBar; \ No newline at end of file diff --git a/utils/registerCommands.js b/utils/registerCommands.js index 651594b..e4a339d 100644 --- a/utils/registerCommands.js +++ b/utils/registerCommands.js @@ -1,6 +1,9 @@ const { SlashCommandBuilder } = require('@discordjs/builders'); const { REST } = require('@discordjs/rest'); const { Routes } = require('discord-api-types/v9'); +const ConsolerLogger = require('./logger'); + +const logger = new ConsolerLogger(); async function registerCommands(clientId, token) { const commands = [ @@ -32,6 +35,15 @@ async function registerCommands(clientId, token) { new SlashCommandBuilder() .setName('stop') .setDescription('Stops the current song!'), + new SlashCommandBuilder() + .setName('skip') + .setDescription('Skips the current song!'), + new SlashCommandBuilder() + .setName('leave') + .setDescription('Leaves the voice channel!'), + new SlashCommandBuilder() + .setName('previous') + .setDescription('Plays the previous song!'), ]; const rest = new REST({ @@ -40,15 +52,15 @@ async function registerCommands(clientId, token) { .setToken(token); try { - console.log('\x1b[35m', 'Started refreshing application (/) commands.'); + logger.register('Started refreshing application (/) commands.'); await rest.put(Routes.applicationCommands(clientId), { body: commands, }); - console.log('\x1b[35m', 'Successfully reloaded application (/) commands.'); + logger.register('Successfully reloaded application (/) commands.'); } catch (error) { - console.error(error); + logger.error('Failed to reload application (/) commands.'); } } diff --git a/utils/setStatus.js b/utils/setStatus.js new file mode 100644 index 0000000..80b41e5 --- /dev/null +++ b/utils/setStatus.js @@ -0,0 +1,8 @@ +const { botClient } = require('../index'); + +async function setStatus(status) { + await botClient.user.setActivity(status); +} + +module.exports.setStatus = setStatus; +module.exports.setStatus = setStatus; \ No newline at end of file