Unable to receive interactionCreate Event in DiscordJS - discord

I am trying to implement Slash Commands to my Discord bot but when i try to recieve interaction create events nothing is getting detected with no errors
client.on('interactionCreate', async (interaction) => {
The Slash Commands do get added and i can edit their name and stuff but im unable to recieve any interaction create events, it does detect normal messages but doesnot detect any interactionCreate stuff,
const client = new Client({
intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.DIRECT_MESSAGES]
});
);
Those are the intents i have provided to the client
Screenshot
Those are the permissions i gave to the bot when i invited it to my server
await rest.put(
Routes.applicationGuildCommands(clientID, devGuildID), {
body: commandList
},
);
console.log('Successfully registered application commands for development guild');
rest.get(Routes.applicationCommands(clientID))
.then(data => console.log(data));
When i use this i get "[]" as an output when i console.log

Related

Discordjs 14.7.1 Skips First Reaction

Problem is the Discord bot is skipping the first reaction emoji.
If I un-react and re-react with the same emoji, then the bot registers it.
I've been trying to figure this out for a while, and am stumped as to what I am missing in my logic or if I need to find another solution.
Intention:
Discord bot gathers and prints out all reactions to a message by a user
Relevant Information:
Discordjs 14.7.1
Discord Developer Website:
Presence Intent: Enabled
Server Members Intent: Enabled
Message Content Intent: Enabled
Code:
const { Client, Events, GatewayIntentBits, Partials } = require('discord.js');
const { token } = require('./includes/config.json');
// create a new discord client
const client = new Client({
intents: [
GatewayIntentBits.DirectMessageReactions,
GatewayIntentBits.DirectMessageTyping,
GatewayIntentBits.DirectMessages,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildMessageReactions,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.Guilds,
GatewayIntentBits.MessageContent,
],
partials: [
Partials.Channel,
Partials.GuildMember,
Partials.Message,
Partials.Reaction,
Partials.User,
]
});
// ready
client.once(Events.ClientReady, () => {
console.log('Ready!');
});
// if partial, fetch full
client.on(Events.MessageReactionAdd, async (reaction, user) => {
if (reaction.partial) {
try {
await reaction.fetch();
} catch (error) {
console.error(error);
return;
}
}
// define the message component
const message = reaction.message;
// all userReactions by user.id
const userReactions = await message.reactions.cache.filter(reaction => reaction.users.cache.has(user.id));
// print emojis
try {
for (const reaction of userReactions.values()) {
console.log(`Emoji: ${reaction.emoji}`);
}
} catch(error) {
console.error(error);
}
})
// login
client.login(token);
Problem:
The bot is not registering the first reaction placed
Example:
- I react to a message in this order: 😄❤️🔥
- the logfile shows:
Emoji: ❤️
Emoji: ❤️
Emoji: 🔥
Expected result:
Emoji: 😄
Emoji: 😄
Emoji: ❤️
Emoji: 😄
Emoji: ❤️
Emoji: 🔥
Observations:
I noticed that the bot works fine for all messages sent after it is running
The problematic behaviour is experienced only for messages sent before the bot was running
Conclusion:
MessageReactionAdd() does get called, as tested by placing 'console.log(test output); statements. I learned that it works on cached messages only, which I thought was mitigated by fetching the full reaction. Such was not the case. I tried testing by forcing a message fetch manually by channel.id and message.id, it still did not work.
My Solution:
Used an sqlite database to keep track of reactions.
From within MessageReactionAdd() I was able to check for the reactions I was interested in logging, and added them to an sqlite database.
Within an equivalent MessageReactionRemove() section, I was able to check for removal of the reactions and delete the pertinent row from the database.
Thank you for reading and assisting. :)

How can I DM the user an embed before he is kicked (discord.js)

I'm trying to make a blacklist command, and how do I make it so it sends an embed instead of normal message.
(Also, I'm new to discord.js)
Here's my script:
module.exports = {
data: new SlashCommandBuilder()
.setName('blacklist')
.setDescription('Blacklist someone from the server')
.addUserOption((option) => option.setName('member')
.setDescription('Who are you blacklisting?')),
async execute(interaction) {
await interaction.deferReply();
const member = interaction.options.getMember('member');
if (!interaction.member.roles.cache.some(r => r.name === "Blacklist perms")) {
return interaction.editReply({ content: 'You do not have permission to use this command!' });
}
member.send("You have been blacklisted!")
member.kick().catch(err => {
interaction.editReply({ content: `I do not have enough permissions to do that.`})
})
await interaction.editReply({ content: `${member} has been succesfully blacklisted!` });
},
};```
Since your function is already async, simply await sending the message before you call kick.
await member.send("You have been blacklisted!")
member.kick().catch(err => {
interaction.editReply({ content: 'I do not have enough permissions to do that.'})
})
You might also wanna catch() on the send method because users can have DMs from server members disabled or blocked your bot.
You also might consider banning the user instead, because this system would fail if your bot ever happens to go offline when a blacklisted user tries to join. Additionally, depending on how fast your bot reacts, the user may still have time to spam in channels or do something harmful before your bot is able to kick them.
To send an embed either use an EmbedBuilder or a plain JavaScript object with the correct embed structure.
Example:
member.send({ embeds:[{
title: "Title",
description: "Hello World!"
}] })

How can i setup my discord bot automatically?

I have a discord bot but I want when someone add my bot to their server they dont need to write !setup. How I can do it automatically ?
client.on('messageCreate', async message => {
if (message.content === '!setup') {
await message.guild.commands
.set(client.commands)
}
});
Use the Client#guildCreate event
For instance:
client.on("guildCreate", guild => {
// What to do when the bot is invited
}
Under client in the discord.js docs there is an event called guildCreate which is emitted when the client joins a guild. If you listen for this event and run your setup code when it is emitted this might be what your after.
const { Client, Intents} = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS] });
client.on('guildCreate', guild => {
//Your setup code
});
If it's just one server that you wan to add the bot to, you can do it manually. Just follow these steps:
Go into discord developer portal > click on your bot > Oauth2 > URl Generator > click bot and any other scope you might need > choose your perms > copy and past the link into your browser and you should be done!
To do this however, you must have manage server perms in that server

messageCreate event no longer firing after adding the interactionCreate event

To start: Yes I have intents setup. I have the "message content" intent enabled in the developer portal.
Recently I decided to setup slash commands for my bot. (That is all working fine, not the purpose of this question). Now however, I find that my "messageCreate" event is not firing at all. I've done some basic testing, including removing the "interactionCreate" event, and it still is non-functional. The only fix I've found is completely reverting to the previous version on my source control.
I haven't been able to find any solutions from the discord.js Discord so I decided to come here in the hopes someone can help. Thanks for your time! Client constructor and event code attached below.
Client:
const myIntents = new Intents(
Intents.FLAGS.GUILDS,
Intents.FLAGS.GUILD_MESSAGES,
Intents.FLAGS.DIRECT_MESSAGES,
Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
Intents.FLAGS.DIRECT_MESSAGE_REACTIONS
);
const client = new Client({ intents: myIntents, partials: ["CHANNEL"] });
Events:
client.once('ready', () => {
// Works fine
});
client.on('interactionCreate', async interaction => {
// Works fine
});
client.on('messageCreate', async message => {
console.log('DEBUG') // Never triggers
// Other stuff
});
client.on("error", (e) => console.error(e));
client.on("warn", (e) => console.warn(e));
process.on('unhandledRejection', (e) => console.error(e));
console.log("client") // All events, including messageCreate, are visible in the resulting output
client.login(config.token);
I think you need the "MESSAGE" partial.
You can try and replace
const client = new Client({ intents: myIntents, partials: ["CHANNEL"] });
To
const client = new Client({ intents: myIntents, partials: ["CHANNEL", "MESSAGE"] });
Moreover, I had the same issue but I was very dumb because I didn't realize that my bot didn't have "READ MESSAGES" and "SEND MESSAGES" permissions in that channel, so that might be the issue.

Discord.js. Reaction Roles

I'm trying to script a bot that gives people a role when they click on an emoji.
My problem is that people don't get the role when they click on the emoji. When I enter the first Command t!role the Message with the emoji is sent correctly. However, the people reacting will not receive the role. I tried everything that was suggested in the Comments. Unfortunatley nothing seems to work.
const bot = new Discord.Client( {
intents: [
Intents.FLAGS.GUILDS,
Intents.FLAGS.GUILD_MEMBERS,
Intents.FLAGS.GUILD_MESSAGES,
Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
Intents.FLAGS.DIRECT_MESSAGE_REACTIONS,
],
partials: ["MESSAGE", "CHANNEL", "REACTION"]
});
else if(parts[0].toLowerCase() == "t!role") {
let sendMessage = await message.channel.send('React with 👮to get the role')
sendMessage.react('👮')
bot.on('messageReactionAdd', async (reaction, user, channel) => {
if(reaction.message.partial) await reaction.message.fetch();
if(reaction.partial) await reaction.fetch();
if(user.bot) return;
if(!reaction.message.guild) return;
if(reaction.message.channel.id === '8786607442820137464') {
if(reaction.emoji.id === '8789972642138767364') {
reaction.message.guild.members.cache.get(user.id).roles.add('8779841244749004804')
}
}
})
Discord had added a few new features in their developer portal a few months ago and most of the documentation and tutorials skip over that but it is necessary for them to be active in order to have a functional reaction roles feature.
The process to turn these on is to go to the application page of your bot, go to the bot page under the application and activate Presence Intent and Server Members Intent. Hopefully after this your reaction roles should start working.
Enable partials in your client initialization. Discord.js requires you now to add partials and intent flags you actually gonna use. The messageReactionAdd event requires some partials as well: REACTION, MESSAGE, CHANNEL.
For example, this is how you should use partials.
const bot = new Client({
intents: [
Intents.FLAGS.GUILDS,
Intents.FLAGS.GUILD_MEMBERS,
Intents.FLAGS.GUILD_MESSAGES,
Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
Intents.FLAGS.DIRECT_MESSAGE_REACTIONS,
],
partials: ["MESSAGE", "CHANNEL", "REACTION"]
});
I have used the same exact code in your post, only changed a few id's on my side, and it's working as intended. As my comment before:
Bots can only give roles below their own, even if they have Administrator permissions. Make sure the role is below the bot's role. Use .catch((error) => console.log(error.message)); to log any errors if giving out the roles has failed for some reason.
bot.on('messageReactionAdd', async (reaction, user, channel) => {
if(reaction.message.partial) await reaction.message.fetch();
if(reaction.partial) await reaction.fetch();
if(user.bot) return;
if(!reaction.message.guild) return;
if(reaction.message.channel.id === '8786607442820137464') {
if(reaction.emoji.id === '8789972642138767364') {
reaction.message.guild.members.cache.get(user.id).roles.add('8779841244749004804')
}
}
});

Resources