diff --git a/package-lock.json b/package-lock.json index 84860170e..3d70e41c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@lavaclient/spotify": "^3.1.0", "@vitalets/google-translate-api": "^9.2.0", "ascii-table": "0.0.9", + "axios": "^1.6.7", "btoa": "^1.2.1", "common-tags": "^1.8.2", "connect-mongo": "^5.1.0", @@ -1986,6 +1987,16 @@ "node": ">=8.0.0" } }, + "node_modules/axios": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "dependencies": { + "follow-redirects": "^1.15.4", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2554,6 +2565,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/erlpack/-/erlpack-0.1.4.tgz", "integrity": "sha512-CJYbkEvsB5FqCCu2tLxF1eYKi28PvemC12oqzJ9oO6mDFrFO9G9G7nNJUHhiAyyL9zfXTOJx/tOcrQk+ncD65w==", + "hasInstallScript": true, "license": "MIT", "optional": true, "dependencies": { @@ -3123,6 +3135,25 @@ "dev": true, "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -4400,6 +4431,11 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", @@ -5463,6 +5499,7 @@ "version": "0.1.9", "resolved": "https://registry.npmjs.org/zlib-sync/-/zlib-sync-0.1.9.tgz", "integrity": "sha512-DinB43xCjVwIBDpaIvQqHbmDsnYnSt6HJ/yiB2MZQGTqgPcwBSZqLkimXwK8BvdjQ/MaZysb5uEenImncqvCqQ==", + "hasInstallScript": true, "license": "MIT", "optional": true, "dependencies": { diff --git a/src/commands/music/pause.js b/src/commands/music/pause.js index 180bf74ba..f4d672946 100644 --- a/src/commands/music/pause.js +++ b/src/commands/music/pause.js @@ -34,5 +34,7 @@ function pause({ client, guildId }) { if (player.paused) return "The player is already paused."; player.pause(true); + // emiting a new event 'playerPaused' to handle voice channel status update + client.musicManager.emit('playerPaused', player, player.trackData) return "⏸️ Paused the music player."; } diff --git a/src/commands/music/resume.js b/src/commands/music/resume.js index 4d81aceb1..9190c6af2 100644 --- a/src/commands/music/resume.js +++ b/src/commands/music/resume.js @@ -33,5 +33,8 @@ function resumePlayer({ client, guildId }) { const player = client.musicManager.getPlayer(guildId); if (!player.paused) return "The player is already resumed"; player.resume(); + + // emiting a new event 'playerResume' to handle voice channel status update + client.musicManager.emit('playerResumed', player, player.trackData) return "▶️ Resumed the music player"; } diff --git a/src/commands/music/stop.js b/src/commands/music/stop.js index 60277209d..b0ef13862 100644 --- a/src/commands/music/stop.js +++ b/src/commands/music/stop.js @@ -34,5 +34,8 @@ async function stop({ client, guildId }) { const player = client.musicManager.getPlayer(guildId); player.disconnect(); await client.musicManager.destroyPlayer(guildId); + + // emiting a new event 'playerDestroy' to handle voice channel status reset + client.musicManager.emit('playerDestroy', player) return "🎶 The music player is stopped and queue has been cleared"; } diff --git a/src/handlers/lavaclient.js b/src/handlers/lavaclient.js index af1364d71..47715e73d 100644 --- a/src/handlers/lavaclient.js +++ b/src/handlers/lavaclient.js @@ -41,7 +41,7 @@ module.exports = (client) => { client.logger.debug(`Node "${node.id}" debug: ${message}`); }); - lavaclient.on("nodeTrackStart", (_node, queue, song) => { + lavaclient.on("nodeTrackStart", async (_node, queue, song) => { const fields = []; const embed = new EmbedBuilder() @@ -72,12 +72,47 @@ module.exports = (client) => { embed.setFields(fields); queue.data.channel.safeSend({ embeds: [embed] }); + + // update voice channel status with 'Now Playing' + await client.wait(1000) // waiting 1 sec, because channel id is null initially + await updateVoiceStatus(queue.player.channelId, `Playing **${song.title}**`, client) }); lavaclient.on("nodeQueueFinish", async (_node, queue) => { queue.data.channel.safeSend("Queue has ended."); await client.musicManager.destroyPlayer(queue.player.guildId).then(queue.player.disconnect()); + + // reset voice channel's status + await updateVoiceStatus(queue.player.channelId, '', client) }); + // for when player is paused, indicate 'paused' in the status + lavaclient.on('playerPaused', async (player, song) => { + await updateVoiceStatus(player.channelId, `Paused **${song.title}**`, client) + }) + // for when player is resumed, indicate 'playing' in the status + lavaclient.on('playerResumed', async (player, song) => { + await updateVoiceStatus(player.channelId, `Playing **${song.title}**`, client) + }) + // for when player is stopped, reset the status + lavaclient.on('playerDestroy', async (player) => { + await updateVoiceStatus(player.channelId, '', client) + }) return lavaclient; }; + +/** + * + * @param {string} channel The channel Id to update the status + * @param {string} status The status + * @param {import("discord.js").Client} client Bot's client + */ +async function updateVoiceStatus(channel, status, client) { + const url = `/channels/${channel}/voice-status`; + await client.rest.put(url, { + body: { + status: status + } + }) + .catch(() => { }); +} \ No newline at end of file