How to make reaction roles in discord.js? - javascript

I would like to know how to integrate reaction roles in my discord.js bot. I have tried the traditional methods of messageReactionAdd but it seem's very hard to make it extendable and editable, and it just became unusuable after having my bot in many guilds...
I have been trying to search for node modules that make this possible, but the only thing i found was this, and when trying to integrate it in my bot, it just made my commands and stuff no longer work, i have tried to read how to make reaction roles using that package, but at no avail, nothing worked...
I did try this:
const ReactionRole = require("reaction-role");
const system = new ReactionRole("my-token");
let option1 = system.createOption("x:697809640147105878", "697809380137107478");
let option2 = system.createOption("emoji-1:720843460158698152", "708355720436777033");
let option3 = system.createOption("pepe:720623437466435626", "703908514887761930");
system.createMessage("725572782157898450", "702115562158948432", 2, null, option1, option2, option3);
system.init();
But as i said, it made all my commands unusable...
Hope someone can help me!

You can easily implement this using the discord.js-collector package, it supports MongoDB, which is a database, so you'll no longer have to edit your bot manually!
Here's how to do it:
const { ReactionRoleManager } = require('discord.js-collector'); //We import the discord.js-collector package that'll make reaction roles possible
const { Client } = require('discord.js'); // We import the client constructor to initialize a new client
const client = new Client(); //We create a new client
const reactionRoleManager = new ReactionRoleManager(client, {
//We create a reaction role manager that'll handle everything related to reaction roles
storage: true, // Enable reaction role store in a Json file
path: __dirname + '/roles.json', // Where will save the roles if store is enabled
mongoDbLink: 'url mongoose link', // See here to see how setup mongoose: https://github.com/IDjinn/Discord.js-Collector/tree/dev/examples/reaction-role-manager/Note.md & https://medium.com/#LondonAppBrewery/how-to-download-install-mongodb-on-windows-4ee4b3493514
});
client.on('ready', () => {
console.log('ready');
});
client.on('message', async (message) => {
const client = message.client;
const args = message.content.split(' ').slice(1);
// Example
// >createReactionRole #role :emoji: MessageId
if (message.content.startsWith('>createReactionRole')) {
const role = message.mentions.roles.first();
if (!role)
return message
.reply('You need mention a role')
.then((m) => m.delete({ timeout: 1_000 }));
const emoji = args[1];
if (!emoji)
return message
.reply('You need use a valid emoji.')
.then((m) => m.delete({ timeout: 1_000 }));
const msg = await message.channel.messages.fetch(args[2] || message.id);
if (!role)
return message
.reply('Message not found!')
.then((m) => m.delete({ timeout: 1_000 }));
reactionRoleManager.addRole({
message: msg,
role,
emoji,
});
message.reply('Done').then((m) => m.delete({ timeout: 500 }));
}
});
client.login('Token');
And here's a live preview:
You can also use this package to do some other really cool stuff! Like embed paginator, questions, Yes/No Questions...
You can find them all here!

Related

How to store the ID of the user who sent a slash command and compare with user who interacted with a button in Discord.js

I'm using the following code to create a quick database to store the ID of the user who called a bot via a slash command. I then want to compare this ID with the ID of the person interacting with the bot. My aim is to prevent anyone but the user that called the bot being able to interact with it.
The following code works but it's temperamental in that it fails without a clear reason on occasion (i.e. it returns the error which states that the person interacting isn't the person who sent the slash command even if they are).
I'm new to discord.js and quick.db tables so I'm hoping someone more competent than me has a better way of achieving this.
const { Client, Intents, MessageEmbed, MessageActionRow, MessageButton } = require('discord.js'),
client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES ] });
client.db = require("quick.db");
var quiz = require("./quiz.json");
client.login(config.token);
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
if ([null, undefined].includes(client.db.get(`quiz`))) client.db.set(`quiz`, {});
if ([null, undefined].includes(client.db.get(`quiz.spawns`))) client.db.set(`quiz.spawns`, {});
});
client.on('messageCreate', async (message) => {
if (!message.content.startsWith(config.prefix)) return;
const args = message.content.slice(config.prefix.length).trim().split(/ +/g);
const command = args.shift();
if (command == "unlock") {
message.delete();
const m = await message.channel.send(getMMenuPage());
client.db.set(`quiz.spawns.m${m.id}`, message.author.id);
}
});
client.on('interactionCreate', async (interaction) => {
if (interaction.isButton()) {
if (client.db.get(`quiz.spawns.m${interaction.message.id}`) != interaction.user.id) return interaction.reply(getMessagePermissionError(client.db.get(`quiz.spawns.m${interaction.message.id}`)));
const q = quiz;
Please let me know if you need more information.
Thanks.
Instead of using:
const db = require("quick.db");
You should be using:
const { QuickDB } = require("quick.db");
const db = new QuickDB();
Other than that I haven't see any problems.

I want to change nickname of discord bot

I want to change the name of a discord bot and I have read numerous tutorials and Stack Overflow posts and I still cannot get it. The code is primarily taken from open source bot code, so I know it works (something with my bot setup maybe?)
As I understand it, this code loops through each guild the bot is a member of and sets the nickname.
I found the botId by right clicking the bot in the channel and copying ID.
const { guildId } = require('../config');
module.exports = (client, botId, nickname) => {
client.guilds.cache.forEach((guild) => {
const { id } = guild;
client.guilds.cache
.get(id)
.members.cache.get(botId)
.setNickname(nickname);
});
};
The bot shows up in the channel (after using oauth2 url), so I'm assuming that means they are a member of the guild.
However, when running this code the bot is not found. I've tried several things from other posts like guild.array() to try and see a full list of the members in the guild, but nothing has worked.
const guild = client.guilds.cache.get('943284788004012072');
const bot = guild.members.cache.get('956373150864642159')
if (!bot) return console.log('bot not found');
Here is the full bot
require('dotenv').config();
const { Client, Intents } = require('discord.js');
const eventBus = require('../utils/events/eventBus');
const setNickname = require('../utils/setNickname');
const getPrice = require('../modules/statsGetters/getPriceDEX');
const { bots } = require('../config');
const client = new Client({
intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES],
});
client.once('ready', async () => {
console.log('DEX Price Watch Bot Ready');
client.user.setPresence({
activities: [{ name: 'DEX Price', type: 'WATCHING' }],
status: 'online',
});
const price = await getPrice();
setNickname(client, bots.priceDEX, price);
eventBus.on(drip.update, async () => {
const price = await getPrice();
setNickname(client, bots.priceDEX, price); //update price in config file
});
});
client.login(process.env.DISCORD_PRICE_DEX);
This is the sample of changing bot's nickname for every guild that bot joined
client.guilds.cache.forEach((guild) => { //This is to get all guild that the bot joined
const nickname = args.slice(0).join(" ") //You wanted to change nickname
guild.me.setNickname(nickname); //setting the nickname of your bot
});
I believe you're doing it wrong.
Docs: https://discord.js.org/#/docs/discord.js/stable/class/GuildMember?scrollTo=setNickname
I would suggest using this module code:
const { guildId } = require('../config');
module.exports = (client, nickname) => {
client.guilds.cache
.get(guildId).me.setNickname(nickname);
};
And use it in this way in your main bot code: setNickname(client, price)
Edit:
Oh wait, I just realised you didn't use the correct intents (guild members), so you definitely need to use guild.me (as written above by me) or use guild.members.fetch() as it fetches members which aren't cached.
More info: https://discord.js.org/#/docs/discord.js/stable/class/GuildMemberManager?scrollTo=fetch

Missing permissions error when using mute command discord.js

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.

node-telegram-bot-api deprecated Automatic enabling of cancellation of promises is deprecated

I'm trying to create a Telegram bot but when I run the code I get these errors:
"node-telegram-bot-api deprecated Automatic enabling of cancellation of promises is deprecated
In the future, you will have to enable it yourself.
See https://github.com/yagop/node-telegram-bot-api/issues/319. internal\modules\cjs\loader.js:1063:30"
"error: [polling_error] {"code":"ETELEGRAM","message":"ETELEGRAM: 409 Conflict: terminated by
other getUpdates request; make sure that only one bot instance is running"}"
I have no idea what that means. I've followed the link but I still don't know how to solve the problem, please help me, I don't know what to do.
Here is my bot.js code if that helps:
const TelegramBot = require('node-telegram-bot-api');
const axios = require('axios');
const parser = require('./parser.js');
require('dotenv').config();
const token = process.env.TELEGRAM_TOKEN;
let bot;
if (process.env.NODE_ENV === 'production') {
bot = new TelegramBot(token);
bot.setWebHook(process.env.HEROKU_URL + bot.token);
} else {
bot = new TelegramBot(token, { polling: true });
}
// Matches "/word whatever"
bot.onText(/\/word (.+)/, (msg, match) => {
const chatId = msg.chat.id;
const word = match[1];
axios
.get(`${process.env.OXFORD_API_URL}/entries/en-gb/${word}`, {
params: {
fields: 'definitions',
strictMatch: 'false'
},
headers: {
app_id: process.env.OXFORD_APP_ID,
app_key: process.env.OXFORD_APP_KEY
}
})
.then(response => {
const parsedHtml = parser(response.data);
bot.sendMessage(chatId, parsedHtml, { parse_mode: 'HTML' });
})
.catch(error => {
const errorText = error.response.status === 404 ? `No definition found for the word: <b>${word}</b>` : `<b>An error occured, please try again later</b>`;
bot.sendMessage(chatId, errorText, { parse_mode:'HTML'})
});
});
Install this package npm I dotenv
Create a file called .env at the root of your project.
Add to that file this NTBA_FIX_319=1
Add to the top of your index.js file (or whatever file that contains your bot instance): require('dotenv').config()
Restart your bot.
So your code will look like
require('dotenv').config();
const TelegramBot = require('node-telegram-bot-api');
// replace the value below with the Telegram token you receive from #BotFather
const token = 'YOUR_TELEGRAM_BOT_TOKEN';
// Create a bot that uses 'polling' to fetch new updates
const bot = new TelegramBot(token, {polling: true});
bot.on('message', (msg) => {
const chatId = msg.chat.id;
// send a message to the chat acknowledging receipt of their message
bot.sendMessage(chatId, 'Received your message');
});
1) Get rid of the promise cancellation warning
The simplest, is to add that line at the top of your bot file:
process.env.NTBA_FIX_319 = 1 // this line SHOULD be above all imports
const TelegramBot = require('node-telegram-bot-api')
// ...rest of your telegram bot code
2) The 409 conflict error
In short, there are two version of your telegram bot running at the same time, so:
check if there is not multiple instance of your server running your bot, which can be the case when using workers, pm2...
check that your bot script is not started twice
Other causes and explanations can be found here and here

Mute Role Saves To The Muted User When They Leave

Hi, I've been working on "Saving / giving the mute role to the muted user who left the server" for quite awhile now. I even tried using quick.db, but it didnt worked
Is there anything I can do to make this? I would appriciate your help!
I suggest you store your users in a JSON database with lowdb.
Example of your bot code:
const Discord = require('discord.js');
const client = new Discord.Client();
const low = require('lowdb')
const FileSync = require('lowdb/adapters/FileSync')
const adapter = new FileSync('db.json')
const db = low(adapter)
client.once('ready', () => {
db.defaults({users: [] })
.write()
console.log('Ready!');
});
client.on('message', message => {
//when you mute a user add you multiple actions and:
db.get('users')
.push({ user: userID, muted: 'yes'})
.write()
});
You will have to create a db.json file beforehand of course.

Categories