Add more commands
This commit is contained in:
@@ -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,
|
||||
},
|
||||
};
|
||||
30
commands/leave.js
Normal file
30
commands/leave.js
Normal file
@@ -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;
|
||||
@@ -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,
|
||||
|
||||
39
commands/previous.js
Normal file
39
commands/previous.js
Normal file
@@ -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;
|
||||
40
commands/skip.js
Normal file
40
commands/skip.js
Normal file
@@ -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;
|
||||
31
index.js
31
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);
|
||||
botClient.login(token);
|
||||
|
||||
module.exports.botClient = { botClient };
|
||||
@@ -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`);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
57
utils/logger.js
Normal file
57
utils/logger.js
Normal file
@@ -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;
|
||||
@@ -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 });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
68
utils/nowPlayingMessage.js
Normal file
68
utils/nowPlayingMessage.js
Normal file
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
8
utils/setStatus.js
Normal file
8
utils/setStatus.js
Normal file
@@ -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;
|
||||
Reference in New Issue
Block a user