Fetch bot messages from bots Discord.js - javascript

I am trying to make a bot that fetches previous bot messages in the channel and then deletes them. I have this code currently that deletes all messages in the channel when !clearMessages is entered:
if (message.channel.type == 'text') {
message.channel.fetchMessages().then(messages => {
message.channel.bulkDelete(messages);
messagesDeleted = messages.array().length; // number of messages deleted
// Logging the number of messages deleted on both the channel and console.
message.channel.send("Deletion of messages successful. Total messages deleted: "+messagesDeleted);
console.log('Deletion of messages successful. Total messages deleted: '+messagesDeleted)
}).catch(err => {
console.log('Error while doing Bulk Delete');
console.log(err);
});
}
I would like the bot to only fetch messages from all bot messages in that channel, and then delete those messages.
How would I do this?

Each Message has an author property that represents a User. Each User has a bot property that indicates if the user is a bot.
Using that information, we can filter out messages that are not bot messages with messages.filter(msg => msg.author.bot):
if (message.channel.type == 'text') {
message.channel.fetchMessages().then(messages => {
const botMessages = messages.filter(msg => msg.author.bot);
message.channel.bulkDelete(botMessages);
messagesDeleted = botMessages.array().length; // number of messages deleted
// Logging the number of messages deleted on both the channel and console.
message.channel.send("Deletion of messages successful. Total messages deleted: " + messagesDeleted);
console.log('Deletion of messages successful. Total messages deleted: ' + messagesDeleted)
}).catch(err => {
console.log('Error while doing Bulk Delete');
console.log(err);
});
}

Related

DiscordJS (Node) Sending PM to user and await reply

I'm trying to get my bot to send a user a private message when a user types a command, and then wait for a reply to the private message.
Expected flow:
Jim types: !auth
bot sends Jim a private message
Jim replies to the message with blablabla
Bot sees the blablabla reply and outputs to terminal => console.log( replyResponse );
I have tried numerous examples I have found from here and in the docs but none of them works.
message.author.send('test').then(function () {
message.channel
.awaitMessages((response) => message.content, {
max: 1,
time: 300000000,
errors: ['time'],
})
.then((collected) => {
message.author.send(`you replied: ${collected.first().content}`);
})
.catch(function () {
return;
});
});
message.author.send('test') returns the sent message so you should use that returned message to set up a message collector. At the moment, you're using message.channel.awaitMessages and that waits for messages in the channel where the user sent the !auth message, not the one where the bot sent a response.
Check out the working code below. It uses async-await, so make sure that the parent function is an async function. I used createMessageCollector instead of awaitMessages as I think it's more readable.
try {
// wait for the message to be sent
let sent = await message.author.send('test');
// set up a collector in the DM channel
let collector = sent.channel.createMessageCollector({
max: 1,
time: 30 * 1000,
});
// fires when a message is collected
collector.on('collect', (collected) => {
collected.reply(`✅ You replied: _"${collected.content}"_`);
});
// fires when we stopped collecting messages
collector.on('end', (collected, reason) => {
sent.reply(`I'm no longer collecting messages. Reason: ${reason}`);
});
} catch {
// send a message when the user doesn't accept DMs
message.reply(`❌ It seems I can't send you a private message...`);
}
Make sure, you don't forget to enable the DIRECT_MESSAGES intents. For example:
const { Client, Intents } = require('discord.js');
const client = new Client({
intents: [
Intents.FLAGS.GUILDS,
Intents.FLAGS.GUILD_MESSAGES,
Intents.FLAGS.DIRECT_MESSAGES,
],
});

Can't get the bot to recognize if the user reacting has a role

The bot sends the embed and reacts to it, but I can't get it to check if the user reacting to the embed has a certain role. (Only certain roles can accept/deny the request.)
When the role ID was a role that the bot was in. It counted the bot's reactions, but when a user reacts with the correct role, it doesn't recognize it and goes to the timeout error:
you didn't react with neither a thumbs up, nor a thumbs down.
client.channels.cache.get("771101528386961428").send(embed).then(function (message) {
message.react("👍")
message.react("👎")
const filter2 = (reaction, user) => {
return ['👍', '👎'].includes(reaction.emoji.name) && reaction.member.roles.cache.find(r => r.id === "873477291445985330");
};
message.awaitReactions(filter2, { max: 1, time: 60000, errors: ['time'] })
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === '👍') {
client.channels.cache.get("868298545269182495").send(Aembed)
} else {
message.author.send("Your request has been denied");
}
})
.catch(collected => {
console.log(`After a minute, only ${collected.size} out of 4 reacted.`);
message.reply('you didn\'t react with neither a thumbs up, nor a thumbs down.');
});
});
The class MessageReaction has no .member property, but you can use Guild.member() instead to obtain an instance of GuildMember corresponding to the user, who reacted to the message.
const filter2 = (reaction, user) => {
return ["👍", "👎"].includes(reaction.emoji.name) &&
message.guild.member(user).roles.cache.find(r => r.id === "role id");
};
Note that later in your code, you use message.author.send(), that won't work because in this context, the message is the message sent by the bot -> the author of the message is your bot. And the bot can't send a message to itself. Will throw an error like this:
DiscordAPIError: Cannot send messages to this user
Tested using discord.js ^12.5.3.

How do I edit an embed field with discord.js?

How do I edit an embed field with discord.js?
execute(client, connection, message, args) {
message.channel.send(client.helpers.get('CreateEmptyEmbed').execute("Poll", client, false)
.setTitle('test')
.addField(`0`)
).then(embedMessage => {
embedMessage.react(`✅`)
embedMessage.react(`❎`)
})
client.on('messageReactionAdd', (reaction, user) => {
if (user.id === client.user.id) return // if reaction is == bot return
if (reaction.emoji.name == '✅') message.channel.send(reaction.count)
embed.editfield("hi")
})
Any help would be greatly appriciated.
First of all, client.on('messageReactionAdd') fires for all reactions, and doesn't stop, it keeps firing until you stop the bot, so you need to use a Reaction Collector and to edit embed, you need to change the embeds field and edit the message itself.
execute(client, connection, message, args) {
message.channel.send(client.helpers.get('CreateEmptyEmbed').execute("Poll", client, false)
.setTitle('test')
.addField(`0`)
).then(embedMessage => {
embedMessage.react(`✅`)
embedMessage.react(`❎`)
const filter = (reaction, user) => user.bot!; //Ignores bot reactions
collector = embedMessage.createReactionCollector(filter,{time:15000)) //The time parameter (in milliseconds) specified for how much time the reactionCollector collects reactions
collector.on('collect',(reaction,user)=>{ //When a reaction is collected
const embed = embedMessage.embeds[0] // Get the embed that you want to edit.
embed.fields[0] = {name : 'The name of the new field' , value : 'Value of new field'}
await embedMessage.edit(embed)
})
collector.on('end',()=>{ //When the time we specified earlier is over
//Do stuff
})
})
let filter = m => m.author.id === message.author.id // to ensure same author is responding
message.channel.send(embedMessage).then(() =>{
message.channel.awaitMessages(filter, { // after he sends a message to the same channel
// You can also use ".awaitReactions" if you want to wait for reactions on the message sent
max: 1,// maximum responses
time: 30000,// timeout for waiting
errors: ['time']// type of error
})
.then(message =>{
// do what everyou like with the response
})
.catch(error => console.log)
});

Make a bot react to a message above it

I need a bot to react to a message above the user who sent the command. Right now the bot only reacts to the user who sent the command.
client.on('message', (msg) => {
if (msg.content === 'Boo Hoo') {
const reactionEmoji = msg.guild.emojis.cache.find(
(emoji) => emoji.name === 'BooHoo'
);
msg.react(reactionEmoji);
}
});
how would I modify/rewrite this code to make it react to a message above the user who sent the command? I'm thinking it might have something to do with MessageManager, and fetching messages but I don't know.
Here, use the .fetch() method:
message.channel.messages
.fetch({ limit: 2 }) // get the two latest messages in that channel (cmd and the one aaobve it)
.then((messages) => messages.last().react(reactEmoji)); // get last (second) entry and react to it

Discord bot message doesn't collect reactions

I am trying to remove reactions to my bots message once the reaction comes in, but for some reason I'm getting behaviors I can not seem to track down the cause of.
I want to be able to see when a user reacts to the reply message but I only see when the bot reacts to their own message and when the user reacts to a users message. I ran my code (below) and sent 'message' to the channel and after the reply from the bot, I clicked the reactions on both my message and the bots message. Here are the logs:
bot is ready
reaction by: Lyon bot on reply
reaction by: Lyon bot on reply
reaction by: Lyon bot on reply
reaction by: Lyon bot on reply
reaction by: Virt on message
reaction by: Virt on message
I am expecting to be able to see reaction by: Virt on reply but I never see it.
const Discord = require('discord.js');
const bot = new Discord.Client();
const token = '*******';
bot.on('ready', () => {
console.log('bot is ready');
});
bot.on('message', message => {
if (message.content === 'message') {
message.channel.send('reply');
}
message.react('👍').then(() => message.react('👎'));
const filter = (reaction, user) => {
return ['👍', '👎'].includes(reaction.emoji.name) && user.id === message.author.id;
};
const collector = message.createReactionCollector(filter, {});
collector.on('collect', r => {
console.log('reaction by: ', r.message.author.username, ' on ', r.message.content);
});
});
bot.login(token);
Your filter doesn't seem right, replace it with this: const filter = (reaction, user) => reaction.emoji.name === '👍' || reaction.emoji.name === '👎' && user.id === message.author.id;

Categories