Making reactions with Partial Events - bots

I've made a code for verify command, it's reacting to certain embed. But when I reboot the bot won't recognize it, so users can still react but won't get role at all. I've heard I can use Partial Event but I don't want to make it inside index.js.
Code:
let wembed = new Discord.MessageEmbed()
.setAuthor("Test")
.setColor("PURPLE")
.setDescription(arg1)
const reactmessage = await client.channels.cache.get(chx).send(wembed)
await reactmessage.react('βœ…');
const filter = (reaction, user) => reaction.emoji.name === 'βœ…' && !user.bot;
const collector = reactmessage.createReactionCollector(filter);
collector.on('collect', async reaction => {
const user = reaction.users.cache.last();
const guild = reaction.message.guild;
const member = guild.member(user) || await guild.fetchMember(user);
member.roles.add("725747028323205170");
});
If there is a way of doing this help would be appreciated!

https://discordjs.guide/popular-topics/partials.html#enabling-partials
index.js:
const client = new Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'] });
your messageReactionAdd file:
module.exports = async (reaction, user) => {
if(reaction.partial) await reaction.fetch();
}
Now all reactions are sent to messageReactionAdd, now you just have to validate the reaction and add the role if it corresponds to the right emoji and the right message

Related

MemberCounter outputs wrong numbers

Iβ€˜m trying my first member counter bot on Discord. Somehow the numbers of the online, idle and dnd members arenβ€˜t updating correct anymore. It seems that the bot is outputting old numbers.
My code:
module.exports = async (client) => {
const guild = client.guilds.cache.get('889774617349218304');
const guildMembers = await guild.members.fetch({ withPresences: true });
const onlineCount = await guildMembers.filter(member =>!member.user.bot && member.presence?.status === "online").size
setInterval(() =>{
const channel = guild.channels.cache.get('906111710706954251');
channel.setName(`🟒 ${onlineCount.toLocaleString()}`);
console.log('Updating User-Online Count');
}, 360000);
}
Looking at your code, you are repeating the process where it changes the channel name, but using the whole variable. You are not updating the guildmember variable, hence it's always the same.
You could either move everything into the setInterval function, or redefine it.
For example:
module.exports = async (client) => {
setInterval( async () =>{
const guild = client.guilds.cache.get('889774617349218304');
const guildMembers = await guild.members.fetch({ withPresences: true });
const onlineCount = await guildMembers.filter(member =>!member.user.bot && member.presence?.status === "online").size
const channel = guild.channels.cache.get('906111710706954251');
channel.setName(`🟒 ${onlineCount.toLocaleString()}`);
console.log('Updating User-Online Count');
}, 360000);
}
This way, every hour, the bot will fetch the members of the guilds again, making it accurate.

Discord.js/Firestore .where() is not a function

I am trying to integrate my discord bot with firestore. Whenever I try to run a query I get .where is not a function and I don't understand why because everything else seems to work. Here is the relevant code. I have tried the require of firebase at the top of Remove.js and that doesn't seem to do anything.
Here is my thought to how I believe it should be working right now.
I run node . and it then runs my index.js file.
On an interaction create (i.e. a slash command is created) it checks the command file and in this case it is the remove command
It calls execute(interaction, db) where interaction is the interaction slash command and db is the admin.Firestore() db reference from index.js. I am fully able to use get commands (i.e. that first chunk of code works before I try to delete)
Because this is a reference I should be able to call .where() based on the Firestore documentation and yet I am hit with the error "TypeError: db.collection(...).doc(...).collection(...).doc(...).where is not a function"
// Index.js
// General Setup
const { Client, Collection, Intents } = require('discord.js')
const config = require('./config.json')
const fs = require('fs')
// Bot Setup
const myIntents = new Intents();
myIntents.add(Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_MEMBERS)
const bot = new Client({intents: myIntents});
// Firebase Setup
const firebase = require('firebase/app')
const fieldValue = require('firebase-admin').firestore.FieldValue
const admin = require('firebase-admin')
const serviceAccount = require('./serviceAccount.json')
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
})
let db = admin.firestore();
// Command Setup
bot.commands = new Collection();
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'))
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
bot.commands.set(command.data.name, command);
}
// Bot Login
bot.once('ready', async () => {
console.log('Wheatley is online!');
});
bot.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) {
return
}
const command = bot.commands.get(interaction.commandName)
if (!command) {
return
}
try {
await command.execute(interaction, db)
} catch (error) {
console.error(error)
await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true})
}
});
bot.login(config.bot_token);
///Remove.js
const { SlashCommandBuilder } = require('#discordjs/builders');
require('#firebase/firestore');
module.exports = {
data: new SlashCommandBuilder()
.setName('remove')
.setDescription('Removes object from collection')
.addStringOption(option =>
option.setName('item')
.setDescription('Enter an item in the collection to remove')
.setRequired(true)
),
async execute(interaction, db) {
const itemName = await interaction.options.getString('item')
const itemToDelete = db.collection('items').doc(interaction.guildId).collection('items').doc(itemName);
const doc = await itemToDelete.get();
if(!doc.exists) {
return interaction.reply({
content: `${itemName} does not exist in the collection. Try using /list to check for the right name.`,
ephemeral: true
})
}
const ownerId = interaction.user.id
const snapshot = db.collection('items').doc(interaction.guildId).collection('items').doc(itemName).where("ownerId", "==", ownerId).get();
if(!snapshot.exists) {
return interaction.reply({
content: `You are not the owner of ${itemName}. Please contact owner to delete this from the collection`,
ephemeral: true
})
}
itemToDelete.delete();
return await interaction.reply(`${itemName} was removed from the collection!`)
},
};
You are using where on a document, as where is a query function that is only available to collections.
Just be warned that the snapshot will return an array of snapshots as it is a query, not a single document.
Try this instead:
const snapshot = db.collection('items').doc(interaction.guildId).collection('items').where("ownerId", "==", ownerId).get();

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...

How to store reactions into quick.db

So I want to store user reactions into quick.db
let wembed = new Discord.MessageEmbed()
.setAuthor("Armagedon RolePlay | Verify System")
.setColor("PURPLE")
.setThumbnail(message.author.displayAvatarURL())
.setDescription(arg1)
const reactmessage = await client.channels.cache.get(chx).send(wembed)
await reactmessage.react('βœ…');
const filter = (reaction, user) => reaction.emoji.name === 'βœ…' && !user.bot;
const collector = reactmessage.createReactionCollector(filter, { time: 15000 });
collector.on('collect', async reaction => {
const user = reaction.users.cache.last();
const guild = reaction.message.guild;
const member = guild.member(user) || await guild.fetchMember(user);
member.roles.add("725747028323205170");
});
Basically I want to store user's reaction then store it into quick.db in case bot crashes and reboots after on users can still react to wembed
Storing into quick.db or any database isn't the best idea. If you want to get working with reactions after the bot crashed/reboot, use Client's options where it includes partials. I recommend use this code:
const client = new Discord.Client({
partials: ['MESSAGE', 'CHANNEL', 'REACTION', "GUILD_MEMBER"]
})

Sqlite Discord.js: Cannot read property 'run' of null

So I am trying to make a SQLite database for my Discord.js bot, but I keep getting this error (Cannot read property of 'run' of null) when I try to use SQLite. Non of my friends seem to have this problem, so I thought to come here. Sorry if this is like a noobish question.. I'm still a little new to this
Here is my code:
const Discord = require("discord.js");
const client = new Discord.Client();
const bot = new Discord.Client();
const sql = require("sqlite")
const fs = require("fs");
const staff = ["97122523086340096", "450241616331145217", "283438590875402240", "288755621787074560"]
const config = require("./config.json");
client.on("ready", async () => {
console.log(`${client.user.username} is ready to help servers!`)
console.log ("Warning: I am being locally hosted. During high usage times, the bot may crash.")
console.log(`I am available in 1 shard! I am in ${client.guilds.size} guilds and serving ${bot.users.size}`)
client.user.setActivity("For sat!help", {type: "WATCHING"}, {status:"dnd"});
client.user.setPresence( {status:"idle"} )
sql.run("CREATE TABLE IF NOT EXISTS guild (guildId TEXT, language INTEGER, links INTEGER)")
});
fs.readdir("./events/", (err, files) => {
if (err) return console.error(err);
files.forEach(file => {
let eventFunction = require(`./events/${file}`);
let eventName = file.split(".")[0];
client.on(eventName, (...args) => eventFunction.run(client, ...args));
});
});
client.on("message", message => {
if (message.author.bot) return;
if(message.content.indexOf(config.prefix) !== 0) return;
const args = message.content.slice(config.prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
try {
let commandFile = require(`./commands/${command}.js`);
commandFile.run(bot, message, args);
} catch (err) {
return
}
});
client.on("guildCreate", guild => {
let guildp = guild.owner
guildp.send("Thanks for adding me to your server! \n To save you some time I would suggest you run the command 'sat!setup' to create the nessecary roles and channels for the bot. \n Please note that the channel is not made with perms.\n ***[PLEASE NOTE!] - I am still in beta so any issues with any part of the bot please tell us with sat!bug! \n Thanks!")
})
client.login(config.token);
You need to open connection with the database and then run the SQL query.
const sql = require("sqlite")
const db = sql.open('./database.sqlite', { Promise });
db.run("CREATE TABLE IF NOT EXISTS guild (guildId TEXT, language INTEGER, links INTEGER)");

Resources