I'm coding a multi-functions discord bot with music support and need some help with this single functionality.
There is a play command that sends an embed message containing music information and when the stop command is executed, it has to edit that embed sent by the play command.
This is a minimized version of my code (just as an example):
(...)
//PLAY COMMAND
if (options === 'play') {
const PlayEmbed = new MessageEmbed()
PlayEmbed.setColor('#007DD1')
PlayEmbed.setDescription(`${track.title}`)
//Send message
interaction.editReply({embeds: [PlayEmbed]}) // <--- The original reply
}
//STOP COMMAND
if (options === 'stop') {
const EndEmbed = new MessageEmbed()
EndEmbed.setColor('#007DD1')
EndEmbed.setDescription(`The music stopped!`)
//Edit message
interaction.editReply({embeds: [EndEmbed]}) // <--- Edit the original reply
}
(...)
In this case, ".editReply" just sends the new embed after the stop command. This may be a lot easier to do than I think it is and I know that I need to get the "play" interaction to edit the specific reply sent by that interaction, either via webhooks or another method, but I don't know-how. The subcommands "play" and "stop" are being handled this way: const options = interaction.options.getSubcommand();
Note: This answer is for Discord.js v13.3.0
Each command is in a different if
block. When you send the play
command, the bot will edit the reply, as intended. Once it finishes that, it checks itself against the stop command. stop
does not match play
and the code moves on. The reason why it's not editing the reply you want it to is because you're using a different Interaction each time. The first Interaction is for the play command and as stated before, since play
does not match stop
, the code moves on, discarding the Interaction.
A solution to this is to use a Set and map the member's ID to the channel ID and the reply ID. However, this only works if the message is not ephemeral ("Only you can see this"). The solution works like this:
const plays = new Map();
(...)
//PLAY COMMAND
if (options === 'play') {
(...)
interaction.editReply({embeds: [PlayEmbed]})
plays.set(interaction.member.id, [interaction.channel.id, interaction.fetchReply().id])
}
//STOP COMMAND
if (options === 'stop') {
(...)
let channel = client.channels.cache.get(plays[interaction.member.id].0);
// Fetch the messages before we can access any of them
channel.messages.fetch();
channel.messages.cache.get(plays[interaction.member.id].1).edit({embeds: [EndEmbed]})
}
One caveat to this code is that if the user hasn't ran the play command, plays[interaction.member.id]
will return undefined and likely result in an error.