Remove a response when reacting with an ❌ - node.js

I tried doing this and adapting it from discordjs.guide, but I've either adapted something wrongly or it isn't working in my context. I tried this:
botMessage.react('❌');
const filter = (reaction, user) => {
return ['❌'].includes(reaction.emoji.name);
};
botMessage.awaitReactions({ filter, max: 1, time: 60000, errors: ['time'] }).then(collected => {
const reaction = collected.first();
console.log('a')
if(reaction.emoji.name === '❌'){
console.log('x')
botMessage.delete(1);
}
}).catch(collected => {});
botMessage is the response from the bot, since I am using a message command.
neither of the console.log() output anything.
any help is grateful and thank you

All you have to do is add the GUILD_MESSAGE_REACTIONS intent:
const client = new Client({ intents: [Intents.FLAGS.GUILD_MESSAGE_REACTIONS /* other intents */] });

Related

[InteractionAlreadyReplied]: The reply to this interaction has already been sent or deferred

It says [InteractionAlreadyReplied]: The reply to this interaction has already been sent or deferred. But inreality i am using editReply
I am having issue in logging error, it works fine with try and else but it shows [InteractionAlreadyReplied]: The reply to this interaction has already been sent or deferred in catch (error). I even tried using followUp but still doesnt work, it keeps giving the same error and shuts the whole bot down.
module.exports = {
data: new SlashCommandBuilder()
.setName("chat-gpt")
.setDescription("chat-gpt-3")
.addStringOption(option =>
option.setName('prompt')
.setDescription('Ask Anything')
.setRequired(true)),
async execute(interaction, client) {
const prompt = interaction.options.getString('prompt');
await interaction.deferReply();
const configuration = new Configuration({
apiKey: "nvm",
});
const openai = new OpenAIApi(configuration);
const response = await openai.createCompletion({
model: 'text-davinci-003',
prompt: prompt,
max_tokens: 2048,
temperature: 0.7,
top_p: 1,
frequency_penalty: 0.0,
presence_penalty: 0.0,
});
let responseMessage = response.data.choices[0].text;
/* Exceed 2000 */
try {
let responseMessage = response.data.choices[0].text;
if (responseMessage.length >= 2000) {
const attachment = new AttachmentBuilder(Buffer.from(responseMessage, 'utf-8'), { name: 'chatgpt-response.txt' });
const limitexceed = new EmbedBuilder()
.setTitle(`Reached 2000 characters`)
.setDescription(`Sorry, but you have already reached the limit of 2000 characters`)
.setColor(`#FF6961`);
await interaction.editReply({ embeds: [limitexceed], files: [attachment] });
} else {
const responded = new EmbedBuilder()
.setTitle(`You said: ${prompt}`)
.setDescription(`\`\`\`${response.data.choices[0].text}\`\`\``)
.setColor(`#77DD77`);
await interaction.editReply({ embeds: [responded] });
}
} catch (error) {
console.error(error);
await interaction.followUp({ content: `error` });
}
return;
},
};
i even tried using followUp or etc but the result is still same.
Your Problem
I believe the error occur in the catch() method (Line 55).
Please be reminded that the interaction has been deferred at Line 14:
await interaction.deferReply();
Explanation
Each interaction can only be replied and deferred once only. If you want to make changes on it, consider using the editReply() method.
Solution
Simply replace the code on Line 55 with editReply and this will solve the current error.
await interaction.editReply({ content: `error` });

Discord.js music bot stops playing

My discord.js music bot randomly stops playing music.
Here's the error report:
Emitted 'error' event on B instance at:
at OggDemuxer.t (/Users/myName/Bot/node_modules/#discordjs/voice/dist/index.js:8:288)
It says the error type is an "ECONNRESET" (code: 'ECONNRESET')
After this error the bot shortly goes offline and the code stops running (all commands don't work)
The code that I use to play music is as follows:
const { Client, Intents, MessageEmbed } = require('discord.js');
const { token } = require('./config.json');
const { joinVoiceChannel, createAudioPlayer, createAudioResource } = require('#discordjs/voice');
const ytdl = require('ytdl-core')
const ytSearch = require('yt-search')
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MEMBERS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_VOICE_STATES] });
client.once('ready', () => {
console.log('Ready!');
});
const videoFinder = async (search) => {
const videoResult = await ytSearch(search)
return (videoResult.videos.length > 1) ? videoResult.videos[0] : null;
}
client.on('messageCreate', msg => {
if(msg.content === '!join') {
connection = joinVoiceChannel({
channelId: msg.member.voice.channel.id,
guildId: msg.guild.id,
adapterCreator: msg.guild.voiceAdapterCreator
})
if (msg.content.substring(0, 6) === '!play ') {
let searchContent = msg.content.substring(6)
async function playChosen() {
let ourVideo = await videoFinder(searchContent)
const stream = ytdl(ourVideo.url, { filter: 'audioonly' })
const player = createAudioPlayer()
let resource = createAudioResource(stream)
player.play(resource)
connection.subscribe(player)
}
playChosen()
}
}
client.on('error', error => {
console.error('The WebSocket encountered an error:', error);
});
client.login(token);
I know the code is kinda messy, but if anybody could help, I'd really appreciate it! Also, I use discord.js v13, and the bot will typically play part of the song before this error comes up.
Yet again, I've posted a question that I quickly found an answer to lol. The problem here was being caused by ytdl-core, which would just randomly shut off for some reason. Play-dl worked much better to combat this. Here's a link to the place where I got this info:
Discord.js/voice How to create an AudioResource?
play-dl link:
https://www.npmjs.com/package/play-dl
example:
https://github.com/play-dl/play-dl/blob/5a780517efca39c2ffb36790ac280abfe281a9e6/examples/YouTube/play%20-%20search.js
for the example I would suggest still using yt-search to obtain the url as I got some wonky results using their search method. Thank you!

Clear reactions edited embed message

I want to do is that when the embed message is changed, the reactions are reset, not deleted.
I mean that when someone reacts to the emoji and embed its changed, the reaction returns to 1 and does not stay at 2.
and when it returns to 1 I can send a third embed
ty
This is the code I am using:
const embed = new MessageEmbed()
.setTitle("Test1")
.setFooter("Test1");
message.channel.send(embed).then(sentEmbed => {
sentEmbed.react("➡");
const filter = (reaction, user) => {
return (
["➡"].includes(reaction.emoji.name) &&
user.id === message.author.id
);
};
sentEmbed
.awaitReactions(filter, { max: 1, time: 30000, errors: ["time"] })
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === "➡") {
const embed2 = new MessageEmbed()
.setTitle('test2')
.setDescription('test2')
sentEmbed.edit(embed2);
}
})
});
You can remove all reactions by using message.reactions.removeAll().catch(error => console.error('Failed to clear reactions: ', error)); and then add reactions back if you want. I would do this in a function so you don't have to add all the reactions over and over each time you want to update the embed.

Discord Bot - Reaction Collector/Embed Edit

I am in the process of creating a Would You Rather command for my bot.
I have everything in place, except one feature I can't work out how to implement.
I would love to have it so that when someone reacts with their answer (🅰️ or 🅱️) the bot then edits the embed and puts the user who replied under their answer like this:
The code I currently have is:
case "wyr":
embed.setColor('#fc2803')
embed.setTitle('Would You Rather?')
embed.setDescription(':a: **Be able to fly** \n \n :b: **Breathe underwater**')
message.channel.send(embed).then(m => m.react('🅰️')).then(r => r.message.react('🅱️'));
You can easily implement this using the discord.js-collector package.
But if you want to make it using plaine discord.js, then you will have to listen to reactions when sending the embed, and then edit it to what you want like in the example i will give.
Simple Example Using The discord.js-collector package:
Code Here
And Live Preview Here
Simple Example Using Plaine Discord.js:
const Discord = require("discord.js");
const embed = new Discord.MessageEmbed()
.setTitle("Hello There!");
const embedtosend = await message.channel.send(embed).then(m => m.react('🅰️')).then(r => r.message.react('🅱️'));
const filter = (reaction, user) => {
return ['🅰️', '🅱️'].includes(reaction.emoji.name) && user.id === message.author.id;
};
message.awaitReactions(filter, { max: 2, time: 60000, errors: ['time'] })
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === '🅰️') {
const someotherembed = new Discord.MessageEmbed()
.setTitle("This Is A Different Hello There!");
embedtosend.edit(someotherembed)
} else if (reaction.emoji.name === '🅱️') {
const anotherembed = new Discord.MessageEmbed()
.setTitle("This Is A Different Embed!");
embedtosend.edit(anotherrembed)
}
});
I haven't tested this code, so it might not work...

Catch the user that responses to an awaitMessages action

in my discord bot, i have a command that scrambles a word, and the first user that responds in the chat gets a reward. i already made the command to await a message response, but how can i save who responded? heres my code so far
authorID = msg.author.id;
const filter = response => {
return response.author.id === authorID;
}
msg.channel.awaitMessages(filter, {
max: 1,
time: 5000
})
.then(mg2 => {
if (mg2.first().content === "1") {
msg.channel.send("you said 1");
}
});
With the filter, you are only allowing the original msg author to enter, you should make it so it detects if the msg.content equals the unscrabbled word. Also you don't have errors: ["time"].
const filter = m => m.content === unscrabledWord;
msg.channel.awaitMessages(filter, { max: 1, time: 5000, errors: ["time"] })
.then(collected => {
const winner = collected.first().author;
msg.channel.send(`${winner} Won!`)
})
.catch(() => msg.channel.send("Nobody guessed it"));

Resources