Add files via upload
This commit is contained in:
commit
5a0271b7b0
42 changed files with 3319 additions and 0 deletions
6
Config.js
Normal file
6
Config.js
Normal 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
|
||||
}
|
||||
8
Src/Commands/ButtonCommands/EvalButton.js
Normal file
8
Src/Commands/ButtonCommands/EvalButton.js
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
module.exports = {
|
||||
name : 'evalbtn',
|
||||
returnNoErrors: true,
|
||||
ownerOnly: true,
|
||||
run : async(client, interaction, container) => {
|
||||
interaction.message.delete()
|
||||
}
|
||||
}
|
||||
11
Src/Commands/ContextMenus/LogMessage.js
Normal file
11
Src/Commands/ContextMenus/LogMessage.js
Normal 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
|
||||
})
|
||||
}
|
||||
}
|
||||
12
Src/Commands/SlashCommands/Basic/Ping.js
Normal file
12
Src/Commands/SlashCommands/Basic/Ping.js
Normal 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] })
|
||||
}
|
||||
}
|
||||
96
Src/Commands/SlashCommands/Basic/reactions.js
Normal file
96
Src/Commands/SlashCommands/Basic/reactions.js
Normal 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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
50
Src/Commands/SlashCommands/Dev/Eval.js
Normal file
50
Src/Commands/SlashCommands/Dev/Eval.js
Normal 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]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Src/Commands/SlashCommands/Dev/Exec.js
Normal file
36
Src/Commands/SlashCommands/Dev/Exec.js
Normal 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]
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
12
Src/Events/Client/ErrorManager.js
Normal file
12
Src/Events/Client/ErrorManager.js
Normal 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)
|
||||
})
|
||||
}
|
||||
}
|
||||
10
Src/Events/Client/InteractionCreate.js
Normal file
10
Src/Events/Client/InteractionCreate.js
Normal 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")
|
||||
}
|
||||
}
|
||||
17
Src/Events/Client/MessageCreate.js
Normal file
17
Src/Events/Client/MessageCreate.js
Normal 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)
|
||||
})
|
||||
}
|
||||
}
|
||||
62
Src/Events/Client/ReadyClient.js
Normal file
62
Src/Events/Client/ReadyClient.js
Normal 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))
|
||||
}
|
||||
}
|
||||
20
Src/Events/Reactions/reactionAdd.js
Normal file
20
Src/Events/Reactions/reactionAdd.js
Normal 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`)
|
||||
}
|
||||
}
|
||||
}
|
||||
19
Src/Events/Reactions/reactionRemove.js
Normal file
19
Src/Events/Reactions/reactionRemove.js
Normal 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`)
|
||||
}
|
||||
}
|
||||
}
|
||||
21
Src/Functions/mongodb-reaction-role/LICENSE
Normal file
21
Src/Functions/mongodb-reaction-role/LICENSE
Normal 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.
|
||||
199
Src/Functions/mongodb-reaction-role/README.md
Normal file
199
Src/Functions/mongodb-reaction-role/README.md
Normal 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>.
|
||||
169
Src/Functions/mongodb-reaction-role/index.js
Normal file
169
Src/Functions/mongodb-reaction-role/index.js
Normal 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;
|
||||
12
Src/Functions/mongodb-reaction-role/models/schema.js
Normal file
12
Src/Functions/mongodb-reaction-role/models/schema.js
Normal 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);
|
||||
35
Src/Functions/mongodb-reaction-role/package.json
Normal file
35
Src/Functions/mongodb-reaction-role/package.json
Normal 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"
|
||||
}
|
||||
21
Src/Structures/CommandOptions/AnyClientPermissions.js
Normal file
21
Src/Structures/CommandOptions/AnyClientPermissions.js
Normal 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
|
||||
}
|
||||
}
|
||||
21
Src/Structures/CommandOptions/AnyUserPermissions.js
Normal file
21
Src/Structures/CommandOptions/AnyUserPermissions.js
Normal 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
|
||||
}
|
||||
}
|
||||
25
Src/Structures/CommandOptions/ClientPermissions.js
Normal file
25
Src/Structures/CommandOptions/ClientPermissions.js
Normal 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
|
||||
}
|
||||
}
|
||||
30
Src/Structures/CommandOptions/Cooldown.js
Normal file
30
Src/Structures/CommandOptions/Cooldown.js
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Src/Structures/CommandOptions/OnlyChannels.js
Normal file
25
Src/Structures/CommandOptions/OnlyChannels.js
Normal 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;
|
||||
}
|
||||
}
|
||||
25
Src/Structures/CommandOptions/OnlyGuilds.js
Normal file
25
Src/Structures/CommandOptions/OnlyGuilds.js
Normal 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
|
||||
}
|
||||
}
|
||||
25
Src/Structures/CommandOptions/OnlyUsers.js
Normal file
25
Src/Structures/CommandOptions/OnlyUsers.js
Normal 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;
|
||||
}
|
||||
}
|
||||
22
Src/Structures/CommandOptions/OwnerOnly.js
Normal file
22
Src/Structures/CommandOptions/OwnerOnly.js
Normal 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
|
||||
}
|
||||
}
|
||||
23
Src/Structures/CommandOptions/RequiredAnyRole.js
Normal file
23
Src/Structures/CommandOptions/RequiredAnyRole.js
Normal 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;
|
||||
}
|
||||
}
|
||||
25
Src/Structures/CommandOptions/RequiredRoles.js
Normal file
25
Src/Structures/CommandOptions/RequiredRoles.js
Normal 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
|
||||
}
|
||||
}
|
||||
25
Src/Structures/CommandOptions/UserPermissions.js
Normal file
25
Src/Structures/CommandOptions/UserPermissions.js
Normal 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;
|
||||
}
|
||||
}
|
||||
35
Src/Structures/CommandOptions/loadCommandOptions.js
Normal file
35
Src/Structures/CommandOptions/loadCommandOptions.js
Normal 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)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Src/Structures/Handlers/ButtonCommands.js
Normal file
12
Src/Structures/Handlers/ButtonCommands.js
Normal 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)
|
||||
})
|
||||
})
|
||||
}
|
||||
55
Src/Structures/Handlers/ContextMenus.js
Normal file
55
Src/Structures/Handlers/ContextMenus.js
Normal 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);
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
23
Src/Structures/Handlers/Events.js
Normal file
23
Src/Structures/Handlers/Events.js
Normal 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));
|
||||
})
|
||||
})
|
||||
}
|
||||
8
Src/Structures/Handlers/Handler.js
Normal file
8
Src/Structures/Handlers/Handler.js
Normal 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")
|
||||
}
|
||||
13
Src/Structures/Handlers/MessageCommands.js
Normal file
13
Src/Structures/Handlers/MessageCommands.js
Normal 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()))
|
||||
})
|
||||
})
|
||||
}
|
||||
12
Src/Structures/Handlers/SelectMenus.js
Normal file
12
Src/Structures/Handlers/SelectMenus.js
Normal 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)
|
||||
})
|
||||
})
|
||||
}
|
||||
59
Src/Structures/Handlers/SlashCommands.js
Normal file
59
Src/Structures/Handlers/SlashCommands.js
Normal 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
4
Src/Utils/Filer.js
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
const glob = require('glob')
|
||||
module.exports = (src, callback) => {
|
||||
glob(src + '/**/*', callback);
|
||||
}
|
||||
39
bot.js
Normal file
39
bot.js
Normal 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
0
json.sqlite
Normal file
1976
package-lock.json
generated
Normal file
1976
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
21
package.json
Normal file
21
package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
Reference in a new issue