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;
Related
I am creating a Discord bot that sends a message when the user's message contains a certain string.
For example, if the user says 'ping', the bot should reply with 'pong'. However, this is not currently working as intended.
The bot itself is online and in the server I am testing, and I am using the correct login token. The code itself does not produce any errors, but it does not function as expected. I am looking for a solution to this issue.
Heres the code:
Ive removed the token just for this post.
const Discord = require('discord.js');
const { Client, GatewayIntentBits } = Discord;
// Create a new client
const client = new Client({
// Set the intents to include guilds and guild messages
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildMembers,
]
});
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('message', message => {
if (message.content === 'ping') {
message.reply('Pong!');
}
});
// Log in to Discord using the bot's token
client.login('REMOVED FOR STACK OVERFLOW POST');
Heres my bots permissions
As Zsolt Meszaros pointed out the client on function should use
https://stackoverflow.com/users/6126373/zsolt-meszaros
client.on('messageCreate', message => {
if (message.content === 'ping') {
message.reply('Pong!');
}
});
instead of
client.on('message', message => {
if (message.content === 'ping') {
message.reply('Pong!');
}
});
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.
I am trying to make a membership bot for Discord. The bot will retrieve an user ID and a role from the API and needs to remove this role from the user.
First I am getting the guild where the specific user is in:
const guild = client.guilds.cache.get('842361027562831872');
Then I am finding the role by the name:
let role = guild.roles.cache.find(role => role.name === "Sport");
if (!role) return;
Then I am trying to find the user by his ID, and remove the above role. However the user is always undefined:
guild.members.cache.get(user.user).roles.remove(role);
Normally when I add a role I use the message Object and then use the guild from that message like this:
let role = message.guild.roles.cache.find(role => role.name === "Sport");
if (!role) return;
message.guild.members.cache.get(message.author.id).roles.add(role);
However I retrieve the data from an API so I have to do it another way.
The full code of my script:
get('/expired', '', function (result) {
let users = result.data.users;
const guild = client.guilds.cache.get('842361027562831872');
users.forEach(user => {
let role = guild.roles.cache.find(role => role.name === user.role);
if (!role) return;
guild.members.cache.get(user.user).roles.remove(role);
});
});
So apparently I had to use the fetch method which then returns a promise.
guild.members.fetch(user.user).then(member => {
member.roles.remove(role);
member.send(`Your subscription for ${user.role} is expired.`);
}).catch(console.log);
I then can remove the role of that user and send him/her a direct message.
I have two servers with my bot on it with two groups of friends. On one server, the bot and I both have admin perms, and I can mute someone who doesn't have those perms. On the other server, I'm the owner and the bot has admin, but I can't mute anyone. I get the error 'Missing Permissions'.
Here's the code:
const Discord = require('discord.js')
const ms = require('ms')
module.exports = {
name: 'mute',
execute(message, args) {
if(!args.length) return message.channel.send("Please Specify a time and who to mute. For example, '!mute #antobot10 1d' And then send the command. Once the command is sent, type the reason like a normal message when I ask for it!")
const client = message.client
if (!message.member.hasPermission('MANAGE_ROLES')) return message.channel.send("You don't have permission to use that command!")
else {
const target = message.mentions.members.first();
const filter = (m) => m.author.id === message.author.id
const collector = new Discord.MessageCollector(message.channel, filter, { time: 600000, max: 1 })
const timeGiven = args[1]
message.channel.send('The reason?')
collector.on('collect', m => {
collector.on('end', d => {
const reason = m
message.channel.send(`${target} has been muted`)
target.send(`You have been muted on ${message.guild.name} for the following reason: ***${reason}*** for ${timeGiven}`)
if(message.author.client) return;
})
})
let mutedRole = message.guild.roles.cache.find(role => role.name === "MUTE");
target.roles.add(mutedRole)
setTimeout(() => {
target.roles.remove(mutedRole); // remove the role
target.send('You have been unmuted.')
}, (ms(timeGiven))
)
}
}
}
Ok, I'm not exactly sure what I did, but it's working now. I think I just changed it so that the MUTE role had 0 permissions instead of normal permissions but making it so that if you have the role you can't talk in that certain channel.
Thanks for the answers!
If your bot's role is below the role of the user you are attempting to mute, there will be a missing permissions error. In your server settings, drag and drop the bot role as high in the hierarchy it will go. This will solve your problem.
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)
});