Add files via upload

This commit is contained in:
Josh S 2022-06-18 23:28:38 -04:00 committed by GitHub
commit 5a0271b7b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 3319 additions and 0 deletions

6
Config.js Normal file
View file

@ -0,0 +1,6 @@
module.exports = {
prefix: ["e"], // Prefixes of the bot
developers: ["764888169047916636", "756160653307412532"], //Owners of the bot
token: "OTgwNjc5NTQ3NjI2MzQ4NjE0.GBgoHE.cDDeLHcvsVDc3in53sMeS08GjsekiSPpKJWDxQ", //TOKEN
mongo: "mongodb://144.172.80.86:3465" // Mongo URI
}

View file

@ -0,0 +1,8 @@
module.exports = {
name : 'evalbtn',
returnNoErrors: true,
ownerOnly: true,
run : async(client, interaction, container) => {
interaction.message.delete()
}
}

View file

@ -0,0 +1,11 @@
module.exports = {
name: "log",
type: "MESSAGE",
run: async(client, interaction, container) => {
console.log(interaction.channel.messages.cache.get(interaction.targetId) ?? await interaction.channel.messages.fetch(interaction.targetId))
interaction.reply({
content: "Logged message to console.",
ephemeral: true
})
}
}

View file

@ -0,0 +1,12 @@
module.exports = {
name: "ping",
description: "Run this to see my ping.",
run: async(client, interaction, container) => {
const ping = new container.Discord.MessageEmbed()
.setColor('RANDOM')
.setTimestamp()
.setTitle('🏓╎ Pong!')
.setDescription(`🏠╎Websocket Latency: ${client.ws.ping}ms\n🤖╎Bot Latency: ${Date.now() - interaction.createdTimestamp}ms`);
interaction.reply({ embeds: [ping] })
}
}

View file

@ -0,0 +1,96 @@
const react = require('../../../Functions/mongodb-reaction-role')
module.exports = {
name: 'reaction',
description: 'Create/Delete/Edit reaction roles',
ownerOnly: true,
options: [{
name: 'create',
description: 'Create a reaction role',
type: 'SUB_COMMAND',
options: [{
name: 'message',
description: 'The message ID',
required: true,
type: 'STRING'
},
{
name: 'role',
description: 'The role ID',
required: true,
type: 'ROLE'
},
{
name: 'emoji',
description: 'The emoji',
required: true,
type: 'STRING'
},
{
name: 'channel',
description: 'The channel',
required: true,
type: 'CHANNEL',
channel_type: 'GUILD_TEXT'
},
]
},
{
name: 'delete',
description: 'Delete a reaction role',
type: 'SUB_COMMAND',
options: [{
name: 'message',
description: 'The message ID',
required: true,
type: 'STRING'
},
{
name: 'emoji',
description: 'The emoji',
required: true,
type: 'STRING'
},
]
}
],
run: async (client, interaction, container) => {
try {
if (interaction.options.getSubcommand() === 'create') {
const message = interaction.options.getString('message');
const role = interaction.options.getRole('role').id;
const emoji = interaction.options.getString('emoji');
const channel = interaction.options.getChannel('channel').id;
await react.createrr(client, interaction.guild.id, message, role, emoji, false); //the last field is : if the person should be dm
//find the given message
const msg = await interaction.guild.channels.cache.find(c => c.id === channel).messages.fetch(message);
await msg.react(emoji);
interaction.reply("Successfully created the reaction role!")
} else if (interaction.options.getSubcommand() === 'delete') {
const message = interaction.options.getString('message');
const emoji = interaction.options.getString('emoji');
/// await react.deleterr(client, message.guild.id ,"message.id" , "emoji");
/// !deleterr <message.id> <emoji>
await react.deleterr(client, interaction.guild.id, message, emoji);
interaction.reply("Successfully deleted the reaction role!")
}
} catch (error) {
console.log(error)
await interaction.reply("Something went wrong.\n", error);
}
}
}

View file

@ -0,0 +1,50 @@
const { inspect } = require('util')
module.exports = {
name : 'eval',
ownerOnly: true,
options: [{
name: 'code',
description: 'The code to run',
required: true,
type: 'STRING'
}],
run : async(client, interaction, container) => {
Object.assign(this, container)
const row = new container.Discord.MessageActionRow()
.addComponents(
new container.Discord.MessageButton()
.setCustomId('evalbtn')
.setLabel('Delete Output')
.setStyle('DANGER'),
);
let code = interaction.options.getString('code').trim()
let depth = 0
const originalCode = code
if(!code) return interaction.reply("Please specify something to Evaluate")
try{
if (originalCode.includes("--str")) code = `${code.replace("--str", "").trim()}.toString()`
if (originalCode.includes("--send")) code = `interaction.channel.send(${code.replace("--send", "").trim()})`
if (originalCode.includes("--async")) code = `(async () => {${code.replace("--async", "").trim()}})()`
if (originalCode.includes("--depth=")) depth = originalCode.split("--depth=")[1]; code = code.split("--depth=")[0]
code = code.replace("--silent", "").trim()
code = await eval(code)
code = inspect(code, { depth: depth })
if (String(code).length > 1990) code = "Output is too long"
if (String(code).includes(container.Config.token)) code = "This message contained client's token."
if (originalCode.includes("--silent")) return;
else interaction.reply({
content:`\`\`\`js\n${code}\n\`\`\``,
components: [row],
allowedMentions: {
repliedUser: false
}
})
} catch (error){
console.log(error)
interaction.reply({
content:`\`\`\`js\n${error}\n\`\`\``,
components: [row]
})
}
}
}

View file

@ -0,0 +1,36 @@
const { exec } = require("child_process")
module.exports = {
name: 'exec',
ownerOnly: true,
options: [{
name: 'command',
description: 'The command to execute',
required: true,
type: 'STRING'
}],
run: async (client, interaction, container) => {
const row = new container.Discord.MessageActionRow()
.addComponents(
new container.Discord.MessageButton()
.setCustomId('evalbtn')
.setLabel('Delete Output')
.setStyle('DANGER')
)
let lola = interaction.options.getString('command')
if (!lola) return interaction.reply("Please provide what to execute in the terminal!")
exec(`${lola}`, (error, stdout) => {
let response = (error || stdout)
if (error) {
interaction.reply({
content:`\`\`\`js\n${error.message}\n\`\`\``,
components: [row]
})
} else {
interaction.reply({
content:`\`\`\`js\n${response}\n\`\`\``,
components: [row]
})
}
})
}
}

View file

@ -0,0 +1,12 @@
module.exports = {
name: "errorManager",
customEvent: true,
run: async(client) => {
process.on('unhandledRejection', error => {
console.log(error)
})
process.on('uncaughtException', error => {
console.log(error)
})
}
}

View file

@ -0,0 +1,10 @@
module.exports = {
name: "interactionCreate",
run: async(interaction, client) => {
const loadCommandOptions = require("../../Structures/CommandOptions/loadCommandOptions")
if (interaction.isButton()) loadCommandOptions(client, interaction, client.commands.buttonCommands.get(interaction.customId), true, "Button")
else if (interaction.isSelectMenu()) loadCommandOptions(client, interaction, client.commands.selectMenus.get(interaction.values[0] ?? interaction.customId), true, "SelectMenus")
else if (interaction.isCommand()) loadCommandOptions(client, interaction, client.commands.slashCommands.get(interaction.commandName), true, "SlashCommand")
else if (interaction.isContextMenu()) loadCommandOptions(client, interaction, client.commands.contextMenus.get(interaction.commandName), true, "ContextMenus")
}
}

View file

@ -0,0 +1,17 @@
module.exports = {
name: "messageCreate",
run: async(message, client, container) => {
const loadCommandOptions = require("../../Structures/CommandOptions/loadCommandOptions")
container.Config.prefix.forEach(prefix => {
if (!message.content.toLowerCase().startsWith(prefix)) return;
const cmdName = message.content.toString().toLowerCase().slice(prefix.length).trim().split(" ")[0]
const command = client.commands.messageCommands.get(cmdName) ?? client.commands.messageCommands.get(client.commands.messageCommands.aliases.get(cmdName))
if (!command) return;
if (command.allowBots) loadCommandOptions(client, message, command, false)
else if (message.author.bot) return;
else if (command.guildOnly == false) loadCommandOptions(client, message, command, false)
else if (!message.guild) return;
else loadCommandOptions(client, message, command, false)
})
}
}

View file

@ -0,0 +1,62 @@
const chalk = require("chalk")
const Box = require("cli-box")
module.exports = {
name: "ready",
once: true,
run: async(client) => {
client.user.setActivity('E', {
type: `WATCHING`,
})
const ClientBox = new Box({
w: Math.floor(client.user.tag.length + 27 ),
h: 7,
stringify: false,
marks: {
nw: '╭',
n: '─',
ne: '╮',
e: '│',
se: '╯',
s: '─',
sw: '╰',
w: '│'
},
hAlign: 'left',
}, `C L I E N T I N F O R M A T I O N
Client Details :: ${client.user.tag}
Guilds Count :: ${client.guilds.cache.size}
User Count :: ${client.users.cache.size}
NodeJS Version :: ${process.version}
`).stringify()
const CommandsBox = new Box({
w: Math.floor(`Initiating ${client.commands.messageCommands.aliases.size} messageCommands Aliases.`.length + 37),
h: 8,
stringify: false,
marks: {
nw: '╭',
n: '─',
ne: '╮',
e: '│',
se: '╯',
s: '─',
sw: '╰',
w: '│'
},
hAlign: "left",
}, `C O M M A N D S I N F O R M A T I O N
MessageCommands :: Initiating ${client.commands.messageCommands.size} messageCommands.
MessageCommands Aliases :: Initiating ${client.commands.messageCommands.aliases.size} messageCommands Aliases.
SlashCommands :: Initiating ${client.commands.slashCommands.size} slashCommands.
SelectMenus :: Initiating ${client.commands.selectMenus.size} selectMenus.
ContextMenus :: Initiating ${client.commands.contextMenus.size} contextMenus.
ButtonCommands :: Initiating ${client.commands.buttonCommands.size} buttonCommands.
Client Events :: Initiating ${client.events.size} events.
`).stringify()
console.log(chalk.bold.greenBright(ClientBox))
console.log(chalk.bold.blueBright(CommandsBox))
}
}

View file

@ -0,0 +1,20 @@
const react = require("../../Functions/mongodb-reaction-role");
module.exports = {
name: "messageReactionAdd",
run: async (reaction, user, client, container) => {
if (user.partial) await user.fetch();
if (reaction.partial) await reaction.fetch();
if (reaction.message.partial) await reaction.message.fetch();
if (user.bot) return;
let rolefetch = await react.fetchrr(client, reaction.message.guild.id, reaction.message.id, reaction.emoji.name);
if (!rolefetch) return;
let member = await reaction.message.guild.members.cache.get(user.id)
if (!member.roles.cache.has(rolefetch.roleid)) {
await member.roles.add(rolefetch.roleid)
console.log(`Role on ${reaction.emoji.name} has been given`)
}
}
}

View file

@ -0,0 +1,19 @@
const react = require("../../Functions/mongodb-reaction-role");
module.exports = {
name: "messageReactionRemove",
run: async (reaction, user, client, container) => {
if (user.partial) await user.fetch();
if (reaction.partial) await reaction.fetch();
if (reaction.message.partial) await reaction.message.fetch();
let rolefetch = await react.fetchrr(client, reaction.message.guild.id, reaction.message.id, reaction.emoji.name);
if (!rolefetch) return;
let member = await reaction.message.guild.members.cache.get(user.id)
if (member.roles.cache.has(rolefetch.roleid)) {
await member.roles.remove(rolefetch.roleid)
console.log(`Role on ${reaction.emoji.name} has been given`)
}
}
}

View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 meister03
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,199 @@
<p align="center"><a href="https://nodei.co/npm/mongodb-reaction-role/"><img src="https://nodei.co/npm/mongodb-reaction-role.png"></a></p>
<p align="center"><img src="https://img.shields.io/npm/v/discord-mongodb-prefix"> <img src="https://img.shields.io/github/repo-size/meister03/mongodb-reaction-role"> <img src="https://img.shields.io/npm/l/mongodb-reaction-role"> <img src="https://img.shields.io/github/contributors/mongodb-reaction-role"> <a href="https://discord.gg/YTdNBHh"><img src="https://discordapp.com/api/guilds/697129454761410600/widget.png" alt="Discord server"/></a></p>
# Discord Mongodb-reaction-role
A lightweight managing package to save/add/remove reaction roles and save them in a db. Intelligent saving ways to lower traffic up to 90% and prevent multipy fetches. This Package can be used for large bots too!
**If you need help feel free to join our <a href="https://discord.gg/YTdNBHh ">discord server</a>. We will provied you all help ☺**
# Download
You can download it from npm:
```cli
npm i mongodb-reaction-role
npm i mongoose // when u did not installed it
```
# Setting Up
First we include the module into the project (into your main bot file).
**Intent must me enabled. See more [here](https://cdn.discordapp.com/attachments/736254990619770981/797536603798634556/unknown.png)**
```js
const react = require("mongodb-reaction-role");
const client = new Discord.Client({
autoReconnect: true,
partials: ["MESSAGE", "CHANNEL", "GUILD_MEMBER", "REACTION", "MESSAGE", "USER"]
}); // this is required to get the messages of the reaction roles
client.react = new Map(); // do not rename here something, or else Dx // save all msg id, role id
client.fetchforguild = new Map() //it will be saved, if the reaction roles were fetched from db
```
After that, you have to provide a valid mongodb url and set the default prefix.
```js
react.setURL("mongodb://..."); //builts a connection with the db
```
# Fetching Reaction Roles/ Add Role
*Following examples assume that your `Discord.Client` is called `client`.*
```js
client.on('messageReactionAdd',async (reaction , user ) => {
if (user.partial) await user.fetch();
if (reaction.partial) await reaction.fetch();
if (reaction.message.partial) await reaction.message.fetch();
let rolefetch = await react.fetchrr(client, reaction.message.guild.id ,reaction.message.id , reaction.emoji.name);
if(!rolefetch) return;
let member = await reaction.message.guild.members.cache.get(user.id)
if(!member.roles.cache.has(rolefetch.roleid)){
await member.roles.add(rolefetch.roleid)
console.log(`Role on ${reaction.emoji.name} has been given`)
}
});
```
# Remove Role
```js
client.on('messageReactionRemove',async (reaction, user) => {
if (user.partial) await user.fetch();
if (reaction.partial) await reaction.fetch();
if (reaction.message.partial) await reaction.message.fetch();
let rolefetch = await react.fetchrr(client, reaction.message.guild.id ,reaction.message.id , reaction.emoji.name);
if(!rolefetch) return;
let member = await reaction.message.guild.members.cache.get(user.id)
if(member.roles.cache.has(rolefetch.roleid)){
await member.roles.remove(rolefetch.roleid)
console.log(`Role on ${reaction.emoji.name} has been given`)
}
});
```
# Create/Delete a Reaction Role
```js
if(command === "createrr"){ /// you can use your command handler to, but look that you overgive the parameters client, message
///await react.createrr(client, message.guild.id ,"message.id" , "roleid" , "emoji");
/// !createrr <message.id> <roleid> <emoji>
if(!args[0] || !args[1] || !args[2]) return message.channel.send("Pls provide the arguments. ex: `!createrr <message.id> <roleid> <emoji>`")
await react.createrr(client, message.guild.id ,args[0] , args[1] , args[2], "false"); //the last field is : if the person should be dm
message.channel.send("Successfully created the reaction role!")
}
```
```js
if(command === "deleterr"){
/// await react.deleterr(client, message.guild.id ,"message.id" , "emoji");
/// !deleterr <message.id> <emoji>
if(!args[0] || !args[1]) return message.channel.send("Pls provide the arguments. ex: `!deleterr <message.id> <emoji>`")
await react.deleterr(client, message.guild.id ,args[0] , args[1]);
message.channel.send("Successfully deleted the reaction role!")
}
```
```js
if(command === "editrr"){
///await react.createrr(client, message.guild.id ,"message.id" , "roleid" , "emoji");
/// !editrr <message.id> <new.roleid> <emoji>
if(!args[0] || !args[1] || !args[2]) return message.channel.send("Pls provide the arguments. ex: `!editrr <message.id> <new.roleid> <emoji>`")
await react.editrr(client, message.guild.id ,args[0] , args[1] , args[2]);
message.channel.send("Successfully edited the reaction role!")
}
```
# Whole Code
```js
const Discord = require('discord.js');
const { prefix, token , url } = require('./config.json');
const react = require("mongodb-reaction-role");
const client = new Discord.Client({
autoReconnect: true,
partials: ["MESSAGE", "CHANNEL", "GUILD_MEMBER", "REACTION", "MESSAGE", "USER"]
}); // this is required to get the messages of the reaction roles
client.react = new Map(); // do not rename here something, or else Dx // save all msg id, role id
client.fetchforguild = new Map() // it will be saved, if the reaction roles were fetched from db
//// Add this
react.setURL(url);
client.once('ready', () => {
console.log('Ready!');
});
client.on('messageReactionAdd',async (reaction , user ) => {
if (user.partial) await user.fetch();
if (reaction.partial) await reaction.fetch();
if (reaction.message.partial) await reaction.message.fetch();
let rolefetch = await react.fetchrr(client, reaction.message.guild.id ,reaction.message.id , reaction.emoji.name);
if(!rolefetch) return;
let member = await reaction.message.guild.members.cache.get(user.id)
if(!member.roles.cache.has(rolefetch.roleid)){
await member.roles.add(rolefetch.roleid)
console.log(`Role on ${reaction.emoji.name} has been given`)
}
});
client.on('messageReactionRemove',async (reaction, user) => {
if (user.partial) await user.fetch();
if (reaction.partial) await reaction.fetch();
if (reaction.message.partial) await reaction.message.fetch();
let rolefetch = await react.fetchrr(client, reaction.message.guild.id ,reaction.message.id , reaction.emoji.name);
if(!rolefetch) return;
let member = await reaction.message.guild.members.cache.get(user.id)
if(member.roles.cache.has(rolefetch.roleid)){
await member.roles.remove(rolefetch.roleid)
console.log(`Role on ${reaction.emoji.name} has been given`)
}
});
client.on('message', async message => {
if (message.author.bot) return;
//add this
/// add this
if (!message.content.startsWith(prefix)) return;
const args = message.content.slice(prefix.length).trim().split(/ +/);
const command = args.shift().toLowerCase();
if(command === "createrr"){ /// you can use your command handler to, but look that you overgive the parameters client, message
///await react.createrr(client, message.guild.id ,"message.id" , "roleid" , "emoji");
/// !createrr <message.id> <roleid> <emoji>
if(!args[0] || !args[1] || !args[2]) return message.channel.send("Pls provide the arguments. ex: `!createrr <message.id> <roleid> <emoji>`")
await react.createrr(client, message.guild.id ,args[0] , args[1] , args[2], "false"); /// the last field is : if the person should be dm
message.channel.send("Successfully created the reaction role!")
}
if(command === "deleterr"){
/// await react.deleterr(client, message.guild.id ,"message.id" , "emoji");
/// !deleterr <message.id> <emoji>
if(!args[0] || !args[1]) return message.channel.send("Pls provide the arguments. ex: `!deleterr <message.id> <emoji>`")
await react.deleterr(client, message.guild.id ,args[0] , args[1]);
message.channel.send("Successfully deleted the reaction role!")
}
if(command === "editrr"){
///await react.createrr(client, message.guild.id ,"message.id" , "roleid" , "emoji");
/// !editrr <message.id> <new.roleid> <emoji>
if(!args[0] || !args[1] || !args[2]) return message.channel.send("Pls provide the arguments. ex: `!editrr <message.id> <new.roleid> <emoji>`")
await react.editrr(client, message.guild.id ,args[0] , args[1] , args[2]);
message.channel.send("Successfully edited the reaction role!")
}
if(command === "rrstats"){
const stats = new Discord.MessageEmbed()
.setTitle("Reaction roles stats")
.addField("Reaction roles found:" , "```" + client.react.size + " reaction roles" + "```")
.addField("Fetched Server:" , "```" + client.fetchforguild.size + "```")
.setColor("YELLOW")
return message.channel.send(stats)
}
});
client.login(token);
```
*Is time for you to use the code creative..*
# Methods
**See if the reaction on the message id exist as reaction role or when not fetched in the db**
```js
let fetch = await react.fetchrr(client, reaction.message.guild.id ,reaction.message.id , reaction.emoji.name);
//undefined || or gives a map entry ==> fetch.roleid, fetch.messageid , fetch.reaction, fetch.guildid , fetch.dm
```
**Fetch all reaction roles and save them in a map (just use this for stats not for the reaction event)**
```js
await react.fetchallrr(client);
```
**Have fun and feel free to contribute/suggest or contact me on my discord server or per dm on Meister#9667**
# Bugs, Glitches and Issues
If you encounter any problems fell free to open an issue in our <a href="https://github.com/meister03/mongodb-reaction-role/issues">github repository or join the discord server.</a>.

View file

@ -0,0 +1,169 @@
const mongoose = require("mongoose");
const serverset = require("./models/schema.js");
class react {
/**
* @param {string} [dbUrl] - A valid mongo database URI.
*/
static async setURL(dbUrl) {
if (!dbUrl) throw new TypeError("A database url was not provided.");
return mongoose.connect(dbUrl, {
useNewUrlParser: true,
useUnifiedTopology: true
}).then(() => {
console.log("Package Connected to database.");
});
}
/**
* @param {object} [client] - Discord client, will save the data in a Map to prevent multiple fetches
* @param {string} [guildId] - Discord guild id.
* @param {string} [msgid] - on which should the reaction roles be.
* @param {string} [roleid] - Discord guild id.
* @param {string} [emoji] - on which emoji u would get the role
* @param {Boolean} [dm] - Discord guild id.
*/
static async createrr(client, guildId, msgid, roleid ,emoji , dm) {
if (!client) throw new TypeError("An client was not provided.");
if (!guildId) throw new TypeError("A guild id was not provided.");
if (!msgid) throw new TypeError("A message id was not provided.");
if (!emoji) throw new TypeError("A reaction/emoji was not provided.");
if(!roleid) throw new TypeError("A role id was not provided.");
dm = dm ? dm : false ; // when dm is undefined // if they should get a message , when they get the role
const issame = await serverset.findOne({guildid: guildId , msgid: msgid , reaction: emoji , roleid: roleid});
if (issame) return false;
const newRR = new serverset({
guildid: guildId,
msgid: msgid,
reaction: emoji ,
roleid: roleid,
dm: dm
});
await newRR.save().catch(e => console.log(`Failed to create reaction role: ${e}`));
client.react.set(msgid+emoji, { ///this saves the msgid in a map to prevent a fetch
guildid: guildId,
msgid: msgid,
reaction: emoji ,
roleid: roleid,
dm: dm
});
return newRR;
}
/**
* @param {object} [client] - Discord client, will save the data in a Map to prevent multiple fetches
* @param {string} [guildId] - Discord guild id.
* @param {string} [msgid] - on which should the reaction roles be.
* @param {string} [emoji] - on which emoji u would get the role
*/
static async deleterr(client, guildId , msgid, emoji) {
if (!client) throw new TypeError("A client was not provided.");
if (!guildId) throw new TypeError("A guild id was not provided.");
if (!msgid) throw new TypeError("A message id was not provided.");
if (!emoji) throw new TypeError("A reaction/emoji was not provided.");
const reactionRole = await serverset.findOne({guildid: guildId , msgid: msgid , reaction: emoji });
if (!reactionRole) return false;
await serverset.findOneAndDelete({guildid: guildId , msgid: msgid , reaction: emoji }).catch(e => console.log(`Failed to reaction: ${e}`));
client.react.delete(msgid+emoji);
return reactionRole;
}
/**
* @param {object} [client] - Discord client, will save the data in a Map to prevent multiple fetches
* @param {string} [guildId] - Discord guild id.
* @param {string} [msgid] - on which should the reaction roles be.
* @param {string} [newroleid] - Discord guild id.
* @param {string} [emoji] - on which emoji u would get the role
*/
static async editrr(client, guildId , msgid, newroleid , emoji) {
if (!client) throw new TypeError("An client was not provided.");
if (!guildId) throw new TypeError("A guild id was not provided.");
if (!msgid) throw new TypeError("A message id was not provided.");
if (!emoji) throw new TypeError("A reaction/emoji was not provided.");
if(!newroleid) throw new TypeError("A role id was not provided.");
const reactionRole = await serverset.findOne({guildid: guildId , msgid: msgid , reaction: emoji });
if (!reactionRole) return false;
reactionRole.roleid= newroleid;
await reactionRole.save().catch(e => console.log(`Failed to save new prefix: ${e}`) );
client.react.set(msgid+emoji, { ///this saves the msgid in a map to prevent a fetch
guildid: guildId,
msgid: msgid,
reaction: emoji ,
roleid: newroleid,
dm: reactionRole.dm
});
return;
}
/**
* @param {object} [client] - Discord client, will save the data in a Map to prevent multiple fetches
* @param {string} [guildId] - Discord guild id.
* @param {string} [msgid] - Discord guild id.
* @param {string} [emoji] - Discord guild id.
*/
static async fetchrr(client, guildId ,msgid , emoji) {
if (!client) throw new TypeError("A client was not provided.");
if (!guildId) throw new TypeError("A guild id was not provided.");
if(!client.fetchforguild.has(guildId)){
let allrole = await serverset.find({guildid: guildId}).sort([['guildid', 'descending']]).exec();
let i = 0;
for(i ; i < Object.keys(allrole).length; i++){
await client.react.set(allrole[i].msgid+allrole[i].reaction, { ///this saves the msgid in a map to prevent a fetch
guildid: allrole[i].guildid,
msgid: allrole[i].msgid,
reaction: allrole[i].reaction ,
roleid: allrole[i].roleid,
dm: allrole[i].dm
});
}
client.fetchforguild.set(guildId, { ///this saves the msgid in a map to prevent a fetch
guildid: guildId,
totalreactions: Object.keys(allrole).length
});
}
return client.react.get(msgid + emoji);
}
/**
* @param {object} [client] - Discord client, will save the data in a Map to prevent multiple fetches
*/
static async fetchallrr(client) {
if (!client) throw new TypeError("An client was not provided.");
let all = await serverset.find({}).sort([['guildid', 'descending']]).exec();
/* let i = 0;
for(i ; i < Object.keys(all).length; i++){
client.react.set(all[i].msgid+all[i].reaction, { ///this saves the msgid in a map to prevent a fetch
guildid: all[i].guildid,
msgid: all[i].msgid,
reaction: all[i].reaction ,
roleid: all[i].roleid,
dm: all[i].dm
});
}*/
return all;
}
}
module.exports = react;

View file

@ -0,0 +1,12 @@
const mongoose = require("mongoose");
const reactionSchema = new mongoose.Schema({
guildid: { type: String },
msgid: { type: String},
roleid: { type: String},
reaction: { type: String }, /// Change the field name | add other Fields, do not forget the "," ;)
dm: {type: Boolean }
});
module.exports = mongoose.model('reaction', reactionSchema);

View file

@ -0,0 +1,35 @@
{
"name": "mongodb-reaction-role",
"version": "1.1.0",
"description": "A lightweight and easy to use db managing package to give roles with reactions",
"main": "index.js",
"dependencies": {
"mongoose": "^5.7.1"
},
"devDependencies": {},
"repository": {
"type": "git",
"url": "git+https://github.com/meister03/mongodb-reaction-role.git"
},
"keywords": [
"discord",
"discord.js",
"intelligent saving",
"bot",
"bots",
"reaction roles",
"reaction",
"mongo",
"mongoose",
"mongodb",
"manage-roles",
"framework"
],
"author": "meister03",
"license": "MIT",
"bugs": {
"url": "https://github.com/meister03/mongodb-reaction-role/issues"
},
"homepage": "https://github.com/meister03/mongodb-reaction-role#readme"
}

View file

@ -0,0 +1,21 @@
module.exports = async function (message, command, Discord) {
if (!command.anyClientPermission) return false;
if (command.anyClientPermission.some(i => message.member.permissions.has(i))) return false;
else {
if (command.returnAnyClientPermissions == false || command.returnNoErrors) return true;
else message.reply({
embeds: [new Discord.MessageEmbed()
.setAuthor({
name: message.member.user.tag,
iconURL: message.member.user.displayAvatarURL({ dynamic: true })
})
.setColor("RANDOM")
.setTimestamp()
.setDescription(`I required any one of these permissions for this command.\n${command.anyClientPermission.join("\n•")}`)],
allowedMentions: {
repliedUser: false
}
})
return true
}
}

View file

@ -0,0 +1,21 @@
module.exports = async function (message, command, Discord) {
if (!command.anyUserPermission) return false;
if (command.anyUserPermission.some(i => message.member.permissions.has(i))) return false;
else {
if (command.returnAnyUserPermissions == false || command.returnNoErrors) return true;
else message.reply({
embeds: [new Discord.MessageEmbed()
.setAuthor({
name: message.member.user.tag,
iconURL: message.member.user.displayAvatarURL({ dynamic: true })
})
.setColor("RANDOM")
.setTimestamp()
.setDescription(`You require any one of these permissions to be able to run this command..\n${command.anyUserPermission.join("\n•")}`)],
allowedMentions: {
repliedUser: false
}
})
return true
}
}

View file

@ -0,0 +1,25 @@
module.exports = async function (message, command, Discord) {
if (!command.clientPermissions) return false;
let missing = []
command.clientPermissions.forEach(i => {
if (!message.guild.me.permissions.has(i)) missing.push(i)
})
if (missing.length == 0) return false;
else {
if (command.returnClientPermissions == false || command.returnNoErrors) return true;
else message.reply({
embeds: [new Discord.MessageEmbed()
.setAuthor({
name: message.member.user.tag,
iconURL: message.member.user.displayAvatarURL({ dynamic: true })
})
.setColor("RANDOM")
.setTimestamp()
.setDescription(`I require these permissions to be able to run this command.\n${missing.join("\n•")}`)],
allowedMentions: {
repliedUser: false
}
})
return true
}
}

View file

@ -0,0 +1,30 @@
const db = require("quick.db")
module.exports = async function (client, message, command, isInteraction, interactionType, Discord) {
if (!command.cooldown) return false;
const currentTime = Date.now()
const user = message.member.user
const cooldown = command.cooldown
const oldTime = await db.get(`CooldownSystem.${message.guild.id}.${command.name}.${interactionType ?? "Normal"}.${user.id}`) ?? 0
if (Math.floor(currentTime - oldTime) >= cooldown || oldTime == 0) {
await db.set(`CooldownSystem.${message.guild.id}.${command.name}.${interactionType ?? "Normal"}.${user.id}`, currentTime)
return false;
} else {
if (command.returnCooldown == false || command.returnNoErrors) return true;
else {
message.reply({
embeds: [new Discord.MessageEmbed()
.setAuthor({
name: message.member.user.tag,
iconURL: message.member.user.displayAvatarURL({ dynamic: true })
})
.setTimestamp()
.setColor("RANDOM")
.setDescription(`You are currently at cooldown until <t:${Math.floor(Math.floor(oldTime + cooldown) / 1000)}>`)],
allowedMentions: {
repliedUser: false
}
})
return true
}
}
}

View file

@ -0,0 +1,25 @@
module.exports = async function (message, command, Discord) {
if (!command.onlyChannels) return false;
if (command.onlyChannels.some(id => id == message.channel.id)) return false;
else {
let onlyChannels = []
command.onlyChannels.forEach(id => {
onlyChannels.push(`<#${id}>`)
})
if (command.returnOnlyChannels == false || command.returnNoErrors) return true;
else message.reply({
embeds: [new Discord.MessageEmbed()
.setAuthor({
name: message.member.user.tag,
iconURL: message.member.user.displayAvatarURL({ dynamic: true })
})
.setColor("RANDOM")
.setTimestamp()
.setDescription(`This command can only be ran in these channels.\n${onlyChannels.join("\n•")}`)],
allowedMentions: {
repliedUser: false
}
})
return true;
}
}

View file

@ -0,0 +1,25 @@
module.exports = async function (client, message, command, Discord) {
if (!command.onlyGuilds) return false;
if (command.onlyGuilds.some(id => id == message.guild.id)) return false;
else {
let onlyGuilds = []
command.onlyGuilds.forEach(id => {
onlyGuilds.push(client.guilds.cache.get(id).name)
})
if (command.returnOnlyGuilds == false || command.returnNoErrors) return true;
else message.reply({
embeds: [new Discord.MessageEmbed()
.setAuthor({
name: message.member.user.tag,
iconURL: message.member.user.displayAvatarURL({ dynamic: true })
})
.setColor("RANDOM")
.setTimestamp()
.setDescription(`This command can only be ran in these guilds.\n${onlyGuilds.join("\n•")}`)],
allowedMentions: {
repliedUser: false
}
})
return true
}
}

View file

@ -0,0 +1,25 @@
module.exports = async function (client, message, command, Discord) {
if (!command.onlyUsers) return false;
if (command.onlyUsers.some(i => i == message.member.user.id)) return false;
else {
let onlyUsers = []
command.onlyUsers.forEach(id => {
onlyUsers.push(`<@${id}>`)
})
if (command.returnOnlyUsers == false || command.returnNoErrors) return true;
else message.reply({
embeds: [new Discord.MessageEmbed()
.setAuthor({
name: message.member.user.tag,
iconURL: message.member.user.displayAvatarURL({ dynamic: true })
})
.setColor("RANDOM")
.setTimestamp()
.setDescription(`This command can only be ran by these people.\n${onlyUsers.join("\n• ")}`)],
allowedMentions: {
repliedUser: false
}
})
return true;
}
}

View file

@ -0,0 +1,22 @@
const config = require("../../../Config")
module.exports = async function (message, command, Discord) {
if (!command.ownerOnly) return false;
if (config.developers.some(id => message.member.user.id == id)) return false
else {
if (command.returnOwnerOnly == false || command.returnNoErrors) return true;
else message.reply({
embeds: [new Discord.MessageEmbed()
.setAuthor({
name: message.member.user.tag,
iconURL: message.member.user.displayAvatarURL({ dynamic: true })
})
.setColor("RANDOM")
.setTimestamp()
.setDescription(`This command is reserved for the developers of the bot.`)],
allowedMentions: {
repliedUser: false
}
})
return true
}
}

View file

@ -0,0 +1,23 @@
module.exports = async function (message, command, Discord) {
if (!command.requiredAnyRole) return false;
if (command.requiredAnyRole.some(i => message.member.roles.cache.has(i))) return false;
else {
let requiredRoles = []
command.requiredAnyRole.forEach(i => requiredRoles.push(`<@&${i}>`))
if (command.returnRequiredAnyRole == false || command.returnNoErrors) return true;
else message.reply({
embeds: [new Discord.MessageEmbed()
.setAuthor({
name: message.member.user.tag,
iconURL: message.member.user.displayAvatarURL({ dynamic: true })
})
.setColor("RANDOM")
.setTimestamp()
.setDescription(`You are required to have any one of these roles to be able to run this command.\n${requiredRoles.join("\n•")}`)],
allowedMentions: {
repliedUser: false
}
})
return true;
}
}

View file

@ -0,0 +1,25 @@
module.exports = async function (message, command, Discord) {
if (!command.requiredRoles) return false;
let missing = []
command.requiredRoles.forEach(role => {
if (!message.member.roles.cache.has(role)) missing.push(`<@&${role}>`);
})
if (missing.length == 0) return false;
else {
if (command.returnRequiredRoles == false || command.returnNoErrors) return true;
else message.reply({
embeds: [new Discord.MessageEmbed()
.setAuthor({
name: message.member.user.tag,
iconURL: message.member.user.displayAvatarURL({ dynamic: true })
})
.setColor("RANDOM")
.setTimestamp()
.setDescription(`You are required to have these roles to be able to run this command.\n${missing.join("\n•")}`)],
allowedMentions: {
repliedUser: false
}
})
return true
}
}

View file

@ -0,0 +1,25 @@
module.exports = async function (message, command, Discord) {
if (!command.userPermissions) return false;
let missing = []
command.userPermissions.forEach(i => {
if (!message.member.permissions.has(i)) missing.push(i)
})
if (missing.length == 0) return false
else {
if (command.returnUserPermissions == false || command.returnNoErrors) return true;
else message.reply({
embeds: [new Discord.MessageEmbed()
.setAuthor({
name: message.member.user.tag,
iconURL: message.member.user.displayAvatarURL({ dynamic: true })
})
.setColor("RANDOM")
.setTimestamp()
.setDescription(`You are required to have these permissions to be able to run this command.\n${missing.join("\n•")}`)],
allowedMentions: {
repliedUser: false
}
})
return true;
}
}

View file

@ -0,0 +1,35 @@
const Discord = require("discord.js")
const { path, config } = require("../../../bot")
module.exports = async function (client, message, command, isInteraction, interactionType) {
if (!command) return;
const container = {
RootPath: path,
Config: config,
Discord: Discord
}
if (await require("./Cooldown")(client, message, command, isInteraction, interactionType, Discord)) return;
else if (await require("./OwnerOnly")(message, command, Discord)) return;
else if (await require("./UserPermissions")(message, command, Discord)) return;
else if (await require("./ClientPermissions")(message, command, Discord)) return;
else if (await require("./AnyUserPermissions")(message, command, Discord)) return;
else if (await require("./AnyClientPermissions")(message, command, Discord)) return;
else if (await require("./RequiredAnyRole")(message, command, Discord)) return;
else if (await require("./RequiredRoles")(message, command, Discord)) return;
else if (await require("./OnlyChannels")(message, command, Discord)) return;
else if (await require("./OnlyGuilds")(client, message, command, Discord)) return;
else if (await require("./OnlyUsers")(client, message, command, Discord)) return;
else {
if (isInteraction) command.run(client, message, container)
else {
container.Config.prefix.forEach(prefix => {
if (!message.content.toLowerCase().startsWith(prefix)) return;
const cmdName = message.content.trim().toLowerCase().slice(prefix.length).trim().split(" ")[0]
const command = client.commands.messageCommands.get(cmdName) ?? client.commands.messageCommands.get(client.commands.messageCommands.aliases.get(cmdName))
if (!command) return;
let args = message.content.slice(prefix.length).trim()
if (args.toLowerCase().startsWith(cmdName)) args = args.slice(cmdName.length).trim().split(" ")
command.run(client, message, args, container)
})
}
}
}

View file

@ -0,0 +1,12 @@
const fs = require("fs");
const Filer = require("../../Utils/Filer");
module.exports = async function(client, path) {
Filer(`${path}/Src/Commands/ButtonCommands`, async function(err, res) {
res.forEach(file => {
if (fs.statSync(file).isDirectory()) return;
const button = require(file)
if (button.ignoreFile) return;
client.commands.buttonCommands.set(button.name, button)
})
})
}

View file

@ -0,0 +1,55 @@
const fs = require("fs");
const Filer = require("../../Utils/Filer");
module.exports = async function(client, path) {
Filer(`${path}/Src/Commands/ContextMenus`, async function(err, res) {
res.forEach(file => {
if (fs.statSync(file).isDirectory()) return;
const cmd = require(file);
if (cmd.ignoreFile) return;
client.commands.contextMenus.set(require(file).name, require(file))
})
let promise = Promise.resolve()
res.forEach(async function(file) {
promise = promise.then(async function() {
const interval = 5000;
if (fs.statSync(file).isDirectory()) return;
const cmd = require(file);
if (cmd.ignoreFile) return;
if (cmd.guilds && Array.isArray(cmd.guilds)) cmd.guilds.forEach(guildID => {
(async () => {
const guild = client.guilds.cache.get(guildID) ?? await client.guilds.fetch(guildID)
const verifier = guild.commands.cache.find(x => x.name == cmd.name)
if (verifier) await guild.commands.edit(verifier.id, {
name: cmd.name,
options: cmd.options ?? [],
type: cmd.type
})
else await guild.commands.create({
name: cmd.name,
options: cmd.options ?? [],
type: cmd.type
})
})()
})
else {
const verifier = client.application.commands.cache.find(x => x.name == cmd.name)
if (verifier) await client.application.commands.edit(verifier.id, {
name: cmd.name,
options: cmd.options ?? [],
type: cmd.type
})
else await client.application.commands.create({
name: cmd.name,
options: cmd.options ?? [],
type: cmd.type
})
}
return new Promise(function(resolve) {
setTimeout(resolve, interval);
})
})
})
})
}

View file

@ -0,0 +1,23 @@
const fs = require("fs");
const Filer = require("../../Utils/Filer");
const Discord = require("discord.js");
const { path, config } = require("../../../bot")
module.exports = async function(client) {
const container = {
RootPath: path,
Config: config,
Discord: Discord
};
Filer(`${container.RootPath}/Src/Events`, async function(err, res){
res.forEach(file => {
if (fs.statSync(file).isDirectory()) return;
const event = require(file);
if (event.ignoreFile) return;
if (event.customEvent) event.run(client, container);
client.events.set(event.name, event);
if (event.once) client.once(event.name, (...args) => event.run(...args, client, container));
else client.on(event.name, (...args) => event.run(...args, client, container));
})
})
}

View file

@ -0,0 +1,8 @@
module.exports = {
loadMessageCommands: require("./MessageCommands"),
loadEvents: require("./Events"),
loadButtonCommands: require("./ButtonCommands"),
loadContextMenus: require("./ContextMenus"),
loadSelectMenus: require("./SelectMenus"),
loadSlashCommands: require("./SlashCommands")
}

View file

@ -0,0 +1,13 @@
const fs = require("fs");
const Filer = require("../../Utils/Filer");
module.exports = async function(client, path) {
Filer(`${path}/Src/Commands/MessageCommands`, async function(err, res) {
res.forEach(file => {
if (fs.statSync(file).isDirectory()) return;
const command = require(file)
if (command.ignoreFile) return;
client.commands.messageCommands.set(command.name.toLowerCase(), command)
if (command.aliases) command.aliases.forEach(alias => client.commands.messageCommands.aliases.set(alias.toLowerCase(), command.name.toLowerCase()))
})
})
}

View file

@ -0,0 +1,12 @@
const fs = require("fs");
const Filer = require("../../Utils/Filer");
module.exports = async function(client, path) {
Filer(`${path}/Src/Commands/SelectMenus`, async function(err, res) {
res.forEach(file => {
if (fs.statSync(file).isDirectory()) return;
const selectMenu = require(file)
if (selectMenu.ignoreFile) return;
client.commands.selectMenus.set(selectMenu.name, selectMenu)
})
})
}

View file

@ -0,0 +1,59 @@
const fs = require("fs");
const Filer = require("../../Utils/Filer");
module.exports = async function(client, path) {
Filer(`${path}/Src/Commands/SlashCommands`, async function(err, res) {
res.forEach(file => {
if (fs.statSync(file).isDirectory()) return;
const cmd = require(file);
if (cmd.ignoreFile) return;
client.commands.slashCommands.set(require(file).name, require(file))
})
let promise = Promise.resolve()
res.forEach(async function(file) {
promise = promise.then(async function() {
const interval = 5000;
if (fs.statSync(file).isDirectory()) return;
const cmd = require(file);
if (cmd.ignoreFile) return;
if (cmd.guilds && Array.isArray(cmd.guilds)) cmd.guilds.forEach(guildID => {
(async () => {
const guild = client.guilds.cache.get(guildID) ?? await client.guilds.fetch(guildID)
const verifier = guild.commands.cache.find(x => x.name == cmd.name)
if (verifier) await guild.commands.edit(verifier.id, {
name: cmd.name,
description: cmd.description ?? "None",
options: cmd.options ?? [],
type: cmd.type ?? "CHAT_INPUT"
})
else await guild.commands.create({
name: cmd.name,
description: cmd.description ?? "None",
options: cmd.options ?? [],
type: cmd.type ?? "CHAT_INPUT"
})
})()
})
else {
const verifier = client.application.commands.cache.find(x => x.name == cmd.name)
if (verifier) await client.application.commands.edit(verifier.id, {
name: cmd.name,
description: cmd.description ?? "None.",
options: cmd.options ?? [],
type: cmd.type ?? "CHAT_INPUT"
})
else await client.application.commands.create({
name: cmd.name,
description: cmd.description ?? "None.",
options: cmd.options ?? [],
type: cmd.type ?? "CHAT_INPUT"
})
}
return new Promise(function(resolve) {
setTimeout(resolve, interval);
})
})
})
})
}

4
Src/Utils/Filer.js Normal file
View file

@ -0,0 +1,4 @@
const glob = require('glob')
module.exports = (src, callback) => {
glob(src + '/**/*', callback);
}

39
bot.js Normal file
View file

@ -0,0 +1,39 @@
(async () => {
const Discord = require("discord.js");
const config = require("./Config");
const path = __dirname;
const react = require("./Src/Functions/mongodb-reaction-role/index");
const client = new Discord.Client({
intents: 32767,
partials: ["MESSAGE", "CHANNEL", "GUILD_MEMBER", "REACTION", "MESSAGE", "USER"]
});
exports.client = client;
exports.path = path;
exports.config = config;
client.commands = {};
client.events = new Discord.Collection();
client.commands.messageCommands = new Discord.Collection();
client.commands.messageCommands.aliases = new Discord.Collection();
client.commands.contextMenus = new Discord.Collection();
client.commands.slashCommands = new Discord.Collection();
client.commands.buttonCommands = new Discord.Collection();
client.commands.selectMenus = new Discord.Collection();
// The maps of the reactions. uh idk what to call it
client.react = new Map(); // do not rename here something, or else ded // save all msg id, role id
client.fetchforguild = new Map()
// end of that shit
const Handler = require(`${path}/Src/Structures/Handlers/Handler`);
await Handler.loadMessageCommands(client, path);
await Handler.loadEvents(client);
await client.login(config.token);
await Handler.loadSlashCommands(client, path);
await Handler.loadContextMenus(client, path);
await Handler.loadButtonCommands(client, path);
await Handler.loadSelectMenus(client, path);
react.setURL(config.mongo);
})()

0
json.sqlite Normal file
View file

1976
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

21
package.json Normal file
View file

@ -0,0 +1,21 @@
{
"name": "rr-bot",
"version": "1.0.0",
"description": "A reaction role bot in discord.js",
"main": "bot.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node bot.js"
},
"author": "Josh S.",
"dependencies": {
"chalk": "^4.1.2",
"child_process": "^1.0.2",
"cli-box": "^6.0.10",
"discord.js": "^13.6.0",
"fs": "^0.0.1-security",
"glob": "^7.2.0",
"mongoose": "^6.3.6",
"quick.db": "^7.1.3"
}
}