From e3abd24b918db507e2a78561159dfc49f837bf93 Mon Sep 17 00:00:00 2001 From: Timofei Galkin Date: Fri, 12 Jan 2024 15:27:26 +0300 Subject: [PATCH 1/9] feat(history): added new command Also, player loads default values from config --- djs-bot/commands/music/history.js | 63 +++++++++++++++++++++++++++++++ djs-bot/config.js | 11 ++++++ djs-bot/lib/MusicEvents.js | 9 +++++ djs-bot/lib/clients/Cosmicord.js | 14 ++++++- djs-bot/lib/clients/Erela.js | 14 ++++++- djs-bot/util/embeds.js | 21 +++++++++-- 6 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 djs-bot/commands/music/history.js diff --git a/djs-bot/commands/music/history.js b/djs-bot/commands/music/history.js new file mode 100644 index 000000000..107da1015 --- /dev/null +++ b/djs-bot/commands/music/history.js @@ -0,0 +1,63 @@ +const colors = require("colors"); +const { EmbedBuilder } = require("discord.js"); +const SlashCommand = require("../../lib/SlashCommand"); +const { historyEmbed } = require("../../util/embeds"); + +const command = new SlashCommand() + .setName("history") + .setDescription("Remove song history (toggle)") + .setRun(async (client, interaction) => { + let channel = await client.getChannel(client, interaction); + if (!channel) { + return; + } + + let player; + if (client.manager.Engine) { + player = client.manager.Engine.players.get(interaction.guild.id); + } else { + return interaction.reply({ + embeds: [ + new EmbedBuilder() + .setColor("Red") + .setDescription("Lavalink node is not connected"), + ], + }); + } + + if (!player) { + return interaction.reply({ + embeds: [ + new EmbedBuilder() + .setColor("Red") + .setDescription("There's nothing playing in the queue"), + ], + ephemeral: true, + }); + } + + const history = player.get("history"); + player.set("requester", interaction.guild.members.me); + + if (!history) { + player.set("history", true); + } else { + player.set("history", false); + } + + client.warn( + `Player: ${ player.options.guild } | [${ colors.blue( + "history", + ) }] has been [${ colors.blue(!history? "ENABLED" : "DISABLED") }] in ${ + client.guilds.cache.get(player.options.guild) + ? client.guilds.cache.get(player.options.guild).name + : "a guild" + }`, + ); + + const ret = await interaction.reply({ embeds: [historyEmbed({history})], fetchReply: true }); + if (ret) setTimeout(() => ret.delete().catch(client.warn), 20000); + return ret; + }); + +module.exports = command; \ No newline at end of file diff --git a/djs-bot/config.js b/djs-bot/config.js index a5de6a2d6..78eeb6c42 100644 --- a/djs-bot/config.js +++ b/djs-bot/config.js @@ -66,6 +66,7 @@ module.exports = { * Music engine to use * @type {keyof typeof import("./lib/clients/MusicClient").Engine} */ musicEngine: "Erela", + /** * Nodes to connect to * @type {import("erela.js").Node[]} */ @@ -121,6 +122,7 @@ module.exports = { * 0 = No debug logging (production), 1 = Standard Logging (debug info), 2 = Development (everything) * @type {number} */ OPLevel: 1, + /** * Color of the embeds (can also be hex) * @type {import('discord.js').ColorResolvable} */ @@ -158,8 +160,17 @@ module.exports = { } ], }, + /** * This icon will be in every embed's author field, if you don't want it, just leave it blank or "undefined" * @type {string} */ iconURL: undefined, + + defaultPlayerValues: { + twentyFourSeven: false, + autoLeave: false, + autoPause: true, + autoQueue: false, + history: false, + } }; diff --git a/djs-bot/lib/MusicEvents.js b/djs-bot/lib/MusicEvents.js index 57a7027d0..3dd6cf7fe 100644 --- a/djs-bot/lib/MusicEvents.js +++ b/djs-bot/lib/MusicEvents.js @@ -4,6 +4,7 @@ const colors = require("colors"); const { getClient } = require("../bot"); const socket = require("../api/v1/dist/ws/eventsHandler"); const { updateControlMessage, updateNowPlaying } = require("../util/controlChannel"); +const { trackStartedEmbed } = require("../util/embeds"); // entries in this map should be removed when bot disconnected from vc const progressUpdater = new Map(); @@ -71,6 +72,14 @@ function handleTrackStart({ player, track }) { if (!playedTracks.includes(track)) playedTracks.push(track); + const history = player.get("history"); + if (history) { + client.channels.cache + .get(player.textChannel) + .send({ embeds: [trackStartedEmbed({ track, player, title: 'Played track' })]}) + .catch(client.warn); + } + updateNowPlaying(player, track); updateControlMessage(player.guild, track); diff --git a/djs-bot/lib/clients/Cosmicord.js b/djs-bot/lib/clients/Cosmicord.js index 14763e4d7..aaf5be66f 100644 --- a/djs-bot/lib/clients/Cosmicord.js +++ b/djs-bot/lib/clients/Cosmicord.js @@ -20,8 +20,18 @@ class CosmicordPlayerExtended extends CosmiPlayer { /** @type {CosmicordExtended} */ this.cosmicord = cosmicordExtended; - /** @type {boolean} */ - this.twentyFourSeven = false; + + getConfig().then((config) => { + const defaultValues = config.defaultPlayerValues; + + if (typeof defaultValues === "object") { + const defaultKeys = Object.keys(config.defaultPlayerValues); + + defaultKeys.forEach((key) => { + this.set(key, defaultValues[key]); + }) + } + }); } /** The guild id of the player */ diff --git a/djs-bot/lib/clients/Erela.js b/djs-bot/lib/clients/Erela.js index 8f3f8e04d..c4027eb3c 100644 --- a/djs-bot/lib/clients/Erela.js +++ b/djs-bot/lib/clients/Erela.js @@ -13,6 +13,7 @@ const { default: AppleMusic } = require("better-erela.js-apple"); // <--- const { updateControlMessage } = require("../../util/controlChannel"); const { handleTrackStart } = require("../MusicEvents"); const { pause } = require("../../util/player"); +const getConfig = require("../../util/getConfig"); Structure.extend( "Player", @@ -21,7 +22,18 @@ Structure.extend( /** @returns {import("erela.js").Player} */ constructor(...props) { super(...props); - this.twentyFourSeven = false; + + getConfig().then((config) => { + const defaultValues = config.defaultPlayerValues; + + if (typeof defaultValues === "object") { + const defaultKeys = Object.keys(config.defaultPlayerValues); + + defaultKeys.forEach((key) => { + this.set(key, defaultValues[key]); + }) + } + }); } /** diff --git a/djs-bot/util/embeds.js b/djs-bot/util/embeds.js index 0a31f64f1..e18fa0615 100644 --- a/djs-bot/util/embeds.js +++ b/djs-bot/util/embeds.js @@ -63,21 +63,23 @@ const embedClearedQueue = () => /** * @typedef {object} TrackStartedEmbedParams * @property {import("cosmicord.js").CosmiTrack=} track + * @property {import("../lib/clients/MusicClient").CosmicordPlayerExtended} player + * @property {string=} title * * @param {TrackStartedEmbedParams} */ -const trackStartedEmbed = ({ track, player } = {}) => { +const trackStartedEmbed = ({ track, player, title = 'Now playing' } = {}) => { const client = getClient(); const embed = new EmbedBuilder().setColor(client.config.embedColor); if (track) { - embed.setAuthor({ name: "Now playing", iconURL: client.config.iconURL }) + embed.setAuthor({ name: title, iconURL: client.config.iconURL }) .setDescription(`[${track.title}](${track.uri})`) .addFields([ { name: "Requested by", - value: `${track.requester}`, + value: `${track.requester ?? 'ʕ•ᴥ•ʔ'}`, inline: true, }, { @@ -281,6 +283,18 @@ const autoQueueEmbed = ({ autoQueue }) => { }); }; +const historyEmbed = ({ history }) => { + const client = getClient(); + return new EmbedBuilder() + .setColor(client.config.embedColor) + .setDescription(`**History is** \`${!history ? "ON" : "OFF"}\``) + .setFooter({ + text: `Music history will ${ + !history ? "no longer be" : "now be automatically" + } removed.`, + }); +}; + /** * @param {import("../lib/clients/MusicClient").CosmicordPlayerExtended} player * @param {EmbedBuilder} embed @@ -328,6 +342,7 @@ module.exports = { addQueueEmbed, loadedPlaylistEmbed, autoQueueEmbed, + historyEmbed, addPlayerStateFooter, getButtons, embedNotEnoughSong, From 67ed8051fb927fee4a7a1e4709e9b7b05cb5f406 Mon Sep 17 00:00:00 2001 From: Timofei Galkin Date: Fri, 12 Jan 2024 15:28:09 +0300 Subject: [PATCH 2/9] chore: bumped version --- djs-bot/package-lock.json | 4 ++-- djs-bot/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/djs-bot/package-lock.json b/djs-bot/package-lock.json index 51955002c..fba2ef027 100644 --- a/djs-bot/package-lock.json +++ b/djs-bot/package-lock.json @@ -1,12 +1,12 @@ { "name": "discord-musicbot", - "version": "5.4.3", + "version": "5.5.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "discord-musicbot", - "version": "5.4.3", + "version": "5.5.0", "license": "CUSTOM", "dependencies": { "@fastify/cors": "^8.3.0", diff --git a/djs-bot/package.json b/djs-bot/package.json index b92da68e3..3104906ad 100644 --- a/djs-bot/package.json +++ b/djs-bot/package.json @@ -1,7 +1,7 @@ { "description": "", "main": "index.js", - "version": "5.4.3", + "version": "5.5.0", "name": "discord-musicbot", "scripts": { "guild": "npm run api-build && node scripts/guild", From 923c56eba9d0eb2518bf8d06b2a22518e883e551 Mon Sep 17 00:00:00 2001 From: Timofei Galkin Date: Fri, 12 Jan 2024 15:32:32 +0300 Subject: [PATCH 3/9] changed command description --- djs-bot/commands/music/history.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/djs-bot/commands/music/history.js b/djs-bot/commands/music/history.js index 107da1015..2987caf4e 100644 --- a/djs-bot/commands/music/history.js +++ b/djs-bot/commands/music/history.js @@ -5,7 +5,7 @@ const { historyEmbed } = require("../../util/embeds"); const command = new SlashCommand() .setName("history") - .setDescription("Remove song history (toggle)") + .setDescription("Keep song history in chat (toggle)") .setRun(async (client, interaction) => { let channel = await client.getChannel(client, interaction); if (!channel) { From c6200c3a05395ccf7a51af806c75d5b2d3dbe482 Mon Sep 17 00:00:00 2001 From: Timofei Galkin Date: Fri, 12 Jan 2024 15:48:43 +0300 Subject: [PATCH 4/9] Added missing requester --- djs-bot/commands/music/history.js | 2 +- djs-bot/commands/music/play.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/djs-bot/commands/music/history.js b/djs-bot/commands/music/history.js index 2987caf4e..9f745e83b 100644 --- a/djs-bot/commands/music/history.js +++ b/djs-bot/commands/music/history.js @@ -60,4 +60,4 @@ const command = new SlashCommand() return ret; }); -module.exports = command; \ No newline at end of file +module.exports = command; diff --git a/djs-bot/commands/music/play.js b/djs-bot/commands/music/play.js index 1ad626e8e..85728a0dc 100644 --- a/djs-bot/commands/music/play.js +++ b/djs-bot/commands/music/play.js @@ -125,9 +125,10 @@ const command = new SlashCommand() } if (res.loadType === "TRACK_LOADED" || res.loadType === "SEARCH_RESULT") { + player.set("requester", interaction.guild.members.me); addTrack(player, res.tracks[0]); - if (!player.playing && !player.paused && !player.queue.size) { + if (!player.playing && !player.paused && !player.queue.size) { player.play(); } @@ -144,6 +145,7 @@ const command = new SlashCommand() } if (res.loadType === "PLAYLIST_LOADED") { + player.set("requester", interaction.guild.members.me); addTrack(player, res.tracks); if ( From d3c457364ac7507c9591ac71b4e6585ead965045 Mon Sep 17 00:00:00 2001 From: Timofei Galkin Date: Fri, 12 Jan 2024 15:50:16 +0300 Subject: [PATCH 5/9] Removed space --- djs-bot/commands/music/play.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/djs-bot/commands/music/play.js b/djs-bot/commands/music/play.js index 85728a0dc..5ce524f0d 100644 --- a/djs-bot/commands/music/play.js +++ b/djs-bot/commands/music/play.js @@ -128,7 +128,7 @@ const command = new SlashCommand() player.set("requester", interaction.guild.members.me); addTrack(player, res.tracks[0]); - if (!player.playing && !player.paused && !player.queue.size) { + if (!player.playing && !player.paused && !player.queue.size) { player.play(); } From 944ac8964e7386ec3f4c519a1d4634887ff1338a Mon Sep 17 00:00:00 2001 From: Neko-Life Date: Fri, 12 Jan 2024 23:48:43 +0700 Subject: [PATCH 6/9] move to utils --- djs-bot/lib/clients/Cosmicord.js | 13 ++----------- djs-bot/lib/clients/Erela.js | 14 ++------------ djs-bot/util/musicManager.js | 20 ++++++++++++++++++++ 3 files changed, 24 insertions(+), 23 deletions(-) create mode 100644 djs-bot/util/musicManager.js diff --git a/djs-bot/lib/clients/Cosmicord.js b/djs-bot/lib/clients/Cosmicord.js index aaf5be66f..0d2155da3 100644 --- a/djs-bot/lib/clients/Cosmicord.js +++ b/djs-bot/lib/clients/Cosmicord.js @@ -8,6 +8,7 @@ const { Cosmicord, CosmiPlayer, CosmiNode } = require("cosmicord.js"); const { updateControlMessage } = require("../../util/controlChannel"); const { handleTrackStart } = require("../MusicEvents"); const { pause } = require("../../util/player"); +const { setDefaultPlayerConfig } = require("../../util/musicManager"); class CosmicordPlayerExtended extends CosmiPlayer { /** @@ -21,17 +22,7 @@ class CosmicordPlayerExtended extends CosmiPlayer { /** @type {CosmicordExtended} */ this.cosmicord = cosmicordExtended; - getConfig().then((config) => { - const defaultValues = config.defaultPlayerValues; - - if (typeof defaultValues === "object") { - const defaultKeys = Object.keys(config.defaultPlayerValues); - - defaultKeys.forEach((key) => { - this.set(key, defaultValues[key]); - }) - } - }); + setDefaultPlayerConfig(this); } /** The guild id of the player */ diff --git a/djs-bot/lib/clients/Erela.js b/djs-bot/lib/clients/Erela.js index c4027eb3c..fedb70893 100644 --- a/djs-bot/lib/clients/Erela.js +++ b/djs-bot/lib/clients/Erela.js @@ -13,7 +13,7 @@ const { default: AppleMusic } = require("better-erela.js-apple"); // <--- const { updateControlMessage } = require("../../util/controlChannel"); const { handleTrackStart } = require("../MusicEvents"); const { pause } = require("../../util/player"); -const getConfig = require("../../util/getConfig"); +const { setDefaultPlayerConfig } = require("../../util/musicManager"); Structure.extend( "Player", @@ -23,17 +23,7 @@ Structure.extend( constructor(...props) { super(...props); - getConfig().then((config) => { - const defaultValues = config.defaultPlayerValues; - - if (typeof defaultValues === "object") { - const defaultKeys = Object.keys(config.defaultPlayerValues); - - defaultKeys.forEach((key) => { - this.set(key, defaultValues[key]); - }) - } - }); + setDefaultPlayerConfig(this); } /** diff --git a/djs-bot/util/musicManager.js b/djs-bot/util/musicManager.js new file mode 100644 index 000000000..e151e72f9 --- /dev/null +++ b/djs-bot/util/musicManager.js @@ -0,0 +1,20 @@ +"use strict"; + +const { getClient } = require("../bot"); + +const setDefaultPlayerConfig = (instance) => { + const config = getClient().config; + const defaultValues = config.defaultPlayerValues; + + if (typeof defaultValues !== "object") return; + + const defaultKeys = Object.keys(config.defaultPlayerValues); + + defaultKeys.forEach((key) => { + instance.set(key, defaultValues[key]); + }); +}; + +module.exports = { + setDefaultPlayerConfig, +}; From 97fae17e295e792537d4183c13f588d594cbd9be Mon Sep 17 00:00:00 2001 From: Neko-Life Date: Fri, 12 Jan 2024 23:49:29 +0700 Subject: [PATCH 7/9] prevent cluttering control channel --- djs-bot/lib/MusicEvents.js | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/djs-bot/lib/MusicEvents.js b/djs-bot/lib/MusicEvents.js index 3dd6cf7fe..ff89f89f0 100644 --- a/djs-bot/lib/MusicEvents.js +++ b/djs-bot/lib/MusicEvents.js @@ -3,7 +3,11 @@ const colors = require("colors"); const { getClient } = require("../bot"); const socket = require("../api/v1/dist/ws/eventsHandler"); -const { updateControlMessage, updateNowPlaying } = require("../util/controlChannel"); +const { + updateControlMessage, + updateNowPlaying, + runIfNotControlChannel, +} = require("../util/controlChannel"); const { trackStartedEmbed } = require("../util/embeds"); // entries in this map should be removed when bot disconnected from vc @@ -60,6 +64,24 @@ function handleQueueUpdate({ guildId, player }) { socket.handleQueueUpdate({ guildId, player }); } +function sendTrackHistory({ player, track }) { + runIfNotControlChannel(player, () => { + const history = player.get("history"); + if (!history) return; + + const client = getClient(); + + client.channels.cache + .get(player.textChannel) + ?.send({ + embeds: [ + trackStartedEmbed({ track, player, title: "Played track" }), + ], + }) + .catch(client.warn); + }); +} + /** * @param {import("./MusicEvents").IHandleTrackStartParams} */ @@ -72,16 +94,9 @@ function handleTrackStart({ player, track }) { if (!playedTracks.includes(track)) playedTracks.push(track); - const history = player.get("history"); - if (history) { - client.channels.cache - .get(player.textChannel) - .send({ embeds: [trackStartedEmbed({ track, player, title: 'Played track' })]}) - .catch(client.warn); - } - updateNowPlaying(player, track); updateControlMessage(player.guild, track); + sendTrackHistory({ player, track }); socket.handleTrackStart({ player, track }); socket.handlePause({ guildId: player.guild, state: player.paused }); From 78777e7ab121d69a18c470fc0f255ceb954bdca2 Mon Sep 17 00:00:00 2001 From: Neko-Life Date: Fri, 12 Jan 2024 23:55:48 +0700 Subject: [PATCH 8/9] make util --- djs-bot/commands/music/history.js | 3 ++- djs-bot/util/message.d.ts | 3 +++ djs-bot/util/message.js | 13 +++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 djs-bot/util/message.d.ts create mode 100644 djs-bot/util/message.js diff --git a/djs-bot/commands/music/history.js b/djs-bot/commands/music/history.js index 9f745e83b..492c7cc44 100644 --- a/djs-bot/commands/music/history.js +++ b/djs-bot/commands/music/history.js @@ -2,6 +2,7 @@ const colors = require("colors"); const { EmbedBuilder } = require("discord.js"); const SlashCommand = require("../../lib/SlashCommand"); const { historyEmbed } = require("../../util/embeds"); +const { deleteMessageDelay } = require("../../util/message"); const command = new SlashCommand() .setName("history") @@ -56,7 +57,7 @@ const command = new SlashCommand() ); const ret = await interaction.reply({ embeds: [historyEmbed({history})], fetchReply: true }); - if (ret) setTimeout(() => ret.delete().catch(client.warn), 20000); + deleteMessageDelay(ret); return ret; }); diff --git a/djs-bot/util/message.d.ts b/djs-bot/util/message.d.ts new file mode 100644 index 000000000..b412ccddb --- /dev/null +++ b/djs-bot/util/message.d.ts @@ -0,0 +1,3 @@ +import { Message } from "discord.js"; + +export function deleteMessageDelay(message: Message, delay?: number): void; diff --git a/djs-bot/util/message.js b/djs-bot/util/message.js new file mode 100644 index 000000000..68d1870c9 --- /dev/null +++ b/djs-bot/util/message.js @@ -0,0 +1,13 @@ +"use strict"; + +const { getClient } = require("../bot"); + +const deleteMessageDelay = (message, delay = 20000) => { + if (!message) return; + + setTimeout(() => message.delete().catch(getClient().warn), delay); +}; + +module.exports = { + deleteMessageDelay, +}; From a4380349c14918579367191401284530008691ab Mon Sep 17 00:00:00 2001 From: Neko-Life Date: Sat, 13 Jan 2024 00:00:37 +0700 Subject: [PATCH 9/9] more efficient check --- djs-bot/lib/MusicEvents.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/djs-bot/lib/MusicEvents.js b/djs-bot/lib/MusicEvents.js index ff89f89f0..e2b49e8fb 100644 --- a/djs-bot/lib/MusicEvents.js +++ b/djs-bot/lib/MusicEvents.js @@ -65,10 +65,10 @@ function handleQueueUpdate({ guildId, player }) { } function sendTrackHistory({ player, track }) { - runIfNotControlChannel(player, () => { - const history = player.get("history"); - if (!history) return; + const history = player.get("history"); + if (!history) return; + runIfNotControlChannel(player, () => { const client = getClient(); client.channels.cache