feat(bot): add NodeJS implementation and deploy script
This commit is contained in:
98
src/structures/ErelaEvents.js
Normal file
98
src/structures/ErelaEvents.js
Normal file
@@ -0,0 +1,98 @@
|
||||
const logger = require('../utils/logger');
|
||||
const { EmbedBuilder } = require('discord.js'); // Import EmbedBuilder
|
||||
|
||||
module.exports = (client) => {
|
||||
if (!client || !client.manager) {
|
||||
logger.error("ErelaEvents requires a client with an initialized manager.");
|
||||
return;
|
||||
}
|
||||
|
||||
client.manager
|
||||
.on('nodeConnect', node => logger.info(`Node "${node.options.identifier}" connected.`))
|
||||
.on('nodeError', (node, error) => logger.error(`Node "${node.options.identifier}" encountered an error: ${error.message}`))
|
||||
.on('nodeDisconnect', node => logger.warn(`Node "${node.options.identifier}" disconnected.`))
|
||||
.on('nodeReconnect', node => logger.info(`Node "${node.options.identifier}" reconnecting.`))
|
||||
|
||||
.on('trackStart', (player, track) => {
|
||||
logger.info(`Track started in guild ${player.guild}: ${track.title} requested by ${track.requester?.tag || 'Unknown'}`);
|
||||
|
||||
// Find the text channel associated with the player (if stored)
|
||||
const channel = client.channels.cache.get(player.textChannel);
|
||||
if (channel) {
|
||||
const embed = new EmbedBuilder()
|
||||
.setColor('#0099ff')
|
||||
.setTitle('Now Playing')
|
||||
.setDescription(`[${track.title}](${track.uri})`)
|
||||
.addFields({ name: 'Requested by', value: `${track.requester?.tag || 'Unknown'}`, inline: true })
|
||||
.setTimestamp();
|
||||
if (track.thumbnail) {
|
||||
embed.setThumbnail(track.thumbnail);
|
||||
}
|
||||
|
||||
channel.send({ embeds: [embed] }).catch(e => logger.error(`Failed to send trackStart message: ${e.message}`));
|
||||
}
|
||||
})
|
||||
|
||||
.on('trackEnd', (player, track, payload) => {
|
||||
// Only log track end if it wasn't replaced (e.g., by skip or play next)
|
||||
// 'REPLACED' means another track started immediately after this one.
|
||||
if (payload && payload.reason !== 'REPLACED') {
|
||||
logger.info(`Track ended in guild ${player.guild}: ${track.title}. Reason: ${payload.reason}`);
|
||||
} else if (!payload) {
|
||||
logger.info(`Track ended in guild ${player.guild}: ${track.title}. Reason: Unknown/Finished`);
|
||||
}
|
||||
// Optional: Send a message when a track ends naturally
|
||||
// const channel = client.channels.cache.get(player.textChannel);
|
||||
// if (channel && payload && payload.reason === 'FINISHED') {
|
||||
// channel.send(`Finished playing: ${track.title}`);
|
||||
// }
|
||||
})
|
||||
|
||||
.on('trackError', (player, track, payload) => {
|
||||
logger.error(`Track error in guild ${player.guild} for track ${track?.title || 'Unknown'}: ${payload.error}`);
|
||||
const channel = client.channels.cache.get(player.textChannel);
|
||||
if (channel) {
|
||||
channel.send(`An error occurred while trying to play: ${track?.title || 'the track'}. Details: ${payload.exception?.message || 'Unknown error'}`).catch(e => logger.error(`Failed to send trackError message: ${e.message}`));
|
||||
}
|
||||
// Optionally destroy player or skip track on error
|
||||
// player.stop();
|
||||
})
|
||||
|
||||
.on('trackStuck', (player, track, payload) => {
|
||||
logger.warn(`Track stuck in guild ${player.guild} for track ${track?.title || 'Unknown'}. Threshold: ${payload.thresholdMs}ms`);
|
||||
const channel = client.channels.cache.get(player.textChannel);
|
||||
if (channel) {
|
||||
channel.send(`Track ${track?.title || 'the track'} seems stuck. Skipping...`).catch(e => logger.error(`Failed to send trackStuck message: ${e.message}`));
|
||||
}
|
||||
// Skip the track
|
||||
player.stop();
|
||||
})
|
||||
|
||||
.on('queueEnd', (player) => {
|
||||
logger.info(`Queue ended for guild ${player.guild}.`);
|
||||
const channel = client.channels.cache.get(player.textChannel);
|
||||
if (channel) {
|
||||
channel.send('Queue finished. Add more songs!').catch(e => logger.error(`Failed to send queueEnd message: ${e.message}`));
|
||||
}
|
||||
// Optional: Add a timeout before leaving the channel
|
||||
// setTimeout(() => {
|
||||
// if (player.queue.current) return; // Don't leave if something started playing again
|
||||
// player.destroy();
|
||||
// }, 180000); // 3 minutes
|
||||
player.destroy(); // Destroy player immediately when queue ends
|
||||
})
|
||||
|
||||
.on('playerCreate', player => logger.debug(`Player created for guild ${player.guild}`))
|
||||
.on('playerDestroy', player => logger.debug(`Player destroyed for guild ${player.guild}`))
|
||||
.on('playerMove', (player, oldChannel, newChannel) => {
|
||||
if (!newChannel) {
|
||||
logger.info(`Player for guild ${player.guild} disconnected (moved from channel ${oldChannel}). Destroying player.`);
|
||||
player.destroy();
|
||||
} else {
|
||||
logger.debug(`Player for guild ${player.guild} moved from channel ${oldChannel} to ${newChannel}`);
|
||||
player.setVoiceChannel(newChannel); // Update player's voice channel reference
|
||||
}
|
||||
});
|
||||
|
||||
logger.info("Erela.js event listeners attached.");
|
||||
};
|
||||
Reference in New Issue
Block a user