├── .gitignore ├── src ├── config.json ├── events │ ├── process │ │ └── unhandledRejection.js │ ├── ws │ │ └── INTERACTION_CREATE.js │ └── client │ │ ├── ready.js │ │ ├── messageReactionAdd.js │ │ ├── message.js │ │ └── guildMemberAdd.js ├── Debrosee-ALPnL.ttf ├── commands │ ├── misc │ │ ├── config.json │ │ ├── math.js │ │ ├── docs.js │ │ ├── ascii.js │ │ ├── stats.js │ │ └── sandbox.js │ ├── music │ │ ├── config.json │ │ ├── loop.js │ │ ├── volume.js │ │ ├── pause.js │ │ ├── resume.js │ │ ├── queue.js │ │ ├── nowplaying.js │ │ ├── stop.js │ │ ├── skip.js │ │ ├── play.js │ │ └── stage.js │ ├── fun │ │ ├── config.json │ │ ├── whale.js │ │ ├── dice.js │ │ ├── kill.js │ │ ├── trigger.js │ │ ├── coinflip.js │ │ ├── gay.js │ │ ├── catfact.js │ │ ├── ticktactoe.js │ │ ├── cat.js │ │ ├── meme.js │ │ ├── moment.js │ │ ├── monke.js │ │ ├── turtle.js │ │ ├── amogus.js │ │ ├── toilet.js │ │ ├── 8ball.js │ │ ├── ppsize.js │ │ ├── dababy.js │ │ └── fart.js │ ├── utils │ │ ├── config.json │ │ ├── translate.js │ │ ├── ping.js │ │ ├── avatar.js │ │ ├── invite.js │ │ ├── eval.js │ │ ├── binary.js │ │ ├── register.js │ │ ├── userinfo.js │ │ ├── help.js │ │ ├── serverinfo.js │ │ └── languagelist.js │ ├── mod │ │ ├── config.json │ │ ├── delete.js │ │ ├── unban.js │ │ ├── unlock.js │ │ ├── kick.js │ │ ├── lock.js │ │ ├── slowmode.js │ │ ├── purge.js │ │ ├── ban.js │ │ └── lockdown.js │ └── config │ │ ├── config.json │ │ ├── lockdown-setup.js │ │ ├── welcome.js │ │ └── ticket.js ├── BieksaFreeTrial-RpdWE.otf ├── TigeriousItalic-9YyJn.otf ├── utils │ ├── loadSlashCommands.js │ ├── loadWsEvents.js │ ├── loadClientEvents.js │ ├── loadProcessEvents.js │ ├── loadCommands.js │ └── commandHandler.js ├── index.js ├── DisCruft.js ├── database │ └── models │ │ └── Guilds.js └── slashcommands │ ├── say.js │ └── help.js ├── Debrosee-ALPnL.ttf ├── database └── Guilds.js ├── LICENSE ├── package.json ├── .eslintrc.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .env 3 | package-lock.json -------------------------------------------------------------------------------- /src/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "mainColor": "0xFFA500" 3 | } -------------------------------------------------------------------------------- /Debrosee-ALPnL.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DashCruft-Nation/DisCruft-Bot/HEAD/Debrosee-ALPnL.ttf -------------------------------------------------------------------------------- /src/events/process/unhandledRejection.js: -------------------------------------------------------------------------------- 1 | module.exports = async (err) => { 2 | console.log(err); 3 | }; -------------------------------------------------------------------------------- /src/Debrosee-ALPnL.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DashCruft-Nation/DisCruft-Bot/HEAD/src/Debrosee-ALPnL.ttf -------------------------------------------------------------------------------- /src/commands/misc/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "🔳 - Miscellaneous", 3 | "description": "Some other commands!" 4 | } -------------------------------------------------------------------------------- /src/BieksaFreeTrial-RpdWE.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DashCruft-Nation/DisCruft-Bot/HEAD/src/BieksaFreeTrial-RpdWE.otf -------------------------------------------------------------------------------- /src/TigeriousItalic-9YyJn.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DashCruft-Nation/DisCruft-Bot/HEAD/src/TigeriousItalic-9YyJn.otf -------------------------------------------------------------------------------- /src/commands/music/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "🎧 - Music", 3 | "description": "Music commands for the bot!" 4 | } -------------------------------------------------------------------------------- /src/commands/fun/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": ":joy: - Fun", 3 | "description": "Fun commands to have fun with your friends!" 4 | } -------------------------------------------------------------------------------- /src/commands/utils/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": ":hammer: - Utils", 3 | "description": "Some utility commands for the bot!" 4 | } -------------------------------------------------------------------------------- /src/commands/mod/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": ":shield: - Moderation", 3 | "description": "The commands for moderation in your server!" 4 | } -------------------------------------------------------------------------------- /src/commands/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": ":gear: - Config", 3 | "description": "Commands to configure the features of this bot!" 4 | } -------------------------------------------------------------------------------- /src/utils/loadSlashCommands.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | module.exports = async (client) => { 4 | fs.readdir('./src/slashcommands', (err, files) => { 5 | if(err) throw err; 6 | 7 | files.forEach((file) => { 8 | const slashcmd = require(`../slashcommands/${file}`); 9 | client.slashcommands.set(slashcmd.config.name, slashcmd); 10 | }); 11 | }); 12 | }; -------------------------------------------------------------------------------- /src/commands/fun/whale.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | 4 | module.exports.run = async (client, message, args) => { 5 | message.react('🐋'); 6 | message.react('💦'); 7 | message.channel.send(':whale: :sweat_drops:'); 8 | }; 9 | 10 | module.exports.config = { 11 | name: 'whale', 12 | aliases: ['whalecum'], 13 | description: ':whale:', 14 | }; 15 | -------------------------------------------------------------------------------- /database/Guilds.js: -------------------------------------------------------------------------------- 1 | const { Schema, model } = require('mongoose'); 2 | 3 | const Guilds = new Schema({ 4 | id: { type: String, required: true }, 5 | prefix: { type: String, default: '?' }, 6 | locked: { type: Boolean, default: false }, 7 | lockedChannels: { type: Array }, 8 | welcome: { type: Boolean, default: false }, 9 | welcomeChannel: { type: String, default: null }, 10 | welcomemsg: { type: String, default: null }, 11 | }); 12 | 13 | module.exports = model('Guilds', Guilds); -------------------------------------------------------------------------------- /src/utils/loadWsEvents.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | module.exports = client => { 4 | fs.readdir(path.join(__dirname, '../', 'events/ws'), (_err, files) => { 5 | files.forEach((file) => { 6 | if (!file.endsWith('.js')) return; 7 | const event = require(`../events/ws/${file}`); 8 | const eventName = file.split('.')[0]; 9 | client.ws.on(eventName, event.bind(null, client)); 10 | delete require.cache[require.resolve(`../events/ws/${file}`)]; 11 | }); 12 | }); 13 | }; -------------------------------------------------------------------------------- /src/events/ws/INTERACTION_CREATE.js: -------------------------------------------------------------------------------- 1 | module.exports = (client, interaction) => { 2 | const cmd = interaction.data.name.toLowerCase(); 3 | const args = interaction.data.options; 4 | 5 | const cmdfile = client.slashcommands.get(cmd); 6 | if(!cmdfile) { 7 | return client.api.interactions(interaction.id, interaction.token).callback.post({ 8 | data: { 9 | type: 4, 10 | data: { 11 | content: 'Unable to find that command!', 12 | }, 13 | }, 14 | }); 15 | } 16 | cmdfile.run(client, interaction, args); 17 | }; -------------------------------------------------------------------------------- /src/utils/loadClientEvents.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | module.exports = client => { 4 | fs.readdir(path.join(__dirname, '../', 'events/client'), (_err, files) => { 5 | files.forEach((file) => { 6 | if (!file.endsWith('.js')) return; 7 | const event = require(`../events/client/${file}`); 8 | const eventName = file.split('.')[0]; 9 | client.on(eventName, event.bind(null, client)); 10 | delete require.cache[require.resolve(`../events/client/${file}`)]; 11 | }); 12 | }); 13 | }; -------------------------------------------------------------------------------- /src/utils/loadProcessEvents.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | module.exports = client => { 4 | fs.readdir(path.join(__dirname, '../', 'events/process'), (_err, files) => { 5 | files.forEach((file) => { 6 | if (!file.endsWith('.js')) return; 7 | const event = require(`../events/process/${file}`); 8 | const eventName = file.split('.')[0]; 9 | process.on(eventName, event.bind(null, client)); 10 | delete require.cache[require.resolve(`../events/process/${file}`)]; 11 | }); 12 | }); 13 | }; -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | const { 2 | Intents, 3 | } = require('discord.js'); 4 | const DisCruft = require('./DisCruft'); 5 | 6 | require('dotenv').config(); 7 | const client = new DisCruft({ 8 | partials: ['MESSAGE', 'CHANNEL', 'REACTION'], 9 | ws: { 10 | intents: Intents.ALL, 11 | }, 12 | disableMentions: 'everyone', 13 | }); 14 | client.queue = new Map(); 15 | const mongoose = require('mongoose'); 16 | mongoose.connect(process.env.MongoDB, { useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false }); 17 | 18 | client.setup(); -------------------------------------------------------------------------------- /src/commands/fun/dice.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | 4 | module.exports.run = async (client, message, args) => { 5 | const dice = Math.floor(Math.random() * 6) + 1 6 | - 1 + 1; 7 | 8 | const diceembed = new Discord.MessageEmbed() 9 | .setAuthor(message.member.user.tag) 10 | .setColor('RANDOM') 11 | .setTimestamp() 12 | .setDescription(`You got a **${dice}**`); 13 | message.reply({ embed: diceembed }); 14 | }; 15 | 16 | module.exports.config = { 17 | name: 'dice', 18 | aliases: ['diceroll'], 19 | description: 'Rolls dice', 20 | }; 21 | -------------------------------------------------------------------------------- /src/commands/fun/kill.js: -------------------------------------------------------------------------------- 1 | const canvacord = require('canvacord'); 2 | const { MessageAttachment } = require('discord.js'); 3 | 4 | module.exports.run = async (client, message, args) => { 5 | const user = message.mentions.users.first() || client.users.cache.get(args[0]) || message.author; 6 | const triggered = await canvacord.Canvas.wasted(user.displayAvatarURL({ format: 'png', dynamic: false })); 7 | const attachment = new MessageAttachment(triggered, 'wasted.gif'); 8 | return message.channel.send(attachment); 9 | }; 10 | 11 | module.exports.config = { 12 | name: 'kill', 13 | aliases: ['wasted'], 14 | description: 'try it out and see', 15 | }; -------------------------------------------------------------------------------- /src/commands/fun/trigger.js: -------------------------------------------------------------------------------- 1 | const canvacord = require('canvacord'); 2 | const { MessageAttachment } = require('discord.js'); 3 | 4 | module.exports.run = async (client, message, args) => { 5 | const user = message.mentions.users.first() || client.users.cache.get(args[0]) || message.author; 6 | const triggered = await canvacord.Canvas.trigger(user.displayAvatarURL({ format: 'png', dynamic: false })); 7 | const attachment = new MessageAttachment(triggered, 'triggered.gif'); 8 | return message.channel.send(attachment); 9 | }; 10 | 11 | module.exports.config = { 12 | name: 'trigger', 13 | aliases: [], 14 | description: 'it can trigger anyone', 15 | }; -------------------------------------------------------------------------------- /src/DisCruft.js: -------------------------------------------------------------------------------- 1 | const { 2 | Client, 3 | Collection, 4 | } = require('discord.js'); 5 | module.exports = class DisCruft extends Client { 6 | constructor(options) { 7 | super(options); 8 | this.commands = new Collection(); 9 | this.aliases = new Collection(); 10 | this.slashcommands = new Collection(); 11 | this.snipes = new Map(); 12 | this.config = require('./config.json'); 13 | } 14 | 15 | setup() { 16 | require('./utils/loadCommands')(this); 17 | require('./utils/loadClientEvents')(this); 18 | require('./utils/loadWsEvents')(this); 19 | require('./utils/loadSlashCommands')(this); 20 | 21 | this.login(process.env.TOKEN); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /src/commands/fun/coinflip.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js'); 2 | 3 | 4 | module.exports.run = async (client, message) => { 5 | 6 | const n = Math.floor(Math.random() * 2); 7 | let result; 8 | if (n === 1) result = 'heads'; 9 | else result = 'tails'; 10 | const embed = new Discord.MessageEmbed() 11 | .setTitle('½ Coinflip ½') 12 | .setDescription(`I flipped a coin for you, ${message.member}. It was **${result}**!`) 13 | .setColor('RANDOM'); 14 | message.reply({ embed: embed, allowedMentions: { repliedUser: false } }); 15 | }; 16 | 17 | module.exports.config = { 18 | name: 'coinflip', 19 | aliases: ['coin', 'cf', 'flip'], 20 | description: 'Flip a coin and make decisions!', 21 | }; 22 | -------------------------------------------------------------------------------- /src/database/models/Guilds.js: -------------------------------------------------------------------------------- 1 | const { Schema, model } = require('mongoose'); 2 | 3 | const Guilds = new Schema({ 4 | id: { type: String, required: true }, 5 | prefix: { type: String, default: '?' }, 6 | locked: { 7 | enabled: { type: Boolean, default: false }, 8 | lockChannels: { type: Array, default: [] }, 9 | }, 10 | welcome: { 11 | enabled: { type: Boolean, default: false }, 12 | channelID: { type: String, default: null }, 13 | message: { type: String, default: null }, 14 | }, 15 | tickets: { 16 | enabled: { type: Boolean, default: null }, 17 | channelID: { type: String, default: null }, 18 | messageID: { type: String, default: null }, 19 | }, 20 | }); 21 | 22 | module.exports = model('Guilds', Guilds); -------------------------------------------------------------------------------- /src/commands/fun/gay.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | const fetch = require('node-fetch').default; 4 | module.exports.run = async (client, message, args) => { 5 | const member = message.mentions.members.first() || message.member; 6 | const buffer = await (await fetch('https://api.monkedev.com/canvas/gay?imgUrl=' + encodeURIComponent(member.user.displayAvatarURL({ size: 1024, format: 'jpg' })))).buffer(); 7 | const attachment = new Discord.MessageAttachment(buffer, 'gay.jpg'); 8 | message.reply({ files: [attachment], allowedMentions: { repliedUser: false } }); 9 | }; 10 | module.exports.config = { 11 | name: 'gay', 12 | aliases: ['gae'], 13 | description: '~~Makes someone gay sadly~~', 14 | }; -------------------------------------------------------------------------------- /src/commands/utils/translate.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js'); 2 | const translate = require("@vitalets/google-translate-api"); 3 | module.exports.run = async (client, message, args) => { 4 | translate(`${args.slice(0).join( )}`, {from: `${args[1]}`, to: `${args[2]}`}).then(res => { 5 | const embed = new Discord.MessageEmbed() 6 | .setTitle('DisCruft') 7 | .setDescription(`Here is the translate result :- \n${res.text}`) 8 | .setColor('#2f3136') 9 | .setFooter("command by PIE IS LIVE") 10 | .setTimestamp(); 11 | message.reply(embed); 12 | }) 13 | } 14 | module.exports.config = { 15 | name: 'translate', 16 | aliases: [], 17 | description: 'It will translate anything from any language to any language \n usage : ?translate (text) (from language) (to language)', 18 | }; -------------------------------------------------------------------------------- /src/commands/utils/ping.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const { 3 | Client, 4 | Message, 5 | } = require('discord.js'); 6 | /** 7 | * JSDOC 8 | * @param {Client} client 9 | * @param {Message} message 10 | * @param {String[]} args 11 | */ 12 | module.exports.run = async (client, message, args) => { 13 | const latency = new Date().getTime() - message.createdTimestamp; 14 | const apilatency = Math.round(client.ws.ping); 15 | 16 | return message.reply({ 17 | embed: { 18 | title: 'Pong 🏓', 19 | description: `latency: \`${latency}ms\`\nAPI latency: \`${apilatency}ms\``, 20 | }, 21 | allowedMentions: { 22 | repliedUser: false, 23 | }, 24 | }); 25 | 26 | }; 27 | module.exports.config = { 28 | name: 'ping', 29 | aliases: ['latency', 'ping'], 30 | description: 'Shows the ping of the bot!', 31 | }; 32 | -------------------------------------------------------------------------------- /src/commands/fun/catfact.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | const { Client, Message } = require('discord.js'); 4 | const fetch = require('node-fetch').default; 5 | /** 6 | * JSDOC 7 | * @param {Client} client 8 | * @param {Message} message 9 | * @param {String[]} args 10 | */ 11 | module.exports.run = async (client, message, args) => { 12 | // Monkedev api for the cat facts because cats are the best animal 13 | fetch('https://api.monkedev.com/facts/cat?key=kPESu2IOtzHFt3AsBOnRfTRZu') 14 | .then(response => response.json()) 15 | .then(data => { 16 | message.reply(data.fact, { allowedMentions: { repliedUser: false } }); 17 | }); 18 | }; 19 | 20 | module.exports.config = { 21 | name: 'catfact', 22 | aliases: [], 23 | description: 'Cat facts for you to know about!', 24 | }; 25 | -------------------------------------------------------------------------------- /src/commands/utils/avatar.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | module.exports.run = async (client, message, args) => { 4 | const target = message.mentions.members.first() || message.guild.members.cache.get(args[0]) || message.guild.members.cache.find(x => x.user.username.toLowerCase() === args.slice(0).join(' ') || x.user.username === args[0]) || message.member; 5 | 6 | const embed = new Discord.MessageEmbed() 7 | .setTitle(`${target.user.username}'s avatar!`) 8 | .setColor('RANDOM') 9 | .setImage(target.user.displayAvatarURL({ size: 1024, dynamic: true })); 10 | message.reply({ embed: embed, allowedMentions: { repliedUser: false } }); 11 | }; 12 | module.exports.config = { 13 | name: 'avatar', 14 | aliases: ['av'], 15 | description: 'Sends the avatar of the user mentioned!', 16 | }; 17 | -------------------------------------------------------------------------------- /src/commands/fun/ticktactoe.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | /* eslint-disable no-var */ 3 | const Discord = require('discord.js'); 4 | const reconlx = require('reconlx'); 5 | /** 6 | * JSDOC 7 | * @param {Discord.Client} client 8 | * @param {Discord.Message} message 9 | * @param {String[]} args 10 | */ 11 | 12 | module.exports.run = async (client, message, args) => { 13 | const user = message.mentions.members.first() || message.guild.members.cache.get(args[0]); 14 | if(!user) return message.reply('Please provide a user!', { allowedMentions: { repliedUser: false } }); 15 | const game = new reconlx.tictactoe({ 16 | message: message, 17 | player_two: message.mentions.members.first(), 18 | }); 19 | }; 20 | module.exports.config = { 21 | name: 'ticktactoe', 22 | aliases: [], 23 | description: 'Play a game of tictctoe with your friends!', 24 | }; -------------------------------------------------------------------------------- /src/commands/fun/cat.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const { Client, Message, MessageAttachment } = require('discord.js'); 3 | const fetch = require('node-fetch').default; 4 | /** 5 | * JSDOC 6 | * @param {Client} client 7 | * @param {Message} message 8 | * @param {String[]} args 9 | */ 10 | module.exports.run = async (client, message, args) => { 11 | const msg = await message.reply('', { allowedMentions: { repliedUser: false } }); 12 | fetch('https://source.unsplash.com/collection/139386/200x200/?sig=') 13 | .then(res => res.buffer()) 14 | .then(data => { 15 | msg.delete(); 16 | const img = new MessageAttachment(data, 'cat.png'); 17 | message.reply({ files: [img], allowedMentions: { repliedUser: false } }); 18 | }) 19 | .catch(e => console.error(e)); 20 | }; 21 | 22 | module.exports.config = { 23 | name: 'cat', 24 | aliases: [], 25 | description: 'Cat images', 26 | }; 27 | -------------------------------------------------------------------------------- /src/commands/fun/meme.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | const fetch = require('node-fetch').default; 4 | const { Client, Message } = require('discord.js'); 5 | /** 6 | * JSDOC 7 | * @param {Client} client 8 | * @param {Message} message 9 | * @param {String[]} args 10 | */ 11 | module.exports.run = async (client, message, args) => { 12 | const res = await fetch('https://api.nuggetdev.com/api/meme'); 13 | const json = await res.json(); 14 | const embed = new Discord.MessageEmbed() 15 | .setTitle(`${json.title}`) 16 | .setURL(`${json.url}`) 17 | .setImage(json.image) 18 | .setColor('RANDOM') 19 | .setFooter(`👍 ${json.upvotes} | 💬 ${json.comments}`); 20 | message.reply({ 21 | embed: embed, 22 | allowedMentions: { repliedUser: false }, 23 | }); 24 | }; 25 | 26 | module.exports.config = { 27 | name: 'meme', 28 | aliases: ['m'], 29 | description: 'Sends an ebik meme', 30 | }; 31 | -------------------------------------------------------------------------------- /src/utils/loadCommands.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable max-nested-callbacks */ 2 | const fs = require('fs'); 3 | 4 | function loadCommands(client) { 5 | fs.readdir('src/commands/', (err, cmdfolders) => { 6 | 7 | if (err) console.log(err); 8 | 9 | if(!cmdfolders[0]) return console.log('Client couldn\'t find any commands in the commands folder!'); 10 | cmdfolders.forEach((cmdfolder) => { 11 | fs.readdir(`src/commands/${cmdfolder}`, (err, cmds) => { 12 | if (!cmds) return console.error(`Client couldn't find any commands in the ${cmdfolder} folder!`); 13 | cmds = cmds.filter(z => z.split('.')[1] === 'js'); 14 | cmds.forEach((cmd) => { 15 | const pull = require(`../commands/${cmdfolder}/${cmd}`); 16 | client.commands.set(pull.config.name, pull); 17 | pull.config.aliases.forEach((alias) => { 18 | client.aliases.set(alias, pull.config.name); 19 | }); 20 | }); 21 | }); 22 | }); 23 | }); 24 | } 25 | 26 | module.exports = loadCommands; -------------------------------------------------------------------------------- /src/slashcommands/say.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js'); 2 | 3 | module.exports.run = async (client, interaction, args) => { 4 | const embed = new Discord.MessageEmbed() 5 | .setDescription(args[0].value) 6 | .setAuthor(`${interaction.member.user.username}`, new Discord.User(client, interaction.member.user).displayAvatarURL()) 7 | .setTimestamp() 8 | .setColor('RANDOM'); 9 | client.api.interactions(interaction.id, interaction.token).callback.post({ 10 | data: { 11 | type: 4, 12 | data: { 13 | embeds: [embed], 14 | }, 15 | }, 16 | }); 17 | }; 18 | module.exports.config = { 19 | name: 'say', 20 | description: 'Says your message content!', 21 | aliases: [], 22 | registerData: { 23 | data: { 24 | name: 'say', 25 | description: 'Says your message content!', 26 | options: [ 27 | { 28 | name: 'content', 29 | description: 'The content of the message!', 30 | required: true, 31 | type: 3, 32 | }, 33 | ], 34 | }, 35 | }, 36 | }; -------------------------------------------------------------------------------- /src/commands/misc/math.js: -------------------------------------------------------------------------------- 1 | const { MessageEmbed } = require('discord.js'); 2 | const math = require('mathjs'); 3 | /** 4 | * JSDOC 5 | * @param {Discord.Client} client 6 | * @param {Discord.Message} message 7 | * @param {String[]} args 8 | */ 9 | 10 | module.exports.run = async (client, message, args) => { 11 | try { 12 | const embed1 = new MessageEmbed() 13 | .setColor('RANDOM') 14 | .addField('Question', args.join(' ')) 15 | .addField('Value', math.evaluate(args.join(' '))) 16 | .setTimestamp(); 17 | return message.channel.send({ embed: embed1 }); 18 | } 19 | catch (err) { 20 | const embed2 = new MessageEmbed() 21 | .setColor('RANDOM') 22 | .setTitle('Error!') 23 | .setDescription('Your question is not valid!') 24 | .setTimestamp(); 25 | return message.channel.send({ embed: embed2 }); 26 | } 27 | }; 28 | 29 | module.exports.config = { 30 | name: 'math', 31 | aliases: ['calculate', 'calc'], 32 | description: 'This command can solve a user\'s mathematical problems', 33 | }; -------------------------------------------------------------------------------- /src/commands/fun/moment.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | const Canvas = require('canvas'); 4 | module.exports.run = async (client, message, args) => { 5 | const member = message.mentions.members.first() || message.member; 6 | const canvas = Canvas.createCanvas(500, 670); 7 | const ctx = canvas.getContext('2d'); 8 | const background = await Canvas.loadImage('https://cdn.discordapp.com/attachments/812590454821355543/815638766252195860/moment.jpg'); 9 | ctx.drawImage(background, 0, 0, canvas.width, canvas.height); 10 | const avatar = await Canvas.loadImage(member.user.displayAvatarURL({ format: 'jpg' })); 11 | ctx.drawImage(avatar, 150, 100, 205, 205); 12 | const attachment = new Discord.MessageAttachment(canvas.toBuffer(), `doggo_${member.user.username}.jpg`); 13 | message.reply({ files: [attachment], allowedMentions: { repliedUser: false } }); 14 | }; 15 | module.exports.config = { 16 | name: 'moment', 17 | aliases: [], 18 | description: 'Description moment', 19 | }; -------------------------------------------------------------------------------- /src/commands/fun/monke.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | const fetch = require('node-fetch').default; 4 | /** 5 | * JSDOC 6 | * @param {Discord.Client} bot 7 | * @param {Discord.Message} message 8 | * @param {String[]} args 9 | */ 10 | module.exports.run = async (bot, message, args) => { 11 | fetch('https://api.monkedev.com/attachments/monkey?key=YiGNicedKYp9c15HbrKrUkMkG') 12 | .then(response => response.json()) 13 | .then(data => { 14 | message.reply({ 15 | embed: new Discord.MessageEmbed().setTitle('Here is your monkey image!').setImage(data.url).setFooter(message.author.tag, message.author.displayAvatarURL()).setColor('RANDOM'), 16 | allowedMentions: { 17 | repliedUser: false, 18 | }, 19 | }); 20 | }) 21 | .catch(() => { 22 | message.reply('Couldn\'t fetch image!', { allowedMentions: { repliedUser: false } }); 23 | }); 24 | }; 25 | 26 | module.exports.config = { 27 | name: 'monke', 28 | aliases: ['monkey'], 29 | description: 'Have a nice monkey picture!', 30 | }; -------------------------------------------------------------------------------- /src/commands/fun/turtle.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | const Canvas = require('canvas'); 4 | module.exports.run = async (client, message, args) => { 5 | const member = message.mentions.members.first() || message.member; 6 | const canvas = Canvas.createCanvas(867, 892); 7 | const ctx = canvas.getContext('2d'); 8 | const background = await Canvas.loadImage('https://cdn.discordapp.com/avatars/235148962103951360/cececd50fdc87b29929e65c768f24ad6.png'); 9 | ctx.drawImage(background, 0, 0, canvas.width, canvas.height); 10 | const avatar = await Canvas.loadImage(member.user.displayAvatarURL({ format: 'jpg' })); 11 | ctx.drawImage(avatar, 60, 320, 225, 225); 12 | const attachment = new Discord.MessageAttachment(canvas.toBuffer(), `turtle_${member.user.username}.jpg`); 13 | message.reply({ files: [attachment], allowedMentions: { repliedUser: false } }); 14 | }; 15 | 16 | module.exports.config = { 17 | name: 'turtle', 18 | aliases: ['carl'], 19 | description: 'Makes you a turtle, as simple as that', 20 | }; 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 DashCruft Nation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/commands/fun/amogus.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Canvas = require('canvas'); 3 | const { Client, Message, MessageAttachment } = require('discord.js'); 4 | /** 5 | * JSDOC 6 | * @param {Client} client 7 | * @param {Message} message 8 | * @param {String[]} args 9 | */ 10 | 11 | module.exports.run = async (client, message, args) => { 12 | 13 | const member = message.mentions.members.first() || message.member; 14 | const canvas = Canvas.createCanvas(867, 892); 15 | const ctx = canvas.getContext('2d'); 16 | const background = await Canvas.loadImage('https://i.imgur.com/OopLtL2.jpeg'); 17 | ctx.drawImage(background, 0, 0, canvas.width, canvas.height); 18 | 19 | const avatar = await Canvas.loadImage(member.user.displayAvatarURL({ format: 'jpg' })); 20 | 21 | ctx.drawImage(avatar, 350, 350, 300, 300); 22 | const attachment = new MessageAttachment(canvas.toBuffer(), `amogus${member.user.username}.jpg`); 23 | message.reply({ files: [attachment], allowedMentions: { repliedUser: false } }); 24 | }; 25 | module.exports.config = { 26 | name: 'amogus', 27 | aliases: ['sus'], 28 | description: 'sus111111!!!!1111111!!!1!1!', 29 | }; -------------------------------------------------------------------------------- /src/commands/utils/invite.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const { MessageEmbed } = require('discord.js'); 3 | 4 | module.exports.run = async (bot, message, args) => { 5 | const embed = new MessageEmbed() 6 | .setTitle('DisCruft') 7 | .setURL('https://discord.com/api/oauth2/authorize?client_id=823751227405893672&permissions=1544420598&scope=bot') 8 | .setColor('#2f3136') 9 | .setDescription(`${bot.user.username} is a community made \`open-source\` discord bot by **DashCruft Nation**! DisCruft is a multi-based bot where we are trying to include everything possible. 10 | 11 | - You can invite DisCruft with this **[LINK](https://discord.com/oauth2/authorize?client_id=823751227405893672&permissions=1544420598&scope=bot)**! 12 | - Check out our \`open-source\` github repository **[HERE](https://github.com/DashCruft-Nation/DisCruft-Bot)**!`) 13 | .setThumbnail(bot.user.displayAvatarURL()); 14 | message.reply({ embed: embed, allowedMentions: { repliedUser: false } }); 15 | }; 16 | 17 | module.exports.config = { 18 | name: 'invite', 19 | aliases: ['info'], 20 | description: 'Invite link and information about our djs bot, DisCruft!', 21 | }; 22 | -------------------------------------------------------------------------------- /src/commands/misc/docs.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable prefer-const */ 2 | /* eslint-disable no-unused-vars */ 3 | const fetch = require('node-fetch').default; 4 | const { Client, Message } = require('discord.js'); 5 | /** 6 | * JSDOC 7 | * @param {Client} client 8 | * @param {Message} message 9 | * @param {String[]} args 10 | */ 11 | module.exports.run = async (client, message, args) => { 12 | let [query, branch] = args; 13 | 14 | if (!query) return message.reply('No results!', { allowedMentions: { repliedUser: false } }); 15 | if (!branch) branch = 'master'; 16 | 17 | fetch(`https://djsdocs.sorta.moe/v2/embed?src=${branch}&q=${encodeURIComponent(query)}`) 18 | .then(res => res.json()) 19 | .then(json => { 20 | if (!json) return message.reply('Not found!', { allowedMentions: { repliedUser: false } }); 21 | 22 | message.reply({ embed: json, allowedMentions: { repliedUser: false } }); 23 | }) 24 | .catch(() => { 25 | message.reply('Couldn\'t fetch docs!', { allowedMentions: { repliedUser: false } }); 26 | }); 27 | }; 28 | 29 | module.exports.config = { 30 | name: 'docs', 31 | aliases: ['djsdocs', 'djs'], 32 | description: 'Searches up discord.js documentation!', 33 | }; -------------------------------------------------------------------------------- /src/commands/fun/toilet.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | const Canvas = require('canvas'); 4 | 5 | module.exports.run = async (client, message, args) => { 6 | const member = message.mentions.members.first() || message.member; 7 | const canvas = Canvas.createCanvas(500, 670); 8 | const ctx = canvas.getContext('2d'); 9 | const background = await Canvas.loadImage('https://cdn.discordapp.com/attachments/779441456464003122/812706484240121876/unknown.png'); 10 | ctx.drawImage(background, 0, 0, canvas.width, canvas.height); 11 | // ctx.beginPath(); 12 | // // ctx.arc(350, 150, 100, 0, Math.PI * 2, true); 13 | // ctx.closePath(); 14 | // ctx.clip(); 15 | const avatar = await Canvas.loadImage(member.user.displayAvatarURL({ format: 'jpg' })); 16 | ctx.drawImage(avatar, 135, 350, 205, 205); 17 | const attachment = new Discord.MessageAttachment(canvas.toBuffer(), `toilet_${member.user.username}.jpg`); 18 | message.reply({ files: [attachment], allowedMentions: { repliedUser: false } }); 19 | }; 20 | 21 | module.exports.config = { 22 | name: 'toilet', 23 | aliases: [], 24 | description: 'Flushes someone in a toilet! No idea how you will wanna go into a toilet', 25 | }; 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "discruft-bot", 3 | "version": "1.0.0", 4 | "description": "The DashCruft Nation community Discord bot!", 5 | "main": "./src/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/DashCruft-Nation/DisCruft-Bot.git" 12 | }, 13 | "author": "DashCruft-Nation-Organization", 14 | "license": "MIT", 15 | "bugs": { 16 | "url": "https://github.com/DashCruft-Nation/DisCruft-Bot/issues" 17 | }, 18 | "homepage": "https://github.com/DashCruft-Nation/DisCruft-Bot#readme", 19 | "dependencies": { 20 | "@vitalets/google-translate-api": "^7.0.0", 21 | "canvacord": "^5.2.1", 22 | "canvas": "^2.7.0", 23 | "discord.js": "^12.5.3", 24 | "dotenv": "^8.6.0", 25 | "eslint": "^7.24.0", 26 | "figlet": "^1.5.0", 27 | "mathjs": "^9.4.4", 28 | "moment": "^2.29.2", 29 | "moment-duration-format": "^2.3.2", 30 | "mongoose": "^5.12.4", 31 | "node-fetch": "^2.6.1", 32 | "os-utils": "^0.0.14", 33 | "pretty-ms": "^7.0.1", 34 | "reconlx": "^1.2.41", 35 | "util": "^0.12.4", 36 | "yt-search": "^2.8.0", 37 | "ytdl-core": "^4.7.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/commands/misc/ascii.js: -------------------------------------------------------------------------------- 1 | const { MessageEmbed } = require('discord.js'); 2 | const figlet = require('figlet'); 3 | const util = require('util'); 4 | /** 5 | * JSDOC 6 | * @param {Discord.Client} client 7 | * @param {Discord.Message} message 8 | * @param {String[]} args 9 | */ 10 | 11 | const figletAsync = util.promisify(figlet); 12 | module.exports.run = async (client, message, args) => { 13 | // eslint-disable-next-line quotes 14 | const text = args.join(" "); 15 | if (!text) { 16 | const embed1 = new MessageEmbed() 17 | .setColor('RANDOM') 18 | .setTitle('Notice!') 19 | .setDescription('You need to add text to execute the command!') 20 | .setTimestamp(); 21 | return message.channel.send({ embed: embed1 }); 22 | } 23 | else if (text.length > 20) { 24 | const embed2 = new MessageEmbed() 25 | .setColor('RANDOM') 26 | .setTitle('Error!') 27 | .setDescription('The inputted text has to be less than 20 characters!') 28 | .setTimestamp(); 29 | return message.channel.send({ embed: embed2 }); 30 | } 31 | 32 | const rendered = await figletAsync(text); 33 | message.channel.send('```' + rendered + '```'); 34 | }; 35 | 36 | module.exports.config = { 37 | name: 'ascii', 38 | aliases: ['unicode', 'figlet'], 39 | description: 'This command turns inputted text to ascii art.', 40 | }; 41 | -------------------------------------------------------------------------------- /src/commands/mod/delete.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const { Client, Message, MessageEmbed } = require('discord.js'); 3 | /** 4 | * JSDOC 5 | * @param {Client} client 6 | * @param {Message} message 7 | * @param {String[]} args 8 | */ 9 | module.exports.run = async (client, message, args) => { 10 | if (!message.guild.me.hasPermission('MANAGE_CHANNELS')) return message.reply('I don\'t have permission to delete channels to gimme right now', { allowedMentions: { repliedUser: false } }); 11 | if (!message.member.hasPermission('MANAGE_CHANNELS')) return message.reply('You do not have permissions to use this command!'); 12 | message.reply('Are you sure you want to delete this channel? Confirm by typing `Yes`!', { allowedMentions: { repliedUser: false } }); 13 | const collector = message.channel.awaitMessages(user => user.author.id === message.author.id, { max: 1 }).then((msgs) => { 14 | if (msgs.first().content.toLowerCase() === 'yes') { 15 | message.channel.delete(); 16 | } 17 | else { 18 | return msgs.first().reply('Cancelled!', { allowedMentions: { repliedUser: false } }); 19 | } 20 | }); 21 | }; 22 | 23 | module.exports.config = { 24 | name: 'delete', 25 | aliases: [], 26 | description: 'Use the command to delete channels go to the channel you want to delete and sinply type ***?delete***', 27 | }; 28 | -------------------------------------------------------------------------------- /src/commands/fun/8ball.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | 4 | module.exports.run = async (client, message, args) => { 5 | const answers = [ 6 | 'It is certain.', 7 | 'It is decidedly so.', 8 | 'Without a doubt.', 9 | 'Yes - definitely.', 10 | 'You may rely on it.', 11 | 'As I see it, yes.', 12 | 'Most likely.', 13 | 'Outlook good.', 14 | 'Yes.', 15 | 'Signs point to yes.', 16 | 'Reply hazy, try again.', 17 | 'Ask again later.', 18 | 'Better not tell you now.', 19 | 'Cannot predict now.', 20 | 'Concentrate and ask again.', 21 | 'Don\'t count on it.', 22 | 'My reply is no.', 23 | 'My sources say no.', 24 | 'Outlook not so good.', 25 | 'Very doubtful.', 26 | ]; 27 | if (!args[0]) {return message.reply('Please provide a question to ask', { allowedMentions: { repliedUser: false } });} 28 | const question = args.join(' '); 29 | const embed = new Discord.MessageEmbed() 30 | .setTitle('🎱 The Magic 8-Ball 🎱') 31 | .addField('Question', question) 32 | .addField('Answer', `${answers[Math.floor(Math.random() * answers.length)]}`) 33 | .setColor('RANDOM'); 34 | message.reply({ embed: embed, allowedMentions: { repliedUser: false } }); 35 | }; 36 | 37 | module.exports.config = { 38 | name: '8ball', 39 | aliases: [], 40 | description: 'The command which will tell the future!', 41 | }; 42 | -------------------------------------------------------------------------------- /src/events/client/ready.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const { Client, Message } = require('discord.js'); 3 | const _os = require('os-utils'); 4 | /** 5 | * JSDOC 6 | * @param {Client} client 7 | */ 8 | module.exports = client => { 9 | console.log(`${client.user.tag} is online!`); 10 | const arrayOfType = [ 11 | 'PLAYING', 12 | 'WATCHING', 13 | ]; 14 | const arrayOfStatus = [ 15 | 'with everyone on discord', 16 | '?help | Made by open-sorce contributors with ❤️', 17 | ]; 18 | 19 | let index = 0; 20 | setInterval(() => { 21 | if(index === arrayOfType.length) index = 0; 22 | if(index === arrayOfStatus.length) index = 0; 23 | const status = arrayOfStatus[index]; 24 | const type = arrayOfType[index]; 25 | 26 | client.user.setActivity(status, { type: type }).catch(console.error); 27 | index++; 28 | }, 10000); 29 | setInterval(() => { 30 | try { 31 | client.cpuusage = ''; 32 | _os.cpuUsage(c => { 33 | if ((c * 100).toString().split('.')[1]) { 34 | client.cpuusage = `${(c * 100).toString().split('.')[0] + '.' + (c * 100).toString().split('.')[1].split('')[0] + (c * 100).toString().split('.')[1].split('')[1]}%`; 35 | } 36 | else { 37 | client.cpuusage = `${(c * 100).toString().split('.')[0]}%`; 38 | } 39 | 40 | }); 41 | } 42 | catch (er) { 43 | console.error(er); 44 | } 45 | }, 1000 * 5); 46 | }; 47 | -------------------------------------------------------------------------------- /src/commands/mod/unban.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | /** 4 | * JSDOC 5 | * @param {Discord.Client} client 6 | * @param {Discord.Message} message 7 | * @param {String[]} args 8 | */ 9 | module.exports.run = async (client, message, args) => { 10 | if (!message.member.hasPermission('BAN_MEMBERS')) return message.channel.send('You are not allowed to unban members!'); 11 | if (!message.guild.me.hasPermission('BAN_MEMBERS')) return message.channel.send('I am not allowed to unban members!'); 12 | if (!args[0]) return message.reply('Please provide a user id to unban!', { allowedMentions: { repliedUser: false } }); 13 | const toUnBan = client.users.cache.get(args[0].match(/[1234567890]{18}/igm)[0]) || await client.users.fetch(args[0], true, true); 14 | if (!toUnBan) return message.reply('You didnt provide a valid user!', { allowedMentions: { repliedUser: false } }); 15 | try { 16 | (await message.guild.fetchBan(toUnBan)); 17 | } 18 | catch (err) { 19 | return message.reply('The user isnt banned!', { allowedMentions: { repliedUser: false } }); 20 | } 21 | message.guild.members.unban(toUnBan); 22 | message.reply(`${toUnBan.username} is now unbanned!`, { allowedMentions: { repliedUser: false } }); 23 | }; 24 | module.exports.config = { 25 | name: 'unban', 26 | desc: 'Unbans a user in your server!', 27 | aliases: [], 28 | }; 29 | -------------------------------------------------------------------------------- /src/commands/utils/eval.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | /** 4 | * JSDOC 5 | * @param {Discord.Client} client 6 | * @param {Discord.Message} message 7 | * @param {String[]} args 8 | * @returns 9 | */ 10 | 11 | module.exports.run = async (client, message, args) => { 12 | const allowedDevs = ['361645744001908736', '515204641450098704', '633730629560958976', '571712139606360069']; 13 | if (!allowedDevs.includes(message.author.id)) { 14 | return message.reply('This is a dev only command.', { allowedMentions: { repliedUser: false } }); 15 | } 16 | args = args.join(' '); 17 | try { 18 | let evaled; 19 | 20 | if (args.includes('await')) { 21 | evaled = await eval(`(async () => { ${args} })();`); 22 | } 23 | else {evaled = eval(args);} 24 | if (typeof evaled !== 'string') { 25 | evaled = require('util').inspect(evaled, { depth: 0 }); 26 | } 27 | message.channel.send(`\`\`\`xl\n${clean(evaled)}\n\`\`\``); 28 | } 29 | catch (err) { 30 | message.channel.send(`\`ERROR\` \`\`\`xl\n${clean(err)}\n\`\`\``); 31 | } 32 | }; 33 | module.exports.config = { 34 | name: 'eval', 35 | aliases: [], 36 | description: 'Eval command for the devs!', 37 | }; 38 | 39 | function clean(text) { 40 | if (typeof (text) === 'string') { 41 | return text.replace(/`/g, '`' + String.fromCharCode(8203)).replace(/@/g, '@' + String.fromCharCode(8203)); 42 | } 43 | else {return text;} 44 | } 45 | -------------------------------------------------------------------------------- /src/commands/mod/unlock.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | /** 4 | * JSDOC 5 | * @param {Discord.Client} client 6 | * @param {Discord.Message} message 7 | * @param {String[]} args 8 | * @returns 9 | */ 10 | 11 | module.exports.run = async (client, message, args) => { 12 | if (!message.member.hasPermission('MANAGE_CHANNELS')) return message.channel.send('You do not have permissions to use this command!'); 13 | if (!message.guild.me.hasPermission('MANAGE_CHANNELS')) return message.channel.send('Unable to lock the channel! Missing permissions'); 14 | if (!message.channel.permissionOverwrites.get(client.user.id)) { 15 | await message.channel.createOverwrite(client.user, { 16 | SEND_MESSAGES: true, 17 | }); 18 | } 19 | if (!message.channel.permissionOverwrites.get(client.user.id).allow.toArray().includes('SEND_MESSAGES')) { 20 | await message.channel.updateOverwrite(client.user, { 21 | SEND_MESSAGES: true, 22 | }); 23 | } 24 | if (!message.channel.permissionOverwrites.get(message.guild.roles.everyone.id).deny.toArray().includes('SEND_MESSAGES')) { 25 | return message.channel.send('The channel is already unlocked!'); 26 | } 27 | await message.channel.updateOverwrite(message.guild.roles.everyone, { 28 | SEND_MESSAGES: null, 29 | }); 30 | await message.channel.send('Unlocked the channel!'); 31 | }; 32 | module.exports.config = { 33 | name: 'unlock', 34 | desc: 'Unlocks a channel', 35 | aliases: [], 36 | }; -------------------------------------------------------------------------------- /src/commands/utils/binary.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js'); 2 | const fetch = require('node-fetch').default; 3 | 4 | /** 5 | * JSDOC 6 | * @param {Discord.Client} bot 7 | * @param {Discord.Message} message 8 | * @param {String[]} args 9 | * @returns 10 | */ 11 | 12 | module.exports.run = async (bot, message, args) => { 13 | if(!args[0]) return message.reply('Please provide a function to do with the binary!'); 14 | if (!args[1]) return message.reply('Please give me some binary!', { allowedMentions: { repliedUser: false } }); 15 | 16 | if (args[0] === 'decode') { 17 | const { 18 | text, 19 | } = await (await fetch(`https://some-random-api.ml/binary?decode=${encodeURI(args[1])}`)).json(); 20 | const embed = new Discord.MessageEmbed() 21 | .setTitle('Here is your decoded binary!') 22 | .setDescription(`**Output:**\n${text}`); 23 | return message.reply({ embed: embed, allowedMentions: { repliedUser: false } }); 24 | } 25 | else if(args[0] === 'encode') { 26 | const { binary } = await ( 27 | await fetch( 28 | `https://some-random-api.ml/binary?text=${encodeURI(args.slice(1).join(' '))}`, 29 | ) 30 | ).json(); 31 | const embed = new Discord.MessageEmbed() 32 | .setTitle('Here is your encoded binary!') 33 | .setDescription(`**Output:**\n${binary}`) 34 | .setColor('RANDOM'); 35 | return message.reply({ embed: embed, allowedMentions: { repliedUser: false } }); 36 | } 37 | }; 38 | module.exports.config = { 39 | name: 'binary', 40 | desc: 'Decodes/Encodes binary numbers!', 41 | aliases: [], 42 | }; -------------------------------------------------------------------------------- /src/commands/music/loop.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | /** 4 | * JSDOC 5 | * @param {Discord.Client} client 6 | * @param {Discord.Message} message 7 | * @param {String[]} args 8 | */ 9 | module.exports.run = async (client, message, args) => { 10 | if (!message.guild.me.voice.channel) { 11 | return message.reply('There isn\'t any music being played right now!', { 12 | allowedMentions: { 13 | repliedUser: false, 14 | }, 15 | }); 16 | } 17 | if (!message.member.voice.channel) { 18 | return message.reply('You must be in a voice channel to use this command.', { 19 | allowedMentions: { 20 | repliedUser: false, 21 | }, 22 | }); 23 | } 24 | if (message.member.voice.channel.id !== message.guild.me.voice.channel.id) { 25 | return message.reply(`You must be in \`${message.guild.me.voice.channel.name}\` to use this command`, { 26 | allowedMentions: { 27 | repliedUser: false, 28 | }, 29 | }); 30 | } 31 | 32 | const queue = client.queue.get(message.guild.id); 33 | 34 | if(!queue.songs) return message.reply('There isnt any queue!', { allowedMentions: { repliedUser: false } }); 35 | if(!queue.songs[0]) return message.reply('There isnt any queue!', { allowedMentions: { repliedUser: false } }); 36 | 37 | queue.loop = true; 38 | message.reply(`${queue.loop ? 'Started' : 'Stopped'} looping the current song!`, { allowedMentions: { repliedUser: false } }); 39 | }; 40 | module.exports.config = { 41 | name: 'loop', 42 | desc: 'Loops the current song!', 43 | aliases: [], 44 | }; -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint:recommended", 3 | "env": { 4 | "node": true, 5 | "es6": true 6 | }, 7 | "parserOptions": { 8 | "ecmaVersion": 2019 9 | }, 10 | "rules": { 11 | "brace-style": ["error", "stroustrup", { "allowSingleLine": true }], 12 | "comma-dangle": ["error", "always-multiline"], 13 | "comma-spacing": "error", 14 | "comma-style": "error", 15 | "curly": ["error", "multi-line", "consistent"], 16 | "dot-location": ["error", "property"], 17 | "handle-callback-err": "off", 18 | "indent": ["error", "tab"], 19 | "max-nested-callbacks": ["error", { "max": 4 }], 20 | "max-statements-per-line": ["error", { "max": 2 }], 21 | "no-console": "off", 22 | "no-empty-function": "error", 23 | "no-floating-decimal": "error", 24 | "no-inline-comments": "error", 25 | "no-lonely-if": "error", 26 | "no-multi-spaces": "error", 27 | "no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }], 28 | "no-shadow": ["error", { "allow": ["err", "resolve", "reject"] }], 29 | "no-trailing-spaces": ["error"], 30 | "no-var": "error", 31 | "object-curly-spacing": ["error", "always"], 32 | "prefer-const": "error", 33 | "quotes": ["error", "single"], 34 | "semi": ["error", "always"], 35 | "space-before-blocks": "error", 36 | "space-before-function-paren": ["error", { 37 | "anonymous": "never", 38 | "named": "never", 39 | "asyncArrow": "always" 40 | }], 41 | "space-in-parens": "error", 42 | "space-infix-ops": "error", 43 | "space-unary-ops": "error", 44 | "spaced-comment": "error", 45 | "yoda": "error" 46 | } 47 | } -------------------------------------------------------------------------------- /src/commands/misc/stats.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | const prettyMs = require('pretty-ms'); 4 | const _os = require('os-utils'); 5 | /** 6 | * JSDOC 7 | * @param {Discord.Client} client 8 | * @param {Discord.Message} message 9 | * @param {String[]} args 10 | */ 11 | module.exports.run = async (client, message, args) => { 12 | const embed = new Discord.MessageEmbed() 13 | .addFields( 14 | { name: 'Client Info 🤖', value: `\`\`\`yaml\nName: ${client.user.tag}\nDisplayName: ${message.guild.me.displayName}\nID: ${client.user.id}\nServers: ${client.guilds.cache.size}\nCachedChannels: ${client.channels.cache.size}\nCachedUsers: ${client.users.cache.size}\nUptime: ${prettyMs(client.uptime)}\`\`\`` }, 15 | { name: 'Vps Info 💻', value: `\`\`\`yaml\nPlatform: ${_os.platform()}\nCpuCores: ${_os.cpuCount()}\nCpuUsage: ${client.cpuusage}\nVpsRamUsage: ${Math.round(_os.totalmem() - _os.freemem())}/${Math.floor(_os.totalmem())} mb\`\`\`` }, 16 | ) 17 | .setColor(require('../../config.json').mainColor) 18 | .setDescription('DisCruft is an open-source discord bot capable of many things such as Moderation, Music, Fun commands and etc!! It\'s being developed by a very actively contributing community! You can check it\'s source-code on it\'s [GitHub](https://github.com/DashCruft-Nation/DisCruft-Bot) 😉') 19 | .setTitle('Bot Stats'); 20 | message.reply({ embed: embed, allowedMentions: { repliedUser: false } }); 21 | }; 22 | module.exports.config = { 23 | name: 'stats', 24 | aliases: [], 25 | description: 'Shows the stats of the client!', 26 | }; 27 | -------------------------------------------------------------------------------- /src/commands/music/volume.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | /** 4 | * JSDOC 5 | * @param {Discord.Client} client 6 | * @param {Discord.Message} message 7 | * @param {String[]} args 8 | * @returns 9 | */ 10 | 11 | module.exports.run = async (client, message, args) => { 12 | if (!message.guild.me.voice.channel) { 13 | return message.reply('There isn\'t any music being played right now!', { 14 | allowedMentions: { 15 | repliedUser: false, 16 | }, 17 | }); 18 | } 19 | if (!message.member.voice.channel) { 20 | return message.reply('You must be in a voice channel to use this command.', { 21 | allowedMentions: { 22 | repliedUser: false, 23 | }, 24 | }); 25 | } 26 | if (message.member.voice.channel.id !== message.guild.me.voice.channel.id) { 27 | return message.reply(`You must be in \`${message.guild.me.voice.channel.name}\` to use this command`, { 28 | allowedMentions: { 29 | repliedUser: false, 30 | }, 31 | }); 32 | } 33 | 34 | const queue = client.queue.get(message.guild.id); 35 | 36 | if(!queue) return message.reply('There isnt any queue!', { allowedMentions: { repliedUser: false } }); 37 | if(!queue.songs[0]) return message.reply('There isnt any queue!', { allowedMentions: { repliedUser: false } }); 38 | 39 | queue.connection.dispatcher.setVolume(args[0]); 40 | message.reply('Paused the music!', { 41 | allowedMentions: { 42 | repliedUser: false, 43 | }, 44 | }); 45 | }; 46 | module.exports.config = { 47 | name: 'volume', 48 | desc: 'Changes the volume of the music!', 49 | aliases: ['vol', 'v'], 50 | }; -------------------------------------------------------------------------------- /src/commands/fun/ppsize.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const { Client, Message, MessageEmbed } = require('discord.js'); 3 | /** 4 | * JSDOC 5 | * @param {Client} client 6 | * @param {Message} message 7 | * @param {String[]} args 8 | */ 9 | module.exports.run = async (client, message, args) => { 10 | 11 | const random = Math.floor(Math.random() * 13) + 1; 12 | const randomEqualSigns = '='.repeat(random); 13 | const pepesize = `8${randomEqualSigns}>`; 14 | 15 | if (!args[0]) { 16 | const embed = new MessageEmbed() 17 | .setTitle('Your PP size!') 18 | .addField(`**${pepesize}**`, 'Pretty smol pp') 19 | .setThumbnail(message.author.displayAvatarURL()) 20 | .setTimestamp() 21 | .setColor('RANDOM'); 22 | message.reply({ embed: embed, allowedMentions: { repliedUser: false } }); 23 | } 24 | else { 25 | const target = message.mentions.members.first() || 26 | message.guild.members.cache.get(args[0]) || 27 | message.guild.members.cache.find(m => m.user.username.toLowerCase() === args[0].toLowerCase()) || 28 | message.guild.members.cache.find(m => m.nickname.toLowerCase() === args[0].toLowerCase()) || 29 | message.guild.member(await client.users.fetch(args[0])); 30 | const embed = new MessageEmbed() 31 | .setTitle(`PP size for ${target.user.tag}`) 32 | .addField(`**${pepesize}**`, 'Pretty smol pp') 33 | .setThumbnail(target.user.displayAvatarURL()) 34 | .setTimestamp() 35 | .setColor('RANDOM'); 36 | message.reply({ embed: embed, allowedMentions: { repliedUser: false } }); 37 | } 38 | }; 39 | module.exports.config = { 40 | name: 'ppsize', 41 | aliases: ['pp'], 42 | description: 'Shows the size of your pp :flushed:', 43 | }; 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DisCruft-Bot 2 | 3 | _The official community bot for the DashCruft Nation._ 4 | 5 | ## Requirements & Information 6 | 7 | - You **HAVE** to be a member in our [Offical Discord Server](https://dashcruft.com/discord)! 8 | - Everyone can commit their changes as they wish. It'll be checked and pushed by the mods! 9 | - Once you joined the server, you'll need to help a bunch of people in the support category. (Do this if you want to be shown in the organization members!) 10 | - You'll gain the `Helper` role once a moderator or a staff member saw you being helpful. 11 | - Everyone with that role has the choice to be apart of the organization! 12 | - If any credentials are leaked / any private information, **then the accused person will be kicked from the organization!** (may also even be banned from the DashCruft Nation Discord server) 13 | 14 | ## Setup 15 | 16 | - Fork the repository 17 | - create a `.env` and put the botToken and mongoDB connection string in there: 18 | ``` 19 | TOKEN=PLACE-TOKEN-HERE 20 | MongoDB=CONNECTION-STRING-HERE 21 | ``` 22 | - Do `npm i` in the console to install all dependencies 23 | - Start creating commands and helping! Make sure you follow all linter rules, we recommend you use Visual Studio Code and install the Eslint addon. 24 | - The code must be clean and readable (IT MUST ALSO BE `FULLY TESTED` AS WELL!) 25 | - Make a pull request with your code once you have finished 26 | - You may also make an issue if something concerns you 27 | - Talk with `DashCruft` or any other member of the org for any questions you may have in our [Discord Server](https://dashcruft.com/discord) 28 | 29 | 😳 So, let's make the first DashCruft-Nation project a success! 30 | -------------------------------------------------------------------------------- /src/commands/mod/kick.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const { 3 | Client, 4 | Message, 5 | MessageEmbed, 6 | } = require('discord.js'); 7 | /** 8 | * JSDOC 9 | * @param {Client} client 10 | * @param {Message} message 11 | * @param {String[]} args 12 | */ 13 | module.exports.run = async (client, message, args) => { 14 | if (!message.guild.me.hasPermission('KICK_MEMBERS')) { 15 | return message.reply('I don\'t have permission to kick members!', { 16 | allowedMentions: { 17 | repliedUser: false, 18 | }, 19 | }); 20 | } 21 | if (!message.member.hasPermission('KICK_MEMBERS')) return message.reply('You do not have permission to kick members!', { allowedMentions: { repliedUser: false } }); 22 | const member = message.mentions.members.first() || message.guild.members.cache.get(args[0]); 23 | const reason = args.slice(1).join(' ') || 'No reason provided!'; 24 | if (!member) return message.reply('Please provide a member to kick!', { allowedMentions: { repliedUser: false } }); 25 | if(member.id === message.author.id) return message.reply('You can\'t kick yourself!', { allowedMentions: { repliedUser: false } }); 26 | if(!member.bannable) return message.reply('Cannot kick that user!', { allowedMentions: { repliedUser: false } }); 27 | member.kick(reason + `\nKicked by: ${message.author.tag} | ${message.author.id}`).then(mem => { 28 | message.reply(`Kicked **${mem.user.tag}** from the server successfully!\nAction done by ${message.author.toString()}`, { allowedMentions: { repliedUser: false } }); 29 | }); 30 | }; 31 | 32 | module.exports.config = { 33 | name: 'kick', 34 | aliases: [], 35 | description: 'Kicks a member! Do it if you think someone is kickable!!', 36 | }; 37 | -------------------------------------------------------------------------------- /src/commands/fun/dababy.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Canvas = require('canvas'); 3 | const Discord = require('discord.js'); 4 | /** 5 | * JSDOC 6 | * @param {Discord.Client} client 7 | * @param {Discord.Message} message 8 | * @param {String[]} args 9 | */ 10 | module.exports.run = async (client, message, args) => { 11 | const loading = client.guilds.cache.find(x => x.name === 'DashCruft Nation').emojis.cache.get('705952835476521073'); 12 | const member = message.mentions.users.first() || message.guild.members.cache.find(x => x.user.username.toLowerCase() === args[0] ? args[0].toLowerCase() : undefined) || message.author; 13 | const loadingmsg = await message.reply(`${loading}`, { allowedMentions: { repliedUser: false } }); 14 | const canvas = Canvas.createCanvas(867, 892); 15 | const ctx = canvas.getContext('2d'); 16 | const background = await Canvas.loadImage('https://cdn.suchavoice.com/wp-content/uploads/sites/388/2017/09/20142830/transparent-image.png'); 17 | ctx.drawImage(background, 0, 0, canvas.width, canvas.height); 18 | 19 | const avatar = await Canvas.loadImage(member.displayAvatarURL({ format: 'jpg', size: 4096 })); 20 | const daboy = await Canvas.loadImage('https://media.discordapp.net/attachments/819812451520479252/827777061392220210/G3fJ8jBVK0dwAAAAAElFTkSuQmCC.png'); 21 | ctx.drawImage(avatar, 260, 270, 370, 370); 22 | ctx.drawImage(daboy, 0, 0, canvas.width, canvas.height); 23 | const attach = new Discord.MessageAttachment(canvas.toBuffer(), `Da${member.username}.jpg`); 24 | await loadingmsg.delete(); 25 | message.reply({ files: [attach], allowedMentions: { repliedUser: false } }); 26 | }; 27 | module.exports.config = { 28 | name: 'dababy', 29 | aliases: [], 30 | description: 'You know what this is...', 31 | }; 32 | -------------------------------------------------------------------------------- /src/commands/music/pause.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | /** 4 | * JSDOC 5 | * @param {Discord.Client} client 6 | * @param {Discord.Message} message 7 | * @param {String[]} args 8 | * @returns 9 | */ 10 | 11 | module.exports.run = async (client, message, args) => { 12 | if (!message.guild.me.voice.channel) { 13 | return message.reply('There isn\'t any music being played right now!', { 14 | allowedMentions: { 15 | repliedUser: false, 16 | }, 17 | }); 18 | } 19 | if (!message.member.voice.channel) { 20 | return message.reply('You must be in a voice channel to use this command.', { 21 | allowedMentions: { 22 | repliedUser: false, 23 | }, 24 | }); 25 | } 26 | if (message.member.voice.channel.id !== message.guild.me.voice.channel.id) { 27 | return message.reply(`You must be in \`${message.guild.me.voice.channel.name}\` to use this command`, { 28 | allowedMentions: { 29 | repliedUser: false, 30 | }, 31 | }); 32 | } 33 | 34 | const queue = client.queue.get(message.guild.id); 35 | 36 | if(!queue) return message.reply('There isnt any queue!', { allowedMentions: { repliedUser: false } }); 37 | if(!queue.songs[0]) return message.reply('There isnt any queue!', { allowedMentions: { repliedUser: false } }); 38 | 39 | if(!queue.playing) { 40 | return message.reply('The music is already paused!', { 41 | allowedMentions: { 42 | repliedUser: false, 43 | }, 44 | }); 45 | } 46 | 47 | queue.connection.dispatcher.pause(); 48 | message.reply('Paused the music!', { 49 | allowedMentions: { 50 | repliedUser: false, 51 | }, 52 | }); 53 | queue.playing = false; 54 | }; 55 | module.exports.config = { 56 | name: 'pause', 57 | desc: 'Pauses the song!', 58 | aliases: [], 59 | }; -------------------------------------------------------------------------------- /src/commands/mod/lock.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | /** 4 | * JSDOC 5 | * @param {Discord.Client} client 6 | * @param {Discord.Message} message 7 | * @param {String[]} args 8 | * @returns 9 | */ 10 | 11 | module.exports.run = async (client, message, args) => { 12 | if (!message.member.hasPermission('MANAGE_CHANNELS')) return message.channel.send('You do not have permissions to use this command!'); 13 | if (!message.guild.me.hasPermission('MANAGE_CHANNELS')) return message.channel.send('Unable to lock the channel! Missing permissions'); 14 | if (!message.channel.permissionOverwrites.get(client.user.id)) { 15 | await message.channel.createOverwrite(client.user, { 16 | SEND_MESSAGES: true, 17 | }); 18 | } 19 | if (!message.channel.permissionOverwrites.get(client.user.id).allow.toArray().includes('SEND_MESSAGES')) { 20 | await message.channel.updateOverwrite(client.user, { 21 | SEND_MESSAGES: true, 22 | }); 23 | } 24 | if(!message.channel.permissionOverwrites.get(message.guild.roles.everyone.id)) { 25 | await message.channel.updateOverwrite(message.guild.roles.everyone, { 26 | SEND_MESSAGES: false, 27 | }); 28 | return message.channel.send('Locked down the channel!'); 29 | } 30 | if (!message.channel.permissionOverwrites.get(message.guild.roles.everyone.id).allow.toArray().includes('SEND_MESSAGES')) { 31 | if(message.channel.permissionOverwrites.get(message.guild.roles.everyone.id).deny.toArray().includes('SEND_MESSAGES')) return message.channel.send('The channel is locked!'); 32 | } 33 | await message.channel.updateOverwrite(message.guild.roles.everyone, { 34 | SEND_MESSAGES: false, 35 | }); 36 | await message.channel.send('Locked down the channel!'); 37 | }; 38 | module.exports.config = { 39 | name: 'lock', 40 | desc: 'Locks a channel!', 41 | aliases: [], 42 | }; -------------------------------------------------------------------------------- /src/commands/music/resume.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | /** 4 | * JSDOC 5 | * @param {Discord.Client} client 6 | * @param {Discord.Message} message 7 | * @param {String[]} args 8 | * @returns 9 | */ 10 | 11 | module.exports.run = async (client, message, args) => { 12 | if (!message.guild.me.voice.channel) { 13 | return message.reply('There isn\'t any music being played right now!', { 14 | allowedMentions: { 15 | repliedUser: false, 16 | }, 17 | }); 18 | } 19 | if (!message.member.voice.channel) { 20 | return message.reply('You must be in a voice channel to use this command.', { 21 | allowedMentions: { 22 | repliedUser: false, 23 | }, 24 | }); 25 | } 26 | if (message.member.voice.channel.id !== message.guild.me.voice.channel.id) { 27 | return message.reply(`You must be in \`${message.guild.me.voice.channel.name}\` to use this command`, { 28 | allowedMentions: { 29 | repliedUser: false, 30 | }, 31 | }); 32 | } 33 | 34 | const queue = client.queue.get(message.guild.id); 35 | 36 | if(!queue.songs) return message.reply('There isnt any queue!', { allowedMentions: { repliedUser: false } }); 37 | if(!queue.songs[0]) return message.reply('There isnt any queue!', { allowedMentions: { repliedUser: false } }); 38 | 39 | if(!message.guild.me.voice.channel.speakable) { 40 | return message.reply('I cannot speak in the channel!', { 41 | allowedMentions: { 42 | repliedUser: false, 43 | }, 44 | }); 45 | } 46 | 47 | if(queue.playing) { 48 | return message.reply('The music is already playing!', { 49 | allowedMentions: { 50 | repliedUser: false, 51 | }, 52 | }); 53 | } 54 | 55 | queue.connection.dispatcher.resume(); 56 | message.reply('Resumed the music!', { 57 | allowedMentions: { 58 | repliedUser: false, 59 | }, 60 | }); 61 | queue.playing = true; 62 | }; 63 | module.exports.config = { 64 | name: 'resume', 65 | desc: 'Resumes the song!', 66 | aliases: [], 67 | }; -------------------------------------------------------------------------------- /src/events/client/messageReactionAdd.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js'); 2 | const schema = require('../../database/models/Guilds'); 3 | 4 | /** 5 | * @param {Discord.Client} client 6 | * @param {Discord.MessageReaction} reaction 7 | * @param {Discord.User} user 8 | */ 9 | module.exports = async (client, reaction, user) => { 10 | if(user.bot) return; 11 | if(reaction.partial) reaction.fetch(); 12 | 13 | const data = await schema.findOne({ 14 | id: reaction.message.guild.id, 15 | }); 16 | if (!data) { 17 | return await new schema({ 18 | id: reaction.message.guild.id, 19 | prefix: '?', 20 | locked: { 21 | enabled: false, 22 | }, 23 | welcome: { 24 | enabled: false, 25 | }, 26 | tickets: { 27 | enabled: false, 28 | }, 29 | }).save(); 30 | } 31 | else if(data) { 32 | if(!data.tickets.enabled) return; 33 | if(!data.tickets.channelID) return; 34 | if(!data.tickets.messageID) return; 35 | if(reaction.emoji.name !== 'tickets' && reaction.message.id === data.tickets.messageID) return; 36 | if(reaction.message.guild.channels.cache.find(channel => channel.name == `ticket-${user.id}`)) return; 37 | reaction.message.guild.channels.create(`ticket-${user.id}`, { 38 | type: 'text', 39 | permissionOverwrites: [ 40 | { 41 | id: user.id, 42 | allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ADD_REACTIONS', 'READ_MESSAGE_HISTORY', 'USE_EXTERNAL_EMOJIS'], 43 | }, 44 | { 45 | id: reaction.message.guild.roles.everyone.id, 46 | deny: ['VIEW_CHANNEL'], 47 | }, 48 | ], 49 | }) 50 | .then((channel) => { 51 | const ticketCreated = new Discord.MessageEmbed() 52 | .setTitle('Ticket 🎟️') 53 | .setDescription(`${user.toString()} has created a ticket! Be sure to provide your reason to create this ticket, details about your issue etc.`) 54 | .setColor('RANDOM') 55 | .setAuthor(user.tag, user.displayAvatarURL()) 56 | .setTimestamp(); 57 | channel.send(user, ticketCreated); 58 | }); 59 | } 60 | }; -------------------------------------------------------------------------------- /src/commands/music/queue.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | /** 4 | * JSDOC 5 | * @param {Discord.Client} client 6 | * @param {Discord.Message} message 7 | * @param {String[]} args 8 | * @returns 9 | */ 10 | module.exports.run = async (client, message, args) => { 11 | if (!message.member.voice.channel) { 12 | return message.reply('You must be in a voice channel to use this command.', { 13 | allowedMentions: { 14 | repliedUser: false, 15 | }, 16 | }); 17 | } 18 | if (message.member.voice.channel.id !== message.guild.me.voice.channel.id) { 19 | return message.reply(`You must be in \`${message.guild.me.voice.channel.name}\` to use this command`, { 20 | allowedMentions: { 21 | repliedUser: false, 22 | }, 23 | }); 24 | } 25 | 26 | const queue = client.queue.get(message.guild.id); 27 | 28 | if(!queue) return message.reply('There isnt any queue!', { allowedMentions: { repliedUser: false } }); 29 | if(!queue.songs[0]) return message.reply('There isnt any queue!', { allowedMentions: { repliedUser: false } }); 30 | 31 | const embed = new Discord.MessageEmbed() 32 | .setTitle(`🎶 **Current Queue** | ${queue.songs.length - 1} entries`) 33 | .setDescription(`Playing songs in ${queue.voicechannel} linked to ${queue.textchannel}!`) 34 | .addFields( 35 | { name: 'Queued songs', value: `${(queue.songs.slice(1, 11).map((song, i) => { 36 | return `${`\`${i + 1}\``} | **${song.title}** - ${song.requestedBy.toString()} \`${song.duration}\``; 37 | }).join('\n'))}` }, 38 | { name: 'Now playing', value: `Title: **${queue.songs[0].title}** \nRequested By: *${queue.songs[0].requestedBy.toString()}*` }, 39 | ) 40 | .setColor(require('../../config.json').mainColor); 41 | message.reply({ 42 | embed: embed, 43 | allowedMentions: { 44 | repliedUser: false, 45 | }, 46 | }); 47 | }; 48 | 49 | module.exports.config = { 50 | name: 'queue', 51 | aliases: ['q', 'list'], 52 | description: 'Shows the music queue of your server if any!', 53 | }; -------------------------------------------------------------------------------- /src/commands/mod/slowmode.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const { Client, Message } = require('discord.js'); 3 | /** 4 | * JSDOC 5 | * @param {Client} client 6 | * @param {Message} message 7 | * @param {String[]} args 8 | */ 9 | module.exports.run = async (client, message, args) => { 10 | if (!message.guild.me.hasPermission('MANAGE_CHANNELS')) return message.reply('I do not have `MANAGE_CHANNELS` permission!', { allowedMentions: { repliedUser: false } }); 11 | if (!message.member.hasPermission('MANAGE_CHANNELS')) return message.reply('You do not have `MANAGE_CHANNELS` permission!', { allowedMentions: { repliedUser: false } }); 12 | const cd = args[0]; 13 | const channel = message.mentions.channels.first() || message.guild.channels.cache.get(args[1]) || message.channel; 14 | if (!channel) return message.reply('Something went wrong!', { allowedMentions: { repliedUser: false } }); 15 | if (!cd) { 16 | return message.reply( 17 | 'Please Give an amount of **Second(s)** to set slowmode!', 18 | { allowedMentions: { repliedUser: false } }, 19 | ); 20 | } 21 | if (isNaN(cd)) { 22 | return message.reply( 23 | 'Please give a valid amount of **Seconds** to set slowmode!', 24 | { allowedMentions: { repliedUser: false } }, 25 | ); 26 | } 27 | if (cd > 21600) { 28 | return message.reply( 29 | 'You can\'t set the Slowmode higher than 21600 seconds.', 30 | { allowedMentions: { repliedUser: false } }, 31 | ); 32 | } 33 | if (cd < 0) { 34 | return message.reply( 35 | 'You can\'t set the Slowmode Lower than 0 seconds', 36 | { allowedMentions: { repliedUser: false } }, 37 | ); 38 | } 39 | else { 40 | channel.setRateLimitPerUser(cd); 41 | message.reply( 42 | `Successfully set the Slowmode to ${cd} Seconds in ${channel.id === message.channel.id ? 'this Channel' : `${channel}`}!`, 43 | { allowedMentions: { repliedUser: false } }, 44 | ); 45 | } 46 | }; 47 | 48 | module.exports.config = { 49 | name: 'slowmode', 50 | aliases: [], 51 | description: 'Adds a slowmode to the channel!', 52 | }; 53 | -------------------------------------------------------------------------------- /src/commands/config/lockdown-setup.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | const schema = require('../../database/models/Guilds'); 4 | /** 5 | * JSDOC 6 | * @param {Discord.Client} client 7 | * @param {Discord.Message} message 8 | * @param {String[]} args 9 | */ 10 | module.exports.run = async (client, message, args) => { 11 | if(!message.member.hasPermission('MANAGE_GUILD')) return message.reply('You do not have the `MANAGE_GUILD` permission!', { allowedMentions: { repliedUser: false } }); 12 | message.channel.send('Specify all the channels you want to lock at the time of lockdown!'); 13 | message.channel.awaitMessages(m => m.author.id === message.author.id, { time: 30000, max: 1 }).then(async msgs => { 14 | const msg = msgs.first(); 15 | if(!msg) return message.reply('You did not respond in time!', { allowedMentions: { repliedUser: false } }); 16 | if(!msg.mentions.channels.first()) return message.reply('Make sure to provide channel!', { allowedMentions: { repliedUser: false } }); 17 | const channelIDs = msg.mentions.channels.filter(x => x.type === 'text').map(e => e.id); 18 | if(!channelIDs[0]) return message.reply('Unable to find any valid channels!'); 19 | const data = await schema.findOne({ 20 | id: message.guild.id, 21 | }); 22 | if(!data) { 23 | await new schema({ 24 | id: message.guild.id, 25 | prefix: '?', 26 | locked: { 27 | enabled: false, 28 | lockChannels: channelIDs, 29 | }, 30 | }).save(); 31 | message.channel.send(`Successfully saved all channels to lock when lockdown command is run! There are ${channelIDs.length} channels.`); 32 | } 33 | else if(data) { 34 | if(!data.locked) data.locked = {}; 35 | data.locked.lockChannels = channelIDs; 36 | await data.save(); 37 | message.channel.send(`Successfully saved all channels to lock when lockdown command is run! There are ${channelIDs.length} channels.`); 38 | } 39 | }); 40 | }; 41 | module.exports.config = { 42 | name: 'lockdown-setup', 43 | description: 'Setup lockdown command for your server!', 44 | aliases: [], 45 | }; -------------------------------------------------------------------------------- /src/commands/utils/register.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | const fs = require('fs'); 4 | /** 5 | * JSDOC 6 | * @param {Discord.Client} client 7 | * @param {Discord.Message} message 8 | * @param {String[]} args 9 | */ 10 | module.exports.run = async (client, message, args) => { 11 | if(!message.member.hasPermission('MANAGE_GUILD')) return message.reply('You do not have permissions to use this command!', { allowedMentions: { repliedUser: false } }); 12 | if (args[0] !== 'force') { 13 | const registerData = client.slashcommands.map((cmd) => cmd.config.registerData); 14 | const guildCmds = (await client.api.applications(client.user.id).guilds(message.guild.id).commands.get()).map(x => x.name); 15 | try { 16 | registerData.filter(x => !guildCmds.includes(x.name)).forEach(data => { 17 | client.api.applications(client.user.id).guilds(message.guild.id).commands.post(data); 18 | }); 19 | } 20 | catch (err) { 21 | console.log(err); 22 | return message.reply('Unable to register all commands! Make sure I am invited with the `applications.commands` scope!'); 23 | } 24 | message.reply('Added slash commands! If there is any issues try using `register force` if that does not work contact the developers!', { allowedMentions: { repliedUser: false } }); 25 | } 26 | else if(args[0] === 'force') { 27 | const registerData = client.slashcommands.map((cmd) => cmd.config.registerData); 28 | try { 29 | registerData.forEach(data => { 30 | client.api.applications(client.user.id).guilds(message.guild.id).commands.post(data); 31 | }); 32 | } 33 | catch (err) { 34 | return message.reply('Unable to register all commands! Make sure I am invited with the `applications.commands` scope!'); 35 | } 36 | message.reply('Added slash commands! If there is still any issues try using `register force` if that does not work contact the developers!', { allowedMentions: { repliedUser: false } }); 37 | } 38 | }; 39 | module.exports.config = { 40 | name: 'register', 41 | desc: 'Registers slash commands in your server!', 42 | aliases: [], 43 | }; -------------------------------------------------------------------------------- /src/commands/misc/sandbox.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | /* eslint-disable no-delete-var */ 3 | const Discord = require('discord.js'); 4 | /** 5 | * @param {Discord.Client} bot 6 | * @param {Discord.Message} message 7 | * @param {String[]} args 8 | */ 9 | module.exports.run = async (bot, message, args) => { 10 | if (!message.member.roles.cache.has('652615952709451825')) return message.reply('This command is only allowed to `Contributors` for now, it may soon be available to everyone after being tested', { allowedMentions: { repliedUser: false } }); 11 | if (!args[0]) return message.reply('Please provide something to evaluate!', { allowedMentions: { repliedUser: false } }); 12 | const evaled = await evaluate(args.join(' ')) || 'No response!'; 13 | message.channel.send(evaled); 14 | }; 15 | module.exports.config = { 16 | name: 'sandbox', 17 | description: 'A eval command to test codes of basic JS for everyone', 18 | aliases: ['sb', 'sand-box'], 19 | }; 20 | 21 | async function evaluate(args) { 22 | if (args.includes('process')) return; 23 | if (args.includes('while')) return; 24 | if (args.includes('fs')) return; 25 | if (args.includes('this')) return; 26 | if (args.includes('console')) return; 27 | if (args.includes('eval')) return; 28 | if (args.split('for')[1]) { 29 | let result = true; 30 | args.split('for').forEach(arg => { 31 | if (arg.startsWith('Each')) result = false; 32 | }); 33 | if (result == true) return; 34 | } 35 | if (args.includes('require')) return; 36 | try { 37 | let evaled; 38 | 39 | if (args.includes('await')) { 40 | evaled = await eval(`(async () => { ${args} })();`); 41 | } 42 | else { evaled = eval(args); } 43 | if (typeof evaled !== 'string') { 44 | evaled = require('util').inspect(evaled, { depth: 0 }); 45 | } 46 | return `\`\`\`xl\n${clean(evaled)}\n\`\`\``; 47 | } 48 | catch (err) { 49 | return `\`ERROR\` \`\`\`xl\n${clean(err)}\n\`\`\``; 50 | } 51 | } 52 | 53 | function clean(text) { 54 | if (typeof (text) === 'string') { 55 | return text.replace(/`/g, '`' + String.fromCharCode(8203)).replace(/@/g, '@' + String.fromCharCode(8203)); 56 | } 57 | else { return text; } 58 | } -------------------------------------------------------------------------------- /src/events/client/message.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | /* eslint-disable no-unused-vars */ 3 | const { Client, Message, MessageEmbed } = require('discord.js'); 4 | const escapeRegex = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); 5 | /** 6 | * JSDOC 7 | * @param {Client} client 8 | * @param {Message} message 9 | */ 10 | module.exports = async (client, message) => { 11 | if (message.author.bot || message.channel.type === 'dm') return; 12 | 13 | const mentionembed = new MessageEmbed() 14 | .setTitle('DisCruft bot info!') 15 | .setDescription(`My prefix for ${message.guild.name} is \`?\`! Use \`?help\` for info about my commands! You can also use mention as my prefix now!`) 16 | .setColor(client.config.mainColor) 17 | .setThumbnail(client.user.displayAvatarURL()) 18 | .setFooter(client.user.tag, client.user.displayAvatarURL()) 19 | .setAuthor(message.author.tag, message.author.displayAvatarURL()); 20 | if (message.content === `<@!${client.user.id}>`) return message.reply({ embed: mentionembed, allowedMentions: { repliedUser: false } }); 21 | 22 | const messageArray = message.content.split(' '); 23 | let cmd = messageArray[0]; 24 | let args = messageArray.slice(1); 25 | 26 | const prefix = '?'; 27 | 28 | const prefixRegex = new RegExp(`^(<@!?${client.user.id}>|${escapeRegex(prefix)})\\s*`); 29 | if (!prefixRegex.test(messageArray)) return; 30 | const [, matchedPrefix] = message.content.match(prefixRegex); 31 | 32 | if (cmd.slice(matchedPrefix.length) != prefix && matchedPrefix.includes(client.user.id)) { 33 | cmd = args[0]; 34 | args = args.slice(1); 35 | commandfile = client.commands.get(cmd.toLowerCase()) || client.commands.get(client.aliases.get(cmd.toLowerCase())); 36 | } 37 | else { 38 | commandfile = client.commands.get(cmd.slice(matchedPrefix.length).toString().toLowerCase()) || client.commands.get(client.aliases.get(cmd.slice(matchedPrefix.length).toString().toLowerCase())); 39 | } 40 | if (commandfile) { 41 | try { 42 | await commandfile.run(client, message, args); 43 | } 44 | catch (err) { 45 | message.reply(`An error occured!\nError: ${require('util').inspect(err, { depth: 0 })}`, { 46 | allowedMentions: { 47 | repliedUser: false, 48 | }, 49 | }); 50 | } 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /src/commands/utils/userinfo.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const moment = require('moment'); 3 | const { Client, Message, MessageEmbed } = require('discord.js'); 4 | const config = require('../../config.json'); 5 | const momentDurationFormatSetup = require('moment-duration-format'); 6 | /** 7 | * JSDOC 8 | * @param {Client} client 9 | * @param {Message} message 10 | * @param {String[]} args 11 | */ 12 | 13 | module.exports.run = async (client, message, args) => { 14 | 15 | const targetMember = message.mentions.members.first() || message.guild.members.cache.get(args[0]) || message.member; 16 | if (!targetMember) return; 17 | 18 | momentDurationFormatSetup(moment); 19 | 20 | const embed = new MessageEmbed() 21 | .setColor(config.mainColor) 22 | .setTitle(targetMember.user.tag) 23 | .setThumbnail(targetMember.user.avatarURL()) 24 | .setAuthor('DisCruft | User Info', client.user.avatarURL()) 25 | 26 | .addFields( 27 | { name: '#️⃣ Role Count', value: `\`\`\`${targetMember.roles.cache.size}\`\`\``, inline: true }, 28 | { name: '🔝 Highest Role', value: `\`\`\`${targetMember.roles.highest.name}\`\`\``, inline: true }, 29 | { name: '🌈 Role Color', value: `\`\`\`${targetMember.displayHexColor}\`\`\``, inline: true }, 30 | { name: '#️⃣ Badge Count', value: `\`\`\`${targetMember.user.flags.toArray().length}\`\`\``, inline: true }, 31 | { name: 'Is Booster?', value: `\`\`\`${targetMember.premiumSince ? 'Yes' : 'No'}\`\`\``, inline: true }, 32 | { name: '——————————————————————————————', value: '_ _' }, 33 | ) 34 | 35 | .addFields( 36 | { name: '🧍 Display Name', value: `\`\`\`${targetMember.displayName}\`\`\``, inline: true }, 37 | { name: '🆔 User ID', value: `\`\`\`${targetMember.user.id}\`\`\``, inline: true }, 38 | { name: '📅 Server Join Date', value: `\`\`\`${moment(targetMember.joinedAt).utc().format('MM/DD/YYYY | h:mm A')}\`\`\``, inline: false }, 39 | { name: '📅 Account Age', value: `\`\`\`${moment.duration(moment().diff(targetMember.user.createdAt.getTime())).format('Y [Year(s)], D [Day(s)], H [Hour(s)], m [Min(s)]')}\`\`\``, inline: false }, 40 | ); 41 | 42 | message.reply({ embed: embed, allowedMentions: { repliedUser: false } }); 43 | 44 | }; 45 | 46 | module.exports.config = { 47 | name: 'userinfo', 48 | aliases: ['uinfo', 'whois'], 49 | description: 'Shows info of a user!', 50 | }; -------------------------------------------------------------------------------- /src/commands/music/nowplaying.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | /** 4 | * JSDOC 5 | * @param {Discord.Client} client 6 | * @param {Discord.Message} message 7 | * @param {String[]} args 8 | * @returns 9 | */ 10 | 11 | module.exports.run = async (client, message, args) => { 12 | if (!message.guild.me.voice.channel) { 13 | return message.reply('There isn\'t any music being played right now!', { 14 | allowedMentions: { 15 | repliedUser: false, 16 | }, 17 | }); 18 | } 19 | if (!message.member.voice.channel) { 20 | return message.reply('You must be in a voice channel to use this command.', { 21 | allowedMentions: { 22 | repliedUser: false, 23 | }, 24 | }); 25 | } 26 | if (message.member.voice.channel.id !== message.guild.me.voice.channel.id) { 27 | return message.reply(`You must be in \`${message.guild.me.voice.channel.name}\` to use this command`, { 28 | allowedMentions: { 29 | repliedUser: false, 30 | }, 31 | }); 32 | } 33 | 34 | const queue = client.queue.get(message.guild.id); 35 | 36 | if(!queue) return message.reply('There isnt any queue!', { allowedMentions: { repliedUser: false } }); 37 | if(!queue.songs[0]) return message.reply('There isnt any queue!', { allowedMentions: { repliedUser: false } }); 38 | 39 | const songplaying = queue.songs[0]; 40 | 41 | const embed = new Discord.MessageEmbed() 42 | .setTitle('Now playing!') 43 | .setDescription(songplaying.title) 44 | .addFields( 45 | { name: 'URL', value: `[${songplaying.title}](${songplaying.url})`, inline: true }, 46 | { name: 'Type', value: songplaying.type, inline: true }, 47 | { name: 'Video duration', value: `${songplaying.duration}`, inline: true }, 48 | { name: 'Song added by', value: `${songplaying.requestedBy.toString()}`, inline: true }, 49 | { name: 'Song By', value: `${songplaying.artist}`, inline: true }, 50 | { name: 'Album', value: `${songplaying.album}`, inline: true }, 51 | ) 52 | .setThumbnail(songplaying.thumbnail) 53 | .setColor(require('../../config.json').mainColor) 54 | .setFooter(message.author.tag, message.author.displayAvatarURL()); 55 | message.reply({ 56 | embed: embed, 57 | allowedMentions: { 58 | repliedUser: false, 59 | }, 60 | }); 61 | }; 62 | module.exports.config = { 63 | name: 'nowplaying', 64 | desc: 'Shows info about the current playing song', 65 | aliases: ['np'], 66 | }; -------------------------------------------------------------------------------- /src/commands/config/welcome.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const schema = require('../../database/models/Guilds'); 3 | /** 4 | * JSDOC 5 | * @param {Discord.Client} client 6 | * @param {Discord.Message} message 7 | * @param {String[]} args 8 | */ 9 | 10 | module.exports.run = async (client, message, args) => { 11 | if(!message.member.hasPermission('MANAGE_GUILD')) return message.reply('You do not have the permissions to use this command!', { allowedMentions: { repliedUser: false } }); 12 | if (!args[0]) return message.reply('Please provide some options!', { allowedMentions: { repliedUser: false } }); 13 | let data = await schema.findOne({ 14 | id: message.guild.id, 15 | }); 16 | if (!data) { 17 | data = await new schema({ 18 | id: message.guild.id, 19 | prefix: '?', 20 | locked: false, 21 | lockedChannels: [], 22 | welcome: true, 23 | }).save(); 24 | } 25 | if (['enable', 'disable'].includes(args[0])) { 26 | data.welcome = args[0] == 'enable' ? true : false; 27 | await schema.findOneAndUpdate({ 28 | id: message.guild.id, 29 | }, data); 30 | return message.reply(`The welcome message is now ${!data.welcome ? 'disabled' : 'enabled'}!`, { allowedMentions: { repliedUser: false } }); 31 | } 32 | else if (!['channel', 'message'].includes(args[0])) {return message.reply('That is not a valid option!', { allowedMentions: { repliedUser: false } });} 33 | if (args[0] === 'channel') { 34 | const channel = message.mentions.channels.first() || message.guild.channels.cache.get(args[1]); 35 | if (!channel) return message.reply('Please provide a valid channel!'); 36 | try{ 37 | await channel.send('Welcome message enabled in this channel!'); 38 | } 39 | catch(err) { 40 | return message.reply('Unable to send messages in the channel!'); 41 | } 42 | data.welcomeChannel = channel.id; 43 | data.welcome = true; 44 | await schema.findOneAndUpdate({ 45 | id: message.guild.id, 46 | }, data); 47 | message.reply(`Welcome message is now going to be sent in ${channel}!`, { allowedMentions: { repliedUser: false } }); 48 | } 49 | else if (args[0] === 'message') { 50 | data.welcomemsg = args.slice(1).join(' '); 51 | data.welcome = true; 52 | await schema.findOneAndUpdate({ 53 | id: message.guild.id, 54 | }, data); 55 | message.reply(`Welcome message is now set to **\`${data.welcomemsg}\`**!`); 56 | } 57 | }; 58 | module.exports.config = { 59 | name: 'welcome', 60 | description: 'Welcome message configuration command!', 61 | aliases: ['wlcm'], 62 | }; -------------------------------------------------------------------------------- /src/commands/music/stop.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | /** 4 | * JSDOC 5 | * @param {Discord.Client} client 6 | * @param {Discord.Message} message 7 | * @param {String[]} args 8 | * @returns 9 | */ 10 | module.exports.run = async (client, message, args) => { 11 | if (!message.guild.me.voice.channelID) { 12 | return message.reply('There isn\'t any music being played right now!', { 13 | allowedMentions: { 14 | repliedUser: false, 15 | }, 16 | }); 17 | } 18 | if (!message.member.voice.channel) { 19 | if (!message.member.voice.channelID) { 20 | return message.reply('You must be in a voice channel to use this command.', { 21 | allowedMentions: { 22 | repliedUser: false, 23 | }, 24 | }); 25 | } 26 | } 27 | if (message.member.voice.channelID !== message.guild.me.voice.channelID) { 28 | return message.reply(`You must be in \`${message.guild.me.voice.channel.name}\` to use this command`, { 29 | allowedMentions: { 30 | repliedUser: false, 31 | }, 32 | }); 33 | } 34 | 35 | const queue = client.queue.get(message.guild.id); 36 | 37 | if (!queue) { 38 | if(!message.guild.me.voice.channel) return message.reply('Bot was not in a channel!', { allowedMentions: { repliedUser: false } }); 39 | message.guild.me.voice.connection.disconnect(); 40 | message.reply('A queue was not found! But bot was in voice channel, I have left the voice channel successfully!', { allowedMentions: { repliedUser: false } }); 41 | } 42 | else if (queue) { 43 | const mes = await message.reply('Do you want to keep the queue?', { allowedMentions: { repliedUser: false } }); 44 | await mes.react('✔️'); 45 | await mes.react('✖️'); 46 | const filter = (reaction, user) => { 47 | return (reaction.emoji.name === '✔️' || reaction.emoji.name === '✖️') && user.id === message.author.id; 48 | }; 49 | mes.createReactionCollector(filter, { max: 1 }).on('end', collceted => { 50 | if (collceted.first().emoji.name === '✔️') { 51 | queue.connection.disconnect(); 52 | message.reply('Stopped the music and saved the queue!', { allowedMentions: { repliedUser: false } }); 53 | } 54 | else { 55 | client.queue.delete(message.guild.id); 56 | queue.connection.disconnect(); 57 | message.reply('Stopped the music and deleted the queue!', { allowedMentions: { repliedUser: false } }); 58 | } 59 | }); 60 | } 61 | }; 62 | 63 | module.exports.config = { 64 | name: 'stop', 65 | aliases: ['leave'], 66 | description: 'stops a current playing music!', 67 | }; 68 | -------------------------------------------------------------------------------- /src/commands/utils/help.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-inline-comments */ 2 | /* eslint-disable no-unused-vars */ 3 | const Discord = require('discord.js'); 4 | const fs = require('fs'); 5 | /** 6 | * 7 | * @param {Discord.Client} client 8 | * @param {Discord.Message} message 9 | * @param {String[]} args 10 | */ 11 | 12 | module.exports.run = (client, message, args) => { 13 | if (!args[0]) { 14 | const embed = new Discord.MessageEmbed() 15 | .setTitle('DisCruft\'s Help!') 16 | .setDescription(`My prefix is \`?\` in ${message.guild.name}! We are getting more commands soon!`) 17 | .setColor('RANDOM') 18 | .setFooter(message.author.tag, message.author.displayAvatarURL()); 19 | fs.readdir('src/commands', (err, cmdfolders) => { 20 | if (err) console.log(err); 21 | for (let i = 0; i < cmdfolders.length; i++) { 22 | embed.addField(`${require(`../${cmdfolders[i]}/config`).title}`, `\`?help ${cmdfolders[i]}\``); 23 | } 24 | message.reply({ embed: embed, allowedMentions: { repliedUser: false } }); 25 | }); 26 | } 27 | else if (fs.readdirSync('src/commands').includes(args[0])) { 28 | let cmds = fs.readdirSync(`src/commands/${args[0]}`); 29 | cmds = cmds.filter(z => z.split('.')[1] === 'js'); 30 | const embed = new Discord.MessageEmbed() 31 | .setTitle(`${args[0].slice(0, 1).toUpperCase() + args[0].slice(1).toLowerCase()} Commands!`) 32 | .setDescription(require(`../${args[0]}/config`).description) 33 | .setColor('RANDOM') 34 | .setFooter(message.author.tag, message.author.displayAvatarURL()); 35 | embed.addField('Commands', '`' + cmds.join('`, `').split('.js').join('') + '`'); 36 | message.reply({ embed: embed, allowedMentions: { repliedUser: false } }); 37 | } 38 | else if (client.commands.get(args[0]) || client.aliases.get(args[0])) { 39 | const cmd = client.commands.get(args[0]) || client.commands.get(client.aliases.get(args[0])); 40 | if(!cmd) return message.reply('That\'s not a valid command!', { allowedMentions: { repliedUser: false } }); 41 | const embed = new Discord.MessageEmbed() 42 | .setTitle(`${cmd.config.name.slice(0, 1).toUpperCase() + cmd.config.name.slice(1).toLowerCase()} Command!`) 43 | .setDescription(`${cmd.config.description}`) 44 | .setFooter(message.author.tag, message.author.displayAvatarURL()) 45 | .setColor('RANDOM') 46 | .addField('Aliases', cmd.config.aliases.join(', ') || 'None'); 47 | message.reply({ embed: embed, allowedMentions: { repliedUser: false } }); 48 | } 49 | }; 50 | module.exports.config = { 51 | name: 'help', 52 | aliases: [], 53 | description: 'The help command to help you with the bot!', 54 | }; -------------------------------------------------------------------------------- /src/slashcommands/help.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-inline-comments */ 2 | /* eslint-disable no-unused-vars */ 3 | const Discord = require('discord.js'); 4 | const fs = require('fs'); 5 | /** 6 | * 7 | * @param {Discord.Client} client 8 | * @param {Object[]} args 9 | */ 10 | module.exports.run = async (client, interaction, args) => { 11 | interaction.author = new Discord.User(client, interaction.member.user); 12 | if (!args) { 13 | const embed = new Discord.MessageEmbed() 14 | .setTitle('DisCruft\'s Help!') 15 | .setDescription(`My prefix is \`?\` in ${client.guilds.cache.get(interaction.guild_id).name}! We are getting more slash commands soon!`) 16 | .setColor('RANDOM') 17 | .setFooter(interaction.author.tag, interaction.author.displayAvatarURL()); 18 | fs.readdir('slashcommands', (err, cmds) => { 19 | if (err) console.log(err); 20 | const cmdss = cmds.map(cmd => cmd.split('.js')[0]); 21 | embed.addField('Commands', `${'`' + cmdss.join('`, `') + '`'}`); 22 | client.api.interactions(interaction.id, interaction.token).callback.post({ 23 | data: { 24 | data: { 25 | embeds: [embed], 26 | }, 27 | type: 4, 28 | }, 29 | }); 30 | }); 31 | } 32 | else if (client.slashcommands.get(args[0].value)) { 33 | const cmd = client.slashcommands.get(args[0].value); 34 | if (!cmd) { 35 | return client.api.interactions(interaction.id, interaction.token).callback.post({ 36 | data: { 37 | data: { 38 | content: 'That\'s not a valid command!', 39 | }, 40 | type: 4, 41 | }, 42 | }); 43 | } 44 | const embed = new Discord.MessageEmbed() 45 | .setTitle(`${cmd.config.name.slice(0, 1).toUpperCase() + cmd.config.name.slice(1).toLowerCase()} Command!`) 46 | .setDescription(`${cmd.config.description}`) 47 | .setFooter(interaction.author.tag, interaction.author.displayAvatarURL()) 48 | .setColor('RANDOM') 49 | .addField('Info', 'More info about the command soon!'); 50 | client.api.interactions(interaction.id, interaction.token).callback.post({ 51 | data: { 52 | data: { 53 | embeds: [embed], 54 | }, 55 | type: 4, 56 | }, 57 | }); 58 | } 59 | }; 60 | module.exports.config = { 61 | name: 'help', 62 | aliases: [], 63 | description: 'The help command to help you with the bot!', 64 | registerData: { 65 | data: { 66 | name: 'help', 67 | description: 'The help command to help you with the bot!', 68 | options: [ 69 | { 70 | name: 'command', 71 | description: 'The command you want info about', 72 | required: false, 73 | type: 3, 74 | }, 75 | ], 76 | }, 77 | }, 78 | }; -------------------------------------------------------------------------------- /src/utils/commandHandler.js: -------------------------------------------------------------------------------- 1 | /* This is in works and has no connection to the main code as of now */ 2 | 3 | 4 | class CommandManager { 5 | /** 6 | * @description Command manager for the commands! 7 | * @returns CommandManager 8 | */ 9 | constructor() { 10 | this.data = new Map(new Command().name, new Command()); 11 | this.amount = this.data.size; 12 | } 13 | } 14 | 15 | class CommandOptions { 16 | /** 17 | * @param {String} name 18 | * @param {String} description 19 | * @param {String[]} aliases 20 | */ 21 | constructor(name, description, aliases) { 22 | this.name = name; 23 | this.description = description; 24 | this.aliases = aliases; 25 | } 26 | 27 | /** 28 | * @param {Object} options 29 | */ 30 | static resolvable(options) { 31 | if(!options.name) throw new Error('No name option provided'); 32 | if(!options.description) throw new Error('No description option provided'); 33 | if(!options.aliases) throw new Error('No aliases option provided'); 34 | if(typeof options.name !== 'string') throw new Error('Provided Name is not a string!'); 35 | if(typeof options.func !== 'function') throw new Error('Provided function is not a function!'); 36 | if(!Array.isArray(options.aliases)) throw new Error('Provided Aliases is not an array!'); 37 | if(typeof options.description !== 'string') throw new Error('Provided Description is not a string'); 38 | return options; 39 | } 40 | } 41 | 42 | class Command { 43 | /** 44 | * @param {String} name Name of the command 45 | * @param {Function} func Function of the command 46 | * @param {CommandOptions} options Options of the command 47 | * @description Makes a new command to be accessed by the bot! 48 | * @returns Command 49 | */ 50 | constructor(name, func, options) { 51 | // if(typeof CommandOptions.resolvable(options) !== 'object') return; 52 | this.run = func; 53 | this.config = new CommandOptions(options.name, options.description, options.aliases); 54 | this.config.name = name; 55 | } 56 | 57 | /** 58 | * @param {Client} client 59 | * @param {Message} message 60 | * @param {String[]} args 61 | */ 62 | run(client, message, args) { 63 | this.run(client, message, args); 64 | } 65 | 66 | /** 67 | * @param {Function} func 68 | */ 69 | setFunction(func) { 70 | this.run = func; 71 | } 72 | 73 | /** 74 | * @param {String} name Returns the name of the command 75 | */ 76 | get name() { 77 | return this.config.name; 78 | } 79 | 80 | /** 81 | * @param {String} name The new name of the command 82 | */ 83 | setName(name) { 84 | if(name) { 85 | this.config.name = name; 86 | } 87 | } 88 | setOptions(options) { 89 | if(typeof CommandOptions.resolvable(options) !== 'object') return; 90 | this.options = options; 91 | } 92 | } 93 | 94 | module.exports = { 95 | Command, 96 | CommandManager, 97 | CommandOptions, 98 | }; -------------------------------------------------------------------------------- /src/commands/fun/fart.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | 3 | const Discord = require('discord.js'); 4 | 5 | module.exports.run = async (client, message, args) => { 6 | message 7 | .reply({ 8 | embed: { 9 | description: 'Uh i think **' + message.author.username + '** feels bad man', 10 | color: 'RANDOM', 11 | timestamp: new Date(), 12 | }, 13 | allowedMentions: { 14 | repliedUser: false, 15 | }, 16 | }) 17 | .then((msg) => { 18 | setTimeout(() => { 19 | msg.edit({ 20 | embed: { 21 | description: `${message.author.username} are u ok? ur green at face 🤢`, 22 | color: 'RANDOM', 23 | timestamp: new Date(), 24 | }, 25 | }); 26 | }, 3000); 27 | setTimeout(() => { 28 | msg.edit({ 29 | embed: { 30 | description: 'dude? why are u vomiting???? 🤮', 31 | color: 'RANDOM', 32 | timestamp: new Date(), 33 | }, 34 | }); 35 | }, 6000); 36 | setTimeout(() => { 37 | msg.edit({ 38 | embed: { 39 | description: 'oh no no NO dont dont do it', 40 | color: 'RANDOM', 41 | timestamp: new Date(), 42 | }, 43 | }); 44 | }, 9000); 45 | setTimeout(() => { 46 | msg.edit({ 47 | embed: { 48 | description: '🤮💨', 49 | color: 'RANDOM', 50 | timestamp: new Date(), 51 | }, 52 | }); 53 | }, 12000); 54 | setTimeout(() => { 55 | msg.edit({ 56 | embed: { 57 | description: '🤮💨💨', 58 | color: 'RANDOM', 59 | timestamp: new Date(), 60 | }, 61 | }); 62 | }, 13000); 63 | setTimeout(() => { 64 | msg.edit({ 65 | embed: { 66 | description: '🤮💨💨💨', 67 | color: 'RANDOM', 68 | timestamp: new Date(), 69 | }, 70 | }); 71 | }, 14000); 72 | setTimeout(() => { 73 | msg.edit({ 74 | embed: { 75 | description: '🤮💨💨💨💨', 76 | color: 'RANDOM', 77 | timestamp: new Date(), 78 | }, 79 | }); 80 | }, 15000); 81 | setTimeout(() => { 82 | msg.edit({ 83 | embed: { 84 | description: '🤮💨💨💨💨💨', 85 | color: 'RANDOM', 86 | timestamp: new Date(), 87 | }, 88 | }); 89 | }, 16000); 90 | setTimeout(() => { 91 | msg.edit({ 92 | embed: { 93 | description: '🤮💨💨💨💨💨💨', 94 | color: 'RANDOM', 95 | timestamp: new Date(), 96 | }, 97 | }); 98 | }, 17000); 99 | setTimeout(() => { 100 | msg.edit({ 101 | embed: { 102 | description: 'the world have been exploded since ' + `${message.author.username} has been farted on all. 👼👼`, 103 | color: 'RANDOM', 104 | timestamp: new Date(), 105 | }, 106 | }); 107 | }, 20000); 108 | }); 109 | }; 110 | module.exports.config = { 111 | name: 'fart', 112 | aliases: [], 113 | description: 'Use this command to fart 🤮', 114 | }; 115 | -------------------------------------------------------------------------------- /src/commands/mod/purge.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | /** 4 | * JSDOC 5 | * @param {Discord.Client} client 6 | * @param {Discord.Message} message 7 | * @param {String[]} args 8 | * @returns 9 | */ 10 | module.exports.run = async (client, message, args) => { 11 | const cross = client.guilds.cache.get('804584266972659722').emojis.cache.get('804967275600805888') || client.guilds.cache.get('804584266972659722').emojis.fetch('804967275600805888', true, false); 12 | if (!message.guild.me.hasPermission('MANAGE_MESSAGES')) return message.reply('I do not have permissions to delete messages!', { allowedMentions: { repliedUser: false } }); 13 | if (!message.member.permissions.has('MANAGE_MESSAGES')) return message.reply(`${cross}, You Need The Permission \`MANAGE_MESSAGES\` to use This Command!`, { allowedMentions: { repliedUser: false } }); 14 | 15 | const user = message.mentions.users.first(); 16 | if (typeof user === 'undefined') { 17 | const number = parseInt(args[0]) + 1; 18 | if (isNaN(number)) return message.reply('Please provide a valid number!', { allowedMentions: { repliedUser: false } }); 19 | if (number >= 100) return message.reply('You cannot delete more than 100 messages at once because of technical limitations!', { allowedMentions: { repliedUser: false } }); 20 | if (number < 1) return message.reply('The amount should be more than 1!', { allowedMentions: { repliedUser: false } }); 21 | 22 | message.channel.bulkDelete(number, true).then(msgs => { 23 | message.channel.send(`Successfully deleted **${msgs.size - 1}** messages`).then(m => { 24 | m.delete({ timeout: 1000 * 4 }); 25 | }); 26 | }); 27 | return; 28 | } 29 | else { 30 | const number = parseInt(args[1]); 31 | if (isNaN(number)) return message.reply('Please provide a valid number!', { allowedMentions: { repliedUser: false } }); 32 | if (number >= 100) return message.reply('You cannot delete more than 100 messages at once because of technical limitations!', { allowedMentions: { repliedUser: false } }); 33 | if (number < 1) return message.reply('The amount should be more than 1!', { allowedMentions: { repliedUser: false } }); 34 | 35 | message.channel.messages.fetch({ limit: 100 }).then(msgs => { 36 | const toDelete = new Discord.Collection(); 37 | msgs.filter(m => m.author.id === user.id).array().slice(0, number).map(m => toDelete.set(m.id, m)); 38 | toDelete.set(message.id, message); 39 | console.log(toDelete.size); 40 | message.channel.bulkDelete(toDelete).then(msg => { 41 | message.channel.send(`Successfully deleted **${msg.size - 1}** messages by **${user.tag}**`).then(m => { 42 | m.delete({ timeout: 1000 * 5 }); 43 | }); 44 | }).catch(error => { 45 | console.log(error); 46 | message.reply(`There was an error deleting the messages!\nError: ${error})`, { allowedMentions: { repliedUser: false } }); 47 | }); 48 | }); 49 | } 50 | }; 51 | module.exports.config = { 52 | name: 'purge', 53 | desc: 'Deletes messages in the channel!', 54 | aliases: ['clear'], 55 | }; -------------------------------------------------------------------------------- /src/commands/mod/ban.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const { Client, Message, MessageEmbed } = require('discord.js'); 3 | /** 4 | * JSDOC 5 | * @param {Client} client 6 | * @param {Message} message 7 | * @param {String[]} args 8 | */ 9 | module.exports.run = async (client, message, args) => { 10 | if (!message.guild.me.hasPermission('BAN_MEMBERS')) return message.reply('I don\'t have permission to ban members!', { allowedMentions: { repliedUser: false } }); 11 | if (!message.member.hasPermission('BAN_MEMBERS')) return message.reply('You don\'t have permission to ban members!', { allowedMentions: { repliedUser: false } }); 12 | if (!args[0]) return message.reply('Provide someone to ban!', { allowedMentions: { repliedUser: false } }); 13 | const target = message.mentions.members.first() || await message.guild.members.fetch(args[0]).catch(e => { 14 | return message.reply('Can\'t find specefied member! Provide a valid id', { allowedMentions: { repliedUser: false } }); 15 | }); 16 | 17 | if(target.id === message.author.id) return message.reply('Why would you want to ban yourself?!', { allowedMentions: { repliedUser: false } }); 18 | if(target.id === client.user.id) return message.reply('Why would you want to ban me?!', { allowedMentions: { repliedUser: false } }); 19 | 20 | const reason = args.slice(1).join(' '); 21 | if (!target.bannable) return message.reply('Can\'t ban specified member! Make sure I\'m above them in the heirarchy', { allowedMentions: { repliedUser: false } }); 22 | 23 | const confirmationEmbed = new MessageEmbed() 24 | .setAuthor(message.author.username, message.author.displayAvatarURL({ dynamic: true })) 25 | .setTitle(`Are you sure you want to ban ${target.user.tag} for reason - ${reason}?`); 26 | const mes = await message.reply({ embed: confirmationEmbed, allowedMentions: { repliedUser: false } }); 27 | await mes.react('✔️'); 28 | await mes.react('✖️'); 29 | 30 | const filter = (reaction, user) => { 31 | return (reaction.emoji.name === '✔️' || reaction.emoji.name === '✖️') && user.id === message.author.id; 32 | }; 33 | const collector = mes.createReactionCollector(filter, { max: 1, time: 1000 * 30 }); 34 | collector.on('end', async collected => { 35 | if (collected.first().emoji.name === '✔️') { 36 | await target.ban({ reason: reason }); 37 | const banEmbed = new MessageEmbed() 38 | .setAuthor(message.author.username, message.author.displayAvatarURL({ dynamic: true })) 39 | .setTitle(`Banned ${target.user.tag}! Reason - ${reason}`); 40 | await mes.edit(banEmbed); 41 | await mes.reactions.removeAll(); 42 | } 43 | else { 44 | const cancelEmbed = new MessageEmbed() 45 | .setAuthor(message.author.username, message.author.displayAvatarURL({ dynamic: true })) 46 | .setTitle(`Cancelled banning ${target.user.tag}!`); 47 | await mes.edit(cancelEmbed); 48 | await mes.reactions.removeAll(); 49 | } 50 | }); 51 | }; 52 | 53 | module.exports.config = { 54 | name: 'ban', 55 | aliases: ['bam'], 56 | description: 'Bans a member! Do it if you think someone is bannable!!', 57 | }; 58 | -------------------------------------------------------------------------------- /src/commands/utils/serverinfo.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const moment = require('moment'); 3 | const { 4 | Client, 5 | Message, 6 | MessageEmbed, 7 | } = require('discord.js'); 8 | const config = require('../../config.json'); 9 | const region = { 10 | 'brazil': ':flag_br: Brazil', 11 | 'eu-central': ':flag_eu: Central Europe', 12 | 'singapore': ':flag_sg: Singapore', 13 | 'us-central': ':flag_us: U.S. Central', 14 | 'sydney': ':flag_au: Sydney', 15 | 'us-east': ':flag_us: U.S. East', 16 | 'us-south': ':flag_us: U.S. South', 17 | 'us-west': ':flag_us: U.S. West', 18 | 'eu-west': ':flag_eu: Western Europe', 19 | 'vip-us-east': ':flag_us: VIP U.S. East', 20 | 'london': ':flag_gb: London', 21 | 'amsterdam': ':flag_nl: Amsterdam', 22 | 'hongkong': ':flag_hk: Hong Kong', 23 | 'russia': ':flag_ru: Russia', 24 | 'southafrica': ':flag_za: South Africa', 25 | }; 26 | /** 27 | * JSDOC 28 | * @param {Client} client 29 | * @param {Message} message 30 | * @param {String[]} args 31 | */ 32 | 33 | module.exports.run = async (client, message, args) => { 34 | 35 | const roles = message.guild.roles.cache.sort((a, b) => b.position - a.position).map(role => role.toString()); 36 | const voiceChannelCount = message.guild.channels.cache.filter(c => c.type === 'voice').size; 37 | const textChannelCount = message.guild.channels.cache.size; 38 | const memberCounts = message.guild.memberCount; 39 | 40 | const voicetext = '#️⃣ ' + ' ' + textChannelCount + ' ' + 'Text ' + ', ' + ' ' + ' ' + ' 🔊 ' + voiceChannelCount + ' ' + 'Voice'; 41 | const serverMembers = `${memberCounts}` + ' ' + '**Total** Members' + ', ' + `${message.guild.members.cache.filter(member => member.user.bot).size}` + ' ' + '**Bot(s)**'; 42 | 43 | const embed = new MessageEmbed() 44 | .setAuthor(message.guild.name, message.guild.iconURL({ 45 | format: 'png', 46 | dynamic: true, 47 | size: 2048, 48 | })) 49 | .setColor(config.mainColor) 50 | .addField('Region', region[message.guild.region], true) 51 | .addField('Server ID', message.guild.id, false) 52 | .addField('Owner', `👑 ${message.guild.owner}`, true) 53 | .addField('Boosts', `${message.guild.premiumSubscriptionCount} (Tier ${message.guild.premiumTier})`, true) 54 | .addField('Total Server Members', `${serverMembers}`, false) 55 | .addField('Channels Count', voicetext, false) 56 | .addField('Emojis Count', `<:bored:823667560016379915> ${message.guild.emojis.cache.size} Emojis`, true) 57 | .addField('Roles Count', `${message.guild.roles.cache.size} Roles`, true) 58 | .addField('Server Creation Date', `:date: ${message.channel.guild.createdAt.toUTCString().substr(0, 16)} (${checkDays(message.channel.guild.createdAt)})`, false) 59 | .setThumbnail(message.guild.iconURL()) 60 | .setTimestamp() 61 | .setFooter(message.guild.name); 62 | 63 | message.reply({ 64 | embed: embed, 65 | allowedMentions: { 66 | repliedUser: false, 67 | }, 68 | }); 69 | 70 | }; 71 | 72 | module.exports.config = { 73 | name: 'serverinfo', 74 | aliases: ['server', 'sinfo'], 75 | description: 'Shows info of a guild/server!', 76 | }; 77 | 78 | function checkDays(date) { 79 | const now = new Date(); 80 | const diff = now.getTime() - date.getTime(); 81 | const days = Math.floor(diff / 86400000); 82 | return days + (days == 1 ? ' day' : ' days') + ' ago'; 83 | } 84 | -------------------------------------------------------------------------------- /src/commands/mod/lockdown.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-inline-comments */ 2 | /* eslint-disable no-unused-vars */ 3 | 4 | /* Any database expert can check this code I cannot complete the database part sadly */ 5 | 6 | const Discord = require('discord.js'); 7 | const schema = require('../../database/models/Guilds'); 8 | /** 9 | * 10 | * @param {Discord.Client} client 11 | * @param {Discord.Message} message 12 | * @param {String[]} args 13 | * @returns 14 | */ 15 | 16 | module.exports.run = async (client, message, args) => { 17 | if (!message.member.hasPermission('MANAGE_CHANNELS')) return message.channel.send('You do not have permissions to use this command!'); 18 | if (!message.guild.me.hasPermission('MANAGE_CHANNELS')) return message.channel.send('Unable to lock the channels! Missing permissions'); 19 | if (!args[0]) return message.reply('There is two options `true` to lockdown the server, `false` to remove the lockdown', { allowedMentions: { repliedUser: false } }); 20 | if (!['true', 'false'].includes(args[0].toLowerCase())) return message.reply('Please provide a valid option! Either `true` or `false`.', { allowedMentions: { repliedUser: false } }); 21 | let data = await schema.findOne({ 22 | id: message.guild.id, 23 | }); 24 | if(!data) { 25 | data = await new schema({ 26 | id: message.guild.id, 27 | prefix: '?', 28 | locked: { 29 | enabled: false, 30 | lockChannels: [], 31 | }, 32 | }).save(); 33 | return message.reply('You have not setup lockdown! Use `lockdown-setup` command to setup lockdown.', { allowedMentions: { repliedUser: false } }); 34 | } 35 | 36 | if(!data.locked) return message.reply('You have not setup lockdown! Use `lockdown-setup` command to setup lockdown.', { allowedMentions: { repliedUser: false } }); 37 | if(!data.locked.lockChannels) return message.reply('You have not setup lockdown! Use `lockdown-setup` command to setup lockdown.', { allowedMentions: { repliedUser: false } }); 38 | if(!data.locked.lockChannels[0]) return message.reply('You have not setup lockdown! Use `lockdown-setup` command to setup lockdown.', { allowedMentions: { repliedUser: false } }); 39 | 40 | if (args[0].toLowerCase() === 'true') { 41 | if(data.locked.enabled) return message.reply('The server is already locked!', { allowedMentions: { repliedUser: false } }); 42 | data.locked.enabled = true; 43 | const channels = message.guild.channels.cache.filter(x => data.locked.lockChannels.includes(x.id)); 44 | channels.forEach((channel) => { 45 | if(!channel.manageable) return; 46 | channel.updateOverwrite(message.guild.id, { 47 | SEND_MESSAGES: false, 48 | }); 49 | }); 50 | message.channel.send('Locked the server!'); 51 | data.save(); 52 | } 53 | else if(args[0].toLowerCase() === 'false') { 54 | if(!data.locked.enabled) return message.reply('The server is already unlocked!', { allowedMentions: { repliedUser: false } }); 55 | data.locked.enabled = false; 56 | const channels = message.guild.channels.cache.filter(x => data.locked.lockChannels.includes(x.id)); 57 | channels.forEach((channel) => { 58 | if(!channel.manageable) return; 59 | channel.updateOverwrite(message.guild.id, { 60 | SEND_MESSAGES: true, 61 | }); 62 | }); 63 | message.channel.send('Unlocked the server!'); 64 | data.save(); 65 | } 66 | }; 67 | module.exports.config = { 68 | name: 'lockdown', 69 | desc: 'Locks the whole server!', 70 | aliases: [], 71 | }; -------------------------------------------------------------------------------- /src/commands/music/skip.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const Discord = require('discord.js'); 3 | const ytdl = require('ytdl-core'); 4 | /** 5 | * JSDOC 6 | * @param {Discord.Client} client 7 | * @param {Discord.Message} message 8 | * @param {String[]} args 9 | * @returns 10 | */ 11 | module.exports.run = async (client, message, args) => { 12 | if (!message.member.voice.channel) { 13 | if (!message.member.voice.channelID) { 14 | return message.reply('You must be in a voice channel to use this command.', { 15 | allowedMentions: { 16 | repliedUser: false, 17 | }, 18 | }); 19 | } 20 | } 21 | if (message.member.voice.channelID !== message.guild.me.voice.channelID) { 22 | return message.reply(`You must be in \`${message.guild.me.voice.channel.name}\` to use this command`, { 23 | allowedMentions: { 24 | repliedUser: false, 25 | }, 26 | }); 27 | } 28 | 29 | const queue = client.queue.get(message.guild.id); 30 | 31 | if (queue) { 32 | if (!queue.songs[0]) return message.reply('There isnt any queue!', { allowedMentions: { repliedUser: false } }); 33 | const skipped = queue.songs.shift(); 34 | play(queue.songs[0], queue.voicechannel); 35 | message.reply(`Skipped **\`${skipped.title}\`** requested by **${skipped.requestedBy.tag}**!`, { allowedMentions: { repliedUser: false } }); 36 | } 37 | else { 38 | return message.reply('There isnt any queue!', { 39 | allowedMentions: { 40 | repliedUser: false, 41 | }, 42 | }); 43 | } 44 | }; 45 | 46 | module.exports.config = { 47 | name: 'skip', 48 | aliases: [], 49 | description: 'skips to the next music in queue if any!', 50 | }; 51 | 52 | async function play(song, voicechannel) { 53 | const queue = voicechannel.client.queue.get(voicechannel.guild.id); 54 | if (voicechannel.members.size === 0) { 55 | queue.textchannel.send('Stopped the music due to empty voice channel! The queue is not deleted'); 56 | } 57 | if (!song) { 58 | voicechannel.client.queue.delete(voicechannel.guild.id); 59 | return queue.connection.disconnect(); 60 | } 61 | if (!voicechannel.guild.me.voice.channelID) { 62 | await queue.voicechannel.join(); 63 | } 64 | const stream = ytdl(song.url, { filter: 'audioonly' }); 65 | queue.connection.play(stream, { seek: 0, volume: 0.5 }) 66 | .on('finish', () => { 67 | const played = queue.songs.shift(); 68 | if (queue.loop) queue.songs.push(played); 69 | play(queue.songs[0], voicechannel); 70 | }); 71 | const playembed = new Discord.MessageEmbed() 72 | .setTitle('Started playing!') 73 | .setDescription(queue.songs[0].title) 74 | .addFields( 75 | { name: 'URL', value: `[${queue.songs[0].title}](${queue.songs[0].url})`, inline: true }, 76 | { name: 'Type', value: queue.songs[0].type, inline: true }, 77 | { name: 'Video duration', value: `${queue.songs[0].duration}`, inline: true }, 78 | { name: 'Song added by', value: `${song.requestedBy.toString()}`, inline: true }, 79 | { name: 'Song By', value: `${queue.songs[0].artist}`, inline: true }, 80 | { name: 'Album', value: `${queue.songs[0].album}`, inline: true }, 81 | ) 82 | .setColor('RANDOM') 83 | .setFooter(`Uploaded ${queue.songs[0].uploaded} | ${queue.songs[0].views.toString().replace(/\B(? { 13 | let data = await schema.findOne({ 14 | id: member.guild.id, 15 | }); 16 | if (!data) { 17 | data = await new schema({ 18 | id: member.guild.id, 19 | prefix: '?', 20 | locked: false, 21 | lockedChannels: [], 22 | welcome: false, 23 | }).save(); 24 | } 25 | if (data.welcome === true && data.welcomeChannel) { 26 | const c = 'https://i.imgur.com/RhAzf2d.png'; 27 | 28 | if (!c) return; 29 | if (!member.guild) return; 30 | // create a new Canvas 31 | const canvas = Canvas.createCanvas(1772, 633); 32 | // make it "2D" 33 | const ctx = canvas.getContext('2d'); 34 | // set the Background to the welcome.png 35 | const background = await Canvas.loadImage(c); 36 | ctx.drawImage(background, 0, 0, canvas.width, canvas.height); 37 | ctx.strokeStyle = '#000000'; 38 | ctx.strokeRect(0, 0, canvas.width, canvas.height); 39 | // set the first text string 40 | const textString3 = `${member.user.username}`; 41 | // if the text is too big then smaller the text 42 | if (textString3.length >= 14) { 43 | ctx.font = 'bold 100px "deb"'; 44 | ctx.fillStyle = '#000000'; 45 | ctx.fillText(textString3, 720, canvas.height / 2 + 20); 46 | } 47 | // else dont do it 48 | else { 49 | ctx.font = 'bold 150px "deb"'; 50 | ctx.fillStyle = '#000000'; 51 | ctx.fillText(textString3, 720, canvas.height / 2 + 20); 52 | } 53 | // define the Discriminator Tag 54 | const textString2 = `#${member.user.discriminator}`; 55 | ctx.font = 'bold 40px "deb"'; 56 | ctx.fillStyle = '#000000'; 57 | ctx.fillText(textString2, 730, canvas.height / 2 + 58); 58 | // define the Member count 59 | const textString4 = `YOU ARE THE ${member.guild.memberCount}th MEMBER`; 60 | ctx.font = 'bold 60px "deb"'; 61 | ctx.fillStyle = '#000000'; 62 | ctx.fillText(textString4, 750, canvas.height / 2 + 125); 63 | // get the Guild Name 64 | const textString5 = `${member.guild.name}`; 65 | ctx.font = 'bold 60px "deb"'; 66 | ctx.fillStyle = '#000000'; 67 | ctx.fillText(textString5, 700, canvas.height / 2 - 150); 68 | // create a circular "mask" 69 | ctx.beginPath(); 70 | ctx.arc(315, canvas.height / 2, 250, 0, Math.PI * 2, true); 71 | ctx.closePath(); 72 | ctx.clip(); 73 | // define the user avatar 74 | const avatar = await Canvas.loadImage(member.user.displayAvatarURL({ format: 'jpg', size: 2048 })); 75 | // draw the avatar 76 | ctx.drawImage(avatar, 65, canvas.height / 2 - 250, 500, 500); 77 | // get it as a discord attachment 78 | const attachment = new Discord.MessageAttachment(canvas.toBuffer(), 'welcome-image.png'); 79 | // define the welcome embed 80 | const welcometitles = [`**${member.user.username}** just landed!`, `Just saw **${member.user.username}** hop in the server`, `**${member.user.username}** thanks for joining!`, `Woah ${member.user.username} just joined!`]; 81 | const welcomeembed = new Discord.MessageEmbed() 82 | .setColor('RANDOM') 83 | .setTimestamp() 84 | .setTitle(welcometitles[Math.floor(Math.random() * welcometitles.length)]) 85 | .setDescription(data.welcomemsg) 86 | .setFooter('Welcome', member.guild.iconURL({ dynamic: true })) 87 | .attachFiles([attachment]); 88 | const ch = member.guild.channels.cache.get(data.welcomeChannel); 89 | try { 90 | ch.send(welcomeembed); 91 | } 92 | catch (e) { 93 | console.log(e); 94 | } 95 | } 96 | }; -------------------------------------------------------------------------------- /src/commands/utils/languagelist.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const recon = require('reconlx'); 3 | const Discord = require('discord.js'); 4 | // Destructure the package 5 | const ReactionPages = recon.ReactionPages; 6 | module.exports.run = async (client, message, args) => { 7 | const embed1 = new Discord.MessageEmbed() 8 | .setDescription(`af : Afrikaans,\n 9 | sq: Albanian,\n 10 | am: Amharic, \n 11 | ar: Arabic, \n 12 | hy: Armenian,\n 13 | az: Azerbaijani,\n 14 | eu: Basque,\n 15 | be: Belarusian,\n 16 | bn: Bengali,\n 17 | bs: Bosnian,\n 18 | bg: Bulgarian,\n 19 | ca: Catalan,\n 20 | ceb: Cebuano,\n 21 | ny: Chichewa,\n 22 | zh-CN: Chinese (Simplified),\n 23 | zh-TW: Chinese (Traditional),\n 24 | co: Corsican,\n 25 | hr: Croatian,\n 26 | cs: Czech,\n 27 | da: Danish,\n 28 | nl: Dutch,\n 29 | en: English,\n 30 | eo: Esperanto,\n 31 | et: Estonian,\n 32 | tl: Filipino,\n 33 | fi: Finnish,\n 34 | fr: French,\n 35 | fy: Frisian,\n 36 | gl: Galician,\n 37 | ka: Georgian,\n 38 | de: German,\n 39 | el: Greek \n 40 | gu: Gujarati`) 41 | .setColor('RANDOM'); 42 | const embed2 = new Discord.MessageEmbed() 43 | .setDescription(`ht: Haitian Creole, 44 | ha: Hausa,\n 45 | haw: Hawaiian,\n 46 | he: Hebrew,\n 47 | iw: Hebrew,\n 48 | hi: Hindi,\n 49 | hmn: Hmong,\n 50 | hu: Hungarian,\n 51 | is: Icelandic,\n 52 | ig: Igbo,\n 53 | id: Indonesian,\n 54 | ga: Irish,\n 55 | it: Italian,\n 56 | ja: Japanese,\n 57 | jw: Javanese,\n 58 | kn: Kannada,\n 59 | kk: Kazakh,\n 60 | km: Khmer,\n 61 | ko: Korean,\n 62 | ku: Kurdish (Kurmanji),\n 63 | ky: Kyrgyz,\n 64 | lo: Lao,\n 65 | la: Latin,\n 66 | lv: Latvian,\n 67 | lt: Lithuanian,\n 68 | lb: Luxembourgish,\n 69 | mk: Macedonian,\n 70 | mg: Malagasy,\n 71 | ms: Malay,\n 72 | ml: Malayalam,\n 73 | mt: Maltese,\n 74 | mi: Maori,\n 75 | mr: Marathi,\n 76 | mn: Mongolian,\n 77 | my: Myanmar (Burmese),\n 78 | ne: Nepali,\n 79 | no: Norwegian,\n 80 | ps: Pashto,\n 81 | fa: Persian,\n 82 | pl: Polish,\n 83 | pt: Portuguese,\n 84 | pa: Punjabi,\n 85 | ro: Romanian,\n 86 | ru: Russian,\n 87 | sm: Samoan,\n 88 | gd: Scots Gaelic,\n 89 | sr: Serbian,\n 90 | st: Sesotho,\n 91 | sn: Shona,\n 92 | sd: Sindhi,\n 93 | si: Sinhala,\n 94 | sk: Slovak,\n 95 | sl: Slovenian,\n 96 | so: Somali,\n 97 | es: Spanish,\n 98 | su: Sundanese,\n 99 | sw: Swahili,\n 100 | sv: Swedish,\n 101 | tg: Tajik,\n 102 | ta: Tamil,\n 103 | te: Telugu,\n 104 | th: Thai,\n 105 | tr: Turkish,\n 106 | uk: Ukrainian,\n 107 | ur: Urdu,\n 108 | uz: Uzbek,\n 109 | vi: Vietnamese,\n 110 | cy: Welsh,\n 111 | xh: Xhosa,\n 112 | yi: Yiddish,\n 113 | yo: Yoruba,\n 114 | zu: Zulu\n 115 | };`) 116 | .setColor('RANDOM'); 117 | const pages = [embed1, embed2]; 118 | // Change pages when sending numbers. 119 | const textPageChange = true; 120 | // Create an emojilist, first emoji being page back and second emoji being page front. Defaults are set to [⏪, ⏩]. 121 | const emojis = ['⏪', '⏩']; 122 | // Define a time in ms, defaults are set to 60000ms which is 60 seconds. Time on how long you want the embed to be interactable 123 | const time = 30000; 124 | // Call the ReactionPages method, use the parameter to initialize it. 125 | ReactionPages(message, pages, textPageChange, emojis, time); 126 | }; 127 | module.exports.config = { 128 | name: 'lang_list', 129 | aliases: [], 130 | description: 'This is the language list for translate command', 131 | }; -------------------------------------------------------------------------------- /src/commands/config/ticket.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-useless-escape */ 2 | /* eslint-disable no-unused-vars */ 3 | const Discord = require('discord.js'); 4 | const schema = require('../../database/models/Guilds'); 5 | 6 | /** 7 | * JSDOC 8 | * @param {Discord.Client} client 9 | * @param {Discord.Message} message 10 | * @param {String[]} args 11 | */ 12 | module.exports.run = async (client, message, args) => { 13 | return message.reply('Disabled command'); 14 | if (!message.member.hasPermission('MANAGE_GUILD')) return message.reply('You need `MANAGE_GUILD` permission!', { allowedMentions: { repliedUser: false } }); 15 | let data = await schema.findOne({ 16 | id: message.guild.id, 17 | }); 18 | if (!data) { 19 | data = await new schema({ 20 | id: message.guild.id, 21 | prefix: '?', 22 | locked: { 23 | enabled: false, 24 | }, 25 | welcome: { 26 | enabled: false, 27 | }, 28 | tickets: { 29 | enabled: false, 30 | }, 31 | }); 32 | } 33 | if (!args[0]) return message.reply('You can use `disable` to disable ticket, `enable` to enable ticket, `list` to list your ticket and `create` to create a ticket!', { allowedMentions: { repliedUser: false } }); 34 | if (!['enable', 'disable', 'create'].includes(args[0].toLowerCase())) return message.reply('There is only `enable`, `disable`, `create`'); 35 | if (args[0].toLowerCase() === 'enable') { 36 | if (data.tickets.enabled === true) return message.reply('Ticket system is already enabled!'); 37 | data.tickets.enabled = true; 38 | message.reply('Successfully enabled ticket! Make sure to put a channel!'); 39 | await data.save(); 40 | } 41 | else if (args[0].toLowerCase() === 'disable') { 42 | if (data.tickets.enabled === false) return message.reply('Ticket system is already disabled!'); 43 | data.tickets.enabled = false; 44 | message.reply('Successfully disabled ticket! Make sure to put a channel!'); 45 | await data.save(); 46 | } 47 | else if (args[0].toLowerCase() === 'create') { 48 | if (!data.tickets.enabled) return message.reply('You did not enable ticket! Enable it and then try running this command'); 49 | 50 | const ticketembed = new Discord.MessageEmbed(); 51 | if (!args[1]) return message.reply('You can use `new` to create a new ticket message OR `existing` to use any existing message, it can even be a message sent by you!', { allowedMentions: { repliedUser: false } }); 52 | 53 | if (args[1].toLowerCase() === 'new') { 54 | let step = 0; 55 | const filter = msg => msg.author.id === message.author.id; 56 | const collector = message.channel.createMessageCollector(filter, { max: 4, time: 60000 }); 57 | message.channel.send('What will be the title of the embed?'); 58 | collector.on('collect', async (msg) => { 59 | if (msg.content.toLowerCase() === 'stop') return cancel(msg, collector); 60 | step++; 61 | if (step == 1) { 62 | if (!msg.content) return cancel(msg, collector); 63 | ticketembed.setTitle(msg.content); 64 | message.channel.send(`Set the title of the embed to \`${msg.content.replace('`', '\`')}\``); 65 | } 66 | else if (step == 2) { 67 | if (!msg.content) return cancel(msg, collector); 68 | ticketembed.setDescription(msg.content); 69 | message.channel.send(`Set the description of the embed to \`${msg.content.replace('`', '\`')}\``); 70 | } 71 | else if (step == 3) { 72 | if (!msg.content) return cancel(msg, collector); 73 | if (!Discord.Util.resolveColor(msg.content)) return cancel(msg, collector, ' Not a valid color!'); 74 | ticketembed.setColor(Discord.Util.resolveColor(msg.content)); 75 | message.channel.send(`Set the color of the embed to \`${msg.content.replace('`', '\`')}\``); 76 | } 77 | else if (step == 4) { 78 | if (!msg.content) return cancel(msg, collector); 79 | if (!msg.mentions.channels.first()) return cancel(msg, collector); 80 | const channel = message.mentions.channels.first() || message.guild.channels.cache.get(msg.content); 81 | data.tickets.channelID = channel.id; 82 | } 83 | }); 84 | collector.on('end', async (msgs) => { 85 | client.channels.cache.get(data.tickets.channelID).send(ticketembed).then(async embed => { 86 | await embed.react('🎟️'); 87 | data.tickets.messageID = embed.id; 88 | await data.save(); 89 | }); 90 | }); 91 | } 92 | else if (args[1].toLowerCase() === 'existing') { 93 | message.reply('Provide channel and message ID of the message. Example: `123456789012345678 #ticket-channel`', { allowedMentions: { repliedUser: false } }); 94 | const filter = msg => msg.author.id === message.author.id; 95 | message.channel.awaitMessages(filter, { time: 30000, max: 1 }) 96 | .then(async (msgs) => { 97 | const m = msgs.first(); 98 | if(!m.mentions.channels.filter(x => x.type === 'text').first()) return message.reply('Please mention a channel!', { allowedMentions: { repliedUser: false } }); 99 | const arg = m.content.split(' '); 100 | if(isNaN(arg[0])) return message.reply('Please provide a message ID!', { allowedMentions: { repliedUser: false } }); 101 | const c = m.guild.channels.cache.get(m.mentions.channels.filter(x => x.type === 'text').first().id); 102 | const messag = await c.messages.fetch(arg[0]).catch(() => {return message.reply('Unable to find the message!', { allowedMentions: { repliedUser: false } });}); 103 | data.tickets.messageID = messag.id; 104 | data.tickets.channelID = c.id; 105 | data.save(); 106 | message.channel.send('Successfully added the message ID to database'); 107 | }); 108 | } 109 | } 110 | }; 111 | module.exports.config = { 112 | name: 'ticket', 113 | description: 'Ticket system to make your applications, etc. cleaner!', 114 | aliases: [], 115 | }; 116 | /** 117 | * @param {Discord.Message} message 118 | * @param {Discord.MessageCollector} collector 119 | * @param {String} reason 120 | */ 121 | async function cancel(message, collector, reason = ' Invalid value or no value provided!') { 122 | message.reply('Cancelled ticket creation!' + reason, { allowedMentions: { repliedUser: false } }); 123 | return collector.stop(); 124 | } -------------------------------------------------------------------------------- /src/commands/music/play.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | const Discord = require('discord.js'); 3 | const yt = require('yt-search'); 4 | const ytdl = require('ytdl-core'); 5 | /** 6 | * JSDOC 7 | * @param {Discord.Client} client 8 | * @param {Discord.Message} message 9 | * @param {String[]} args 10 | * @returns 11 | */ 12 | module.exports.run = async (client, message, args) => { 13 | if (!message.member.voice.channel) return message.reply('You need to be a voice channel!', { allowedMentions: { repliedUser: false } }); 14 | if (!message.guild.me.hasPermission('CONNECT')) return message.reply(`I don't have \`CONNECT\` permission to connect to \`${message.member.voice.channel.name}\``, { allowedMentions: { repliedUser: false } }); 15 | if (!message.guild.me.permissionsIn(message.member.voice.channel).has('CONNECT')) return message.reply(`I don't have \`CONNECT\` permission to connect to \`${message.member.voice.channel.name}\``, { allowedMentions: { repliedUser: false } }); 16 | if (!message.member.voice.channel.joinable || !message.member.voice.channel.speakable) return message.reply(`I cannot join/speak in ${message.member.voice.channel.toString()}`, { allowedMentions: { repliedUser: false } }); 17 | let joiningmsg = null; 18 | if (client.queue.get(message.guild.id) && !args[0]) { 19 | if (client.queue.get(message.guild.id).songs[0]) { 20 | if (!message.guild.me.voice.channel) { 21 | if (message.member.voice.channel.id !== client.queue.get(message.guild.id).voicechannel.id) client.queue.get(message.guild.id).voicechannel = message.member.voice.channel; 22 | client.queue.get(message.guild.id).connection = await message.member.voice.channel.join(); 23 | } 24 | return play(client.queue.get(message.guild.id).songs[0], client.queue.get(message.guild.id).voicechannel); 25 | } 26 | } 27 | if (ytdl.validateURL(args[0])) { 28 | const queue = client.queue.get(message.guild.id); 29 | if (!message.guild.me.voice.channel) { 30 | joiningmsg = await message.reply(`Joining ${message.member.voice.channel.toString()}!`, { allowedMentions: { repliedUser: false } }); 31 | connection = await message.member.voice.channel.join(); 32 | } 33 | else if (!queue) { 34 | message.member.voice.channel.leave(); 35 | connection = await message.member.voice.channel.join(); 36 | } 37 | 38 | const songInfo = await ytdl.getInfo(args[0]); 39 | const artist = !songInfo.videoDetails.media.artist ? songInfo.videoDetails.author.name : songInfo.videoDetails.media.artist; 40 | const album = !songInfo.videoDetails.media.album ? 'None' : songInfo.videoDetails.media.album; 41 | const song = { 42 | title: songInfo.videoDetails.title, 43 | url: songInfo.videoDetails.video_url, 44 | duration: (songInfo.videoDetails.lengthSeconds / 60).toFixed(2), 45 | rawDuration: songInfo.videoDetails.lengthSeconds, 46 | thumbnail: songInfo.player_response.videoDetails.thumbnail.thumbnails[0].url, 47 | uploaded: `${(new Date(Date.now() - new Date(songInfo.videoDetails.publishDate.split('-')[0], songInfo.videoDetails.publishDate.split('-')[1], songInfo.videoDetails.publishDate.split('-')[2]).getTime()) / 31536000000).toFixed(0).startsWith('0') ? (new Date(Date.now() - new Date(songInfo.videoDetails.publishDate.split('-')[0], songInfo.videoDetails.publishDate.split('-')[1], songInfo.videoDetails.publishDate.split('-')[2]).getTime()) / 31536000000).toFixed(0) : (new Date(Date.now() - new Date(songInfo.videoDetails.publishDate.split('-')[0], songInfo.videoDetails.publishDate.split('-')[1], songInfo.videoDetails.publishDate.split('-')[2]).getTime()) / 86400000).toFixed(0)} days(s) ago`, 48 | views: String(songInfo.videoDetails.viewCount).padStart(10, ' '), 49 | requestedBy: message.author, 50 | artist: artist, 51 | album: album, 52 | skippedSec: 0, 53 | }; 54 | if (!queue) { 55 | const basequeue = { 56 | voicechannel: message.member.voice.channel, 57 | textchannel: message.channel, 58 | connection: connection, 59 | playing: true, 60 | loop: false, 61 | songs: [], 62 | }; 63 | basequeue.songs.push(song); 64 | client.queue.set(message.guild.id, basequeue); 65 | play(song, basequeue.voicechannel); 66 | } 67 | else if (queue) { 68 | queue.songs.push(song); 69 | const playembed = new Discord.MessageEmbed() 70 | .setTitle('Song added to queue!') 71 | .setDescription(result.title) 72 | .addFields( 73 | { name: 'URL', value: `[${song.title}](${song.url})`, inline: true }, 74 | { name: 'Type', value: 'Song', inline: true }, 75 | { name: 'Video duration', value: `${song.duration}`, inline: true }, 76 | { name: 'Song added by', value: `${message.author.toString()}`, inline: true }, 77 | { name: 'Song By', value: `${result.author.name}`, inline: true }, 78 | { name: 'Album', value: `${album}`, inline: true }, 79 | ) 80 | .setColor('RANDOM') 81 | .setFooter(`Uploaded ${queue.songs[0].uploaded} | ${song.views.toString().replace(/\B(? { 177 | voicechannel.client.queue.delete(voicechannel.guild.id); 178 | return voicechannel.leave(); 179 | }, 5000); 180 | } 181 | const stream = ytdl(song.url, { filter: 'audioonly' }); 182 | queue.connection.play(stream, { seek: 0, volume: 0.5 }) 183 | .on('finish', () => { 184 | const played = queue.songs.shift(); 185 | if (queue.loop) queue.songs.push(played); 186 | play(queue.songs[0], voicechannel); 187 | }); 188 | const playembed = new Discord.MessageEmbed() 189 | .setTitle('Started playing!') 190 | .setDescription(queue.songs[0].title) 191 | .addFields( 192 | { name: 'URL', value: `[${queue.songs[0].title}](${queue.songs[0].url})`, inline: true }, 193 | { name: 'Type', value: queue.songs[0].type || 'video', inline: true }, 194 | { name: 'Video duration', value: `${queue.songs[0].duration}`, inline: true }, 195 | { name: 'Song added by', value: `${song.requestedBy.toString()}`, inline: true }, 196 | { name: 'Song By', value: `${queue.songs[0].artist}`, inline: true }, 197 | { name: 'Album', value: `${queue.songs[0].album}`, inline: true }, 198 | ) 199 | .setColor('RANDOM') 200 | .setFooter(`Uploaded ${queue.songs[0].uploaded} | ${queue.songs[0].views.toString().replace(/\B(? { 15 | if (!message.member.voice.channelID) return message.reply('You need to be in a stage channel!', { allowedMentions: { repliedUser: false } }); 16 | const channel = new Discord.VoiceChannel(message.guild, (await client.api.channels(message.member.voice.channelID).get())); 17 | if(channel.type !== 'unknown') return message.reply('You need to be in a stage channel!'); 18 | if (client.voice.connections.get(message.guild.id)) client.voice.connections.delete(message.guild.id); 19 | channel.joinable = true; 20 | if (!channel) return message.reply('You need to be a stage channel!', { allowedMentions: { repliedUser: false } }); 21 | if (!message.guild.me.hasPermission('CONNECT')) return message.reply(`I don't have \`CONNECT\` permission to connect to \`${channel.name}\``, { allowedMentions: { repliedUser: false } }); 22 | if (!message.guild.me.permissionsIn(channel).has('CONNECT')) return message.reply(`I don't have \`CONNECT\` permission to connect to \`${channel.name}\``, { allowedMentions: { repliedUser: false } }); 23 | if (!channel.joinable || !channel.speakable) return message.reply(`I cannot join/speak in ${channel.toString()}`, { allowedMentions: { repliedUser: false } }); 24 | let joiningmsg = null; 25 | if (client.queue.get(message.guild.id) && !args[0]) { 26 | if (client.queue.get(message.guild.id).songs[0]) { 27 | if (!message.guild.me.voice.channel) { 28 | if (message.member.voice.channel.id !== client.queue.get(message.guild.id).voicechannel.id) client.queue.get(message.guild.id).voicechannel = message.member.voice.channel; 29 | client.queue.get(message.guild.id).connection = await message.member.voice.channel.join(); 30 | } 31 | return play(client.queue.get(message.guild.id).songs[0], client.queue.get(message.guild.id).voicechannel); 32 | } 33 | } 34 | if (ytdl.validateURL(args[0])) { 35 | const queue = client.queue.get(message.guild.id); 36 | if (!message.guild.me.voice.channelID) { 37 | joiningmsg = await message.reply(`Joining ${channel.toString()}!`, { allowedMentions: { repliedUser: false } }); 38 | connection = await channel.join(); 39 | connection.channel = channel; 40 | } 41 | else if (!queue) { 42 | channel.guild.me.voice.connection.disconnect(); 43 | connection = await channel.join(); 44 | connection.channel = channel; 45 | } 46 | 47 | const songInfo = await ytdl.getInfo(args[0]); 48 | const artist = !songInfo.videoDetails.media.artist ? songInfo.videoDetails.author.name : songInfo.videoDetails.media.artist; 49 | const album = !songInfo.videoDetails.media.album ? 'None' : songInfo.videoDetails.media.album; 50 | const song = { 51 | title: songInfo.videoDetails.title, 52 | url: songInfo.videoDetails.video_url, 53 | duration: (songInfo.videoDetails.lengthSeconds / 60).toFixed(2), 54 | rawDuration: songInfo.videoDetails.lengthSeconds, 55 | thumbnail: songInfo.player_response.videoDetails.thumbnail.thumbnails[0].url, 56 | uploaded: `${(new Date(Date.now() - new Date(songInfo.videoDetails.publishDate.split('-')[0], songInfo.videoDetails.publishDate.split('-')[1], songInfo.videoDetails.publishDate.split('-')[2]).getTime()) / 31536000000).toFixed(0).startsWith('0') ? (new Date(Date.now() - new Date(songInfo.videoDetails.publishDate.split('-')[0], songInfo.videoDetails.publishDate.split('-')[1], songInfo.videoDetails.publishDate.split('-')[2]).getTime()) / 31536000000).toFixed(0) : (new Date(Date.now() - new Date(songInfo.videoDetails.publishDate.split('-')[0], songInfo.videoDetails.publishDate.split('-')[1], songInfo.videoDetails.publishDate.split('-')[2]).getTime()) / 86400000).toFixed(0)} days(s) ago`, 57 | views: String(songInfo.videoDetails.viewCount).padStart(10, ' '), 58 | requestedBy: message.author, 59 | artist: artist, 60 | album: album, 61 | skippedSec: 0, 62 | }; 63 | if (!queue) { 64 | const basequeue = { 65 | voicechannel: channel, 66 | textchannel: message.channel, 67 | connection: connection, 68 | playing: true, 69 | loop: false, 70 | songs: [], 71 | }; 72 | basequeue.songs.push(song); 73 | client.queue.set(message.guild.id, basequeue); 74 | play(song, basequeue.voicechannel); 75 | } 76 | else if (queue) { 77 | queue.songs.push(song); 78 | const playembed = new Discord.MessageEmbed() 79 | .setTitle('Song added to queue!') 80 | .setDescription(result.title) 81 | .addFields( 82 | { name: 'URL', value: `[${song.title}](${song.url})`, inline: true }, 83 | { name: 'Type', value: 'Song', inline: true }, 84 | { name: 'Video duration', value: `${song.duration}`, inline: true }, 85 | { name: 'Song added by', value: `${message.author.toString()}`, inline: true }, 86 | { name: 'Song By', value: `${result.author.name}`, inline: true }, 87 | { name: 'Album', value: `${album}`, inline: true }, 88 | ) 89 | .setColor('RANDOM') 90 | .setFooter(`Uploaded ${queue.songs[0].uploaded} | ${song.views.toString().replace(/\B(? { 180 | voicechannel.client.queue.delete(voicechannel.guild.id); 181 | return voicechannel.leave(); 182 | }, 5000); 183 | } 184 | if (!voicechannel.guild.me.voice.channel || !voicechannel.guild.me.voice.channelID) { 185 | await queue.voicechannel.join(); 186 | } 187 | const stream = ytdl(song.url, { filter: 'audioonly' }); 188 | queue.connection.play(stream, { seek: 0, volume: 0.5 }) 189 | .on('finish', () => { 190 | const played = queue.songs.shift(); 191 | if (queue.loop) queue.songs.push(played); 192 | play(queue.songs[0], voicechannel); 193 | }); 194 | const playembed = new Discord.MessageEmbed() 195 | .setTitle('Started playing!') 196 | .setDescription(queue.songs[0].title) 197 | .addFields( 198 | { name: 'URL', value: `[${queue.songs[0].title}](${queue.songs[0].url})`, inline: true }, 199 | { name: 'Type', value: queue.songs[0].type || 'video', inline: true }, 200 | { name: 'Video duration', value: `${queue.songs[0].duration}`, inline: true }, 201 | { name: 'Song added by', value: `${song.requestedBy.toString()}`, inline: true }, 202 | { name: 'Song By', value: `${queue.songs[0].artist}`, inline: true }, 203 | { name: 'Album', value: `${queue.songs[0].album}`, inline: true }, 204 | ) 205 | .setColor('RANDOM') 206 | .setFooter(`Uploaded ${queue.songs[0].uploaded} | ${queue.songs[0].views.toString().replace(/\B(?