Skip to content

Commit

Permalink
(v1.5) Code refactoring, Plex playnext cmd & bug fixes
Browse files Browse the repository at this point in the history
+ Refactored code relating to searching and playing songs. This relates to both the regular system and via Plex optional feature.
+ Estimated code reduction of around 40%~ for play/search related commands versus v1.4 build.
+ New sharedFunctions.js utils file which houses new functions relating to searching and playing songs (relates to the general #4 goal).
+ Added a new /plex playnext command which functions similarly to the regular playnext command, but for the Plex feature (#52).
+ Adjusted the API endpoints that are used for Plex server requests, to more reliable and valid options.
+ Fixed bug #53 by encoding the query into a URI component for any web requests.
+ Bug #32 should be resolved after reworking code into functions and switching to a different endpoint for searching.
+ Config version remains unchanged.
  • Loading branch information
ThatGuyJacobee committed May 13, 2024
1 parent e5f74a5 commit c14f8e2
Showing 5 changed files with 442 additions and 688 deletions.
224 changes: 11 additions & 213 deletions commands/music/play.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require("dotenv").config();
const musicFuncs = require('../../utils/sharedFunctions.js')
const { SlashCommandBuilder } = require("@discordjs/builders");
const { ActionRowBuilder, EmbedBuilder, StringSelectMenuBuilder, StringSelectMenuOptionBuilder } = require("discord.js");
const { Player, QueryType } = require('discord-player');
@@ -20,43 +21,23 @@ module.exports = {
if (!interaction.member.voice.channelId) return await interaction.reply({ content: "❌ | You are not in a voice channel!", ephemeral: true });
if (interaction.guild.members.me.voice.channelId && interaction.member.voice.channelId !== interaction.guild.members.me.voice.channelId) return await interaction.reply({ content: "❌ | You are not in my voice channel!", ephemeral: true });

const player = Player.singleton();
const query = interaction.options.getString("music");
var checkqueue = player.nodes.get(interaction.guild.id);

if (!checkqueue) {
player.nodes.create(interaction.guild.id, {
leaveOnEmpty: client.config.leaveOnEmpty,
leaveOnEmptyCooldown: client.config.leaveOnEmptyCooldown,
leaveOnEnd: client.config.leaveOnEnd,
leaveOnEndCooldown: client.config.leaveOnEndCooldown,
leaveOnStop: client.config.leaveOnStop,
leaveOnStopCooldown: client.config.leaveOnStopCooldown,
selfDeaf: client.config.selfDeafen,
skipOnNoStream: true,
metadata: {
channel: interaction.channel,
requestedBy: interaction.user,
client: interaction.guild.members.me,
}
})
}

var queue = player.nodes.get(interaction.guild.id);
const player = Player.singleton();
await musicFuncs.getQueue(interaction);

try {
const search = await player.search(query, {
requestedBy: interaction.user,
searchEngine: QueryType.AUTO
})


//console.log(search)
if (!search || search.tracks.length == 0 || !search.tracks) {
return interaction.reply({ content: `❌ | Ooops... something went wrong, couldn't find the song with the requested query.`, ephemeral: true })
}

//Otherwise it has found so defer reply
await interaction.deferReply();
//console.log(search)

//If there is more than one search result
if (search.tracks.length >= 2 && !search.playlist) {
@@ -81,11 +62,10 @@ module.exports = {
actionmenu.components[0].addOptions(
new StringSelectMenuOptionBuilder()
.setLabel(result.title)
.setValue(`${!result.playlist ? 'song' : 'playlist' }_${result.url}`)
.setValue(`${!result.playlist ? 'song' : 'playlist' }_${result.url}_false`)
.setDescription(`Duration - ${result.duration}`)
.setEmoji(emojis[count-1])
)

count++
}

@@ -104,87 +84,7 @@ module.exports = {

//There is only one search result, play it direct
else {
try {
if (!queue.connection) await queue.connect(interaction.member.voice.channel);
}

catch (err) {
queue.delete();
return interaction.followUp({ content: `❌ | Ooops... something went wrong, couldn't join your channel.`, ephemeral: true })
}

try {
search.playlist ? queue.addTrack(search.tracks) : queue.addTrack(search.tracks[0])
}

catch (err) {
return interaction.followUp({ content: `❌ | Ooops... something went wrong, failed to add the track(s) to the queue.`, ephemeral: true })
}

if (!queue.isPlaying()) {
try {
await queue.node.play(queue.tracks[0]);
queue.node.setVolume(client.config.defaultVolume);
}

catch (err) {
return interaction.followUp({ content: `❌ | Ooops... something went wrong, there was a playback related error. Please try again.`, ephemeral: true })
}

if (search.playlist) {
const playlistembed = new EmbedBuilder()
.setAuthor({ name: interaction.client.user.tag, iconURL: interaction.client.user.displayAvatarURL() })
.setThumbnail(search.tracks[0].thumbnail)
.setColor(client.config.embedColour)
.setTitle(`Started playback ▶️`)
.setDescription(`Imported the **${search.tracks[0].playlist.title} ([Link](${search.tracks[0].playlist.url})) playlist** with **${search.tracks.length}** songs and started to play the queue!`)
.setTimestamp()
.setFooter({ text: `Requested by: ${interaction.user.discriminator != 0 ? interaction.user.tag : interaction.user.username}` })

interaction.followUp({ embeds: [playlistembed] })
}

else {
const playsongembed = new EmbedBuilder()
.setAuthor({ name: interaction.client.user.tag, iconURL: interaction.client.user.displayAvatarURL() })
.setThumbnail(search.tracks[0].thumbnail)
.setColor(client.config.embedColour)
.setTitle(`Started playback ▶️`)
.setDescription(`Began playing the song **${search.tracks[0].title}** ${search.tracks[0].queryType != 'arbitrary' ? `([Link](${search.tracks[0].url}))` : ''}!`)
.setTimestamp()
.setFooter({ text: `Requested by: ${interaction.user.discriminator != 0 ? interaction.user.tag : interaction.user.username}` })

interaction.followUp({ embeds: [playsongembed] })
}
}

else {
if (search.playlist) {
const queueplaylistembed = new EmbedBuilder()
.setAuthor({ name: interaction.client.user.tag, iconURL: interaction.client.user.displayAvatarURL() })
.setThumbnail(search.tracks[0].thumbnail)
.setColor(client.config.embedColour)
.setTitle(`Added to queue ⏱️`)
.setDescription(`Imported the **${search.tracks[0].playlist.title} ([Link](${search.tracks[0].playlist.url})) playlist** with **${search.tracks.length}** songs!`)
.setTimestamp()
.setFooter({ text: `Requested by: ${interaction.user.discriminator != 0 ? interaction.user.tag : interaction.user.username}` })

interaction.followUp({ embeds: [queueplaylistembed] })
}

else {
const queuesongembed = new EmbedBuilder()
.setAuthor({ name: interaction.client.user.tag, iconURL: interaction.client.user.displayAvatarURL() })
.setThumbnail(search.tracks[0].thumbnail)
.setColor(client.config.embedColour)
.setTitle(`Added to queue ⏱️`)
.setDescription(`Began playing the song **${search.tracks[0].title}** ${search.tracks[0].queryType != 'arbitrary' ? `([Link](${search.tracks[0].url}))` : ''}!`)
.setTimestamp()
.setFooter({ text: `Requested by: ${interaction.user.discriminator != 0 ? interaction.user.tag : interaction.user.username}` })

interaction.followUp({ embeds: [queuesongembed] })
}
}
await musicFuncs.addTracks(interaction, 'false', search, 'send')
}
}

@@ -199,28 +99,10 @@ client.on('interactionCreate', async (interaction) => {
if (!interaction.isStringSelectMenu()) return;
if (interaction.customId == "playsearch") {
const player = Player.singleton();
var checkqueue = player.nodes.get(interaction.guild.id);

if (!checkqueue) {
player.nodes.create(interaction.guild.id, {
leaveOnEmpty: client.config.leaveOnEmpty,
leaveOnEmptyCooldown: client.config.leaveOnEmptyCooldown,
leaveOnEnd: client.config.leaveOnEnd,
leaveOnEndCooldown: client.config.leaveOnEndCooldown,
leaveOnStop: client.config.leaveOnStop,
leaveOnStopCooldown: client.config.leaveOnStopCooldown,
selfDeaf: client.config.selfDeafen,
skipOnNoStream: true,
metadata: {
channel: interaction.channel,
requestedBy: interaction.user,
client: interaction.guild.members.me,
}
})
}

var queue = player.nodes.get(interaction.guild.id);
await musicFuncs.getQueue(interaction);
var allcomponents = interaction.values;
var getPlayNext = allcomponents[0].split('_')[2] != null && allcomponents[0].split('_')[2] == "true" ? true : false
//console.log(allcomponents)

try {
const search = await player.search(allcomponents[0].split('_')[1], {
@@ -235,91 +117,7 @@ client.on('interactionCreate', async (interaction) => {
//Defer update from menu interaction
await interaction.deferUpdate();

try {
if (!queue.connection) await queue.connect(interaction.member.voice.channel);
}

catch (err) {
queue.delete();
return interaction.followUp({ content: `❌ | Ooops... something went wrong, couldn't join your channel.`, ephemeral: true })
}

try {
search.playlist ? queue.addTrack(search.tracks) : queue.addTrack(search.tracks[0])
}

catch (err) {
return interaction.followUp({ content: `❌ | Ooops... something went wrong, failed to add the track(s) to the queue.`, ephemeral: true })
}

if (!queue.isPlaying()) {
try {
await queue.node.play(queue.tracks[0]);
queue.node.setVolume(client.config.defaultVolume);
}

catch (err) {
return interaction.followUp({ content: `❌ | Ooops... something went wrong, there was a playback related error. Please try again.`, ephemeral: true })
}

if (search.playlist) {
const playlistembed = new EmbedBuilder()
.setAuthor({ name: interaction.client.user.tag, iconURL: interaction.client.user.displayAvatarURL() })
.setThumbnail(search.tracks[0].thumbnail)
.setColor(client.config.embedColour)
.setTitle(`Started playback ▶️`)
.setDescription(`Imported the **${search.tracks[0].playlist.title} ([Link](${search.tracks[0].playlist.url})) playlist** with **${search.tracks.length}** songs and started to play the queue!`)
.setTimestamp()
.setFooter({ text: `Requested by: ${interaction.user.discriminator != 0 ? interaction.user.tag : interaction.user.username}` })

var sourceMessage = interaction.message
sourceMessage.edit({ embeds: [playlistembed], components: [] })
}

else {
const playsongembed = new EmbedBuilder()
.setAuthor({ name: interaction.client.user.tag, iconURL: interaction.client.user.displayAvatarURL() })
.setThumbnail(search.tracks[0].thumbnail)
.setColor(client.config.embedColour)
.setTitle(`Started playback ▶️`)
.setDescription(`Began playing the song **${search.tracks[0].title}** ${search.tracks[0].queryType != 'arbitrary' ? `([Link](${search.tracks[0].url}))` : ''}!`)
.setTimestamp()
.setFooter({ text: `Requested by: ${interaction.user.discriminator != 0 ? interaction.user.tag : interaction.user.username}` })

var sourceMessage = interaction.message
sourceMessage.edit({ embeds: [playsongembed], components: [] })
}
}

else {
if (search.playlist) {
const queueplaylistembed = new EmbedBuilder()
.setAuthor({ name: interaction.client.user.tag, iconURL: interaction.client.user.displayAvatarURL() })
.setThumbnail(search.tracks[0].thumbnail)
.setColor(client.config.embedColour)
.setTitle(`Added to queue ⏱️`)
.setDescription(`Imported the **${search.tracks[0].playlist.title} ([Link](${search.tracks[0].playlist.url})) playlist** with **${search.tracks.length}** songs!`)
.setTimestamp()
.setFooter({ text: `Requested by: ${interaction.user.discriminator != 0 ? interaction.user.tag : interaction.user.username}` })

var sourceMessage = interaction.message
sourceMessage.edit({ embeds: [queueplaylistembed], components: [] })
}

else {
const queuesongembed = new EmbedBuilder()
.setAuthor({ name: interaction.client.user.tag, iconURL: interaction.client.user.displayAvatarURL() })
.setThumbnail(search.tracks[0].thumbnail)
.setColor(client.config.embedColour)
.setTitle(`Added to queue ⏱️`)
.setDescription(`Began playing the song **${search.tracks[0].title}** ${search.tracks[0].queryType != 'arbitrary' ? `([Link](${search.tracks[0].url}))` : ''}!`)
.setTimestamp()
.setFooter({ text: `Requested by: ${interaction.user.discriminator != 0 ? interaction.user.tag : interaction.user.username}` })

var sourceMessage = interaction.message
sourceMessage.edit({ embeds: [queuesongembed], components: [] })
}
}
await musicFuncs.addTracks(interaction, getPlayNext, search, 'edit')
}

catch (err) {
Loading

0 comments on commit c14f8e2

Please sign in to comment.