├── .gitignore ├── events ├── ready.js ├── interactionCreate.js └── messageCreate.js ├── prefix_commands ├── miscellaneous │ ├── ping.js │ └── deploy.js └── owner │ └── eval.js ├── settings.json ├── slash_commands ├── miscellaneous │ ├── ping.js │ └── userinfo.js └── moderation │ ├── timeout.js │ ├── ban.js │ └── kick.js ├── package.json ├── index.js └── handlers ├── slash_command.js ├── prefix_command.js └── event.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | settings.json 3 | package-lock.json -------------------------------------------------------------------------------- /events/ready.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | run: (client) => { 3 | console.log(`[ ${client.user?.username} ] : Connected to Discord with ${client.ws?.ping} ping!`) 4 | } 5 | } -------------------------------------------------------------------------------- /prefix_commands/miscellaneous/ping.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | description: "Get the websocket ping of the message.", 3 | run: (client, message) => { 4 | return message.channel.send(`🏓 | Ping is \`${client.ws.ping}\` ms.`) 5 | } 6 | } -------------------------------------------------------------------------------- /settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "token": "TOKEN", 3 | "prefix": "?", 4 | "color": { 5 | "positive": "GREEN", 6 | "negative": "RED", 7 | "neutral": "BLUE", 8 | "warn": "YELLOW" 9 | }, 10 | "ownerId": "OWNER ID" 11 | } -------------------------------------------------------------------------------- /slash_commands/miscellaneous/ping.js: -------------------------------------------------------------------------------- 1 | const { SlashCommandBuilder } = require('@discordjs/builders'); 2 | 3 | module.exports = { 4 | data: new SlashCommandBuilder() 5 | .setName("ping") 6 | .setDescription("Replies with pong"), 7 | run: async (client, interaction) => { 8 | await interaction.followUp({ content: `🏓 | Ping is \`${client.ws.ping}\` ms.`}); 9 | }, 10 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "discord-bot-for-starters", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "ascii-table": "^0.0.9", 15 | "discord.js": "^13.1.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /prefix_commands/miscellaneous/deploy.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | description: "Deploy the slash commands in your guild.", 3 | run: async (client, message) => { 4 | if(message.author.id !== message.guild.ownerId) return message.channel.send(`⚔️ | This command can only be used by server owner.`) 5 | await message.guild.commands.set([...client.slash_commands].map(x => x[1].data)) 6 | 7 | return message.channel.send("✅ | Slash commands are deploied.") 8 | } 9 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const { Client, Intents, Collection } = require("discord.js"), 2 | { token, prefix, color, ownerId } = require("./settings.json"), 3 | client = new Client( { intents: [ Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MEMBERS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_PRESENCES ] }) 4 | 5 | client.prefix_commands = new Collection(); 6 | client.slash_commands = new Collection(); 7 | client.aliases = new Collection(); 8 | client.settings = { prefix, color, ownerId } 9 | 10 | for(let handler of ["slash_command", "prefix_command", "event"]) require(`./handlers/${handler}`)(client); 11 | 12 | client.login(token) 13 | -------------------------------------------------------------------------------- /events/interactionCreate.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | run: async (client, interaction) => { 3 | if (!interaction.isCommand()) return; 4 | await interaction.deferReply().catch(err => {}) 5 | 6 | const { commandName } = interaction; 7 | const command = client.slash_commands.get(commandName) 8 | if(!command) return interaction.followUp("Unknown Command: Can not find this command in bot.") 9 | 10 | try { 11 | if(command) await command.run(client, interaction) 12 | } catch (err) { 13 | console.log(err) 14 | return interaction.followUp(`Something went wrong while executing the command.`) 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /prefix_commands/owner/eval.js: -------------------------------------------------------------------------------- 1 | const { codeBlock } = require("@discordjs/builders"); 2 | 3 | module.exports = { 4 | ownerOnly: true, 5 | run: async (client, message, args) => { 6 | /* Join all arguments back to string */ 7 | const content = args.join(" ") 8 | /* Promisify the eval */ 9 | let output = await new Promise((resolve, reject) => resolve(eval(content))); 10 | 11 | /* If output is not a string */ 12 | if (typeof output !== "string") { 13 | /* convert it to string */ 14 | output = require("util").inspect(output, { depth: 0 }); 15 | } 16 | 17 | /* Send the output */ 18 | message.channel.send({ 19 | content: codeBlock('js', output) 20 | }); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /handlers/slash_command.js: -------------------------------------------------------------------------------- 1 | const { readdirSync } = require("fs"), 2 | ascii = require("ascii-table"); 3 | 4 | let table = new ascii("Commands"); 5 | table.setHeading("Slash Commands", "Load status"); 6 | 7 | module.exports = (client) => { 8 | readdirSync("./slash_commands").forEach(dir => { 9 | const commands = readdirSync(`./slash_commands/${dir}/`).filter(file => file.endsWith(".js")); 10 | 11 | for (let file of commands) { 12 | let pull = require(`../slash_commands/${dir}/${file}`); 13 | 14 | client.slash_commands.set(pull.data.name, pull); 15 | table.addRow(file, '✅'); 16 | 17 | if (pull.aliases && Array.isArray(pull.aliases)) pull.aliases.forEach(alias => client.aliases.set(alias, pull.name)); 18 | } 19 | }); 20 | // Log the table 21 | console.log(table.toString()); 22 | } -------------------------------------------------------------------------------- /handlers/prefix_command.js: -------------------------------------------------------------------------------- 1 | const { readdirSync } = require("fs"), 2 | ascii = require("ascii-table"); 3 | 4 | let table = new ascii("Commands"); 5 | table.setHeading("Prefix Command", "Load status"); 6 | 7 | module.exports = (client) => { 8 | readdirSync("./prefix_commands").forEach(dir => { 9 | const commands = readdirSync(`./prefix_commands/${dir}/`).filter(file => file.endsWith(".js")); 10 | 11 | for (let file of commands) { 12 | let pull = require(`../prefix_commands/${dir}/${file}`); 13 | pull.name = file.replace(".js", "") 14 | pull.category = dir 15 | client.prefix_commands.set(pull.name, pull); 16 | table.addRow(file, '✅'); 17 | 18 | if (pull.aliases && Array.isArray(pull.aliases)) pull.aliases.forEach(alias => client.aliases.set(alias, pull.name)); 19 | } 20 | }); 21 | // Log the table 22 | console.log(table.toString()); 23 | } -------------------------------------------------------------------------------- /handlers/event.js: -------------------------------------------------------------------------------- 1 | const { readdirSync } = require("fs"), 2 | ascii = require("ascii-table"); 3 | 4 | let table = new ascii("Events"); 5 | table.setHeading("Events", "Load status"); 6 | 7 | module.exports = (client) => { 8 | const commands = readdirSync("./events").filter(file => file.endsWith(".js")); 9 | for (let file of commands) { 10 | 11 | try { 12 | let pull = require(`../events/${file}`); 13 | if (pull.event && typeof pull.event !== "string") { 14 | table.addRow(file, `❌ -> Property event should be string.`); 15 | continue; 16 | } 17 | 18 | pull.event = pull.event || file.replace(".js", "") 19 | client.on(pull.event, pull.run.bind(null, client)) 20 | table.addRow(file, '✅'); 21 | 22 | } catch(err) { 23 | console.log("Error While loading/executing command, join for help : https://withwin.in/dbd") 24 | console.log(err) 25 | table.addRow(file, `❌ -> Error while loading event, join for help : https://withwin.in/dbd`); 26 | } 27 | } 28 | 29 | console.log(table.toString()); 30 | } -------------------------------------------------------------------------------- /events/messageCreate.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | run: (client, message) => { 3 | if(message.author.bot || !message.guild || !message.content.startsWith(client.settings.prefix)) return; 4 | const args = message.content.slice(client.settings.prefix.length).trim().split(/ +/g); 5 | const cmd = args.shift().toLowerCase(); 6 | 7 | let command = client.prefix_commands.get(cmd) 8 | if (!command) command = client.prefix_commands.get(client.aliases.get(cmd)); 9 | if(!command) return; 10 | 11 | if (command.botPermissions) { 12 | const Permissions = command.botPermissions.filter(x => !message.guild.me.permissions.has(x)).map(x => "`" + x + "`") 13 | if (Permissions.length) return message.channel.send(`I need ${Permissions.join(", ")} permission(s) to execute the command!`) 14 | } 15 | 16 | if (command.memberPermissions) { 17 | const Permissions = command.memberPermissions.filter(x => !message.member.permissions.has(x)).map(x => "`" + x + "`") 18 | if (Permissions.length) return message.channel.send(`You need ${Permissions.join(", ")} permission(s) to execute this command!`) 19 | } 20 | 21 | if (command.ownerOnly) { 22 | if (message.author.id !== client.settings.ownerId) return message.channel.send("This command can only be use by owner :C") 23 | } 24 | 25 | command.run(client, message, args) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /slash_commands/moderation/timeout.js: -------------------------------------------------------------------------------- 1 | const { SlashCommandBuilder } = require('@discordjs/builders'); 2 | const ms = require("ms") 3 | 4 | module.exports = { 5 | data: new SlashCommandBuilder() 6 | .setName("timeout") 7 | .setDescription("Put member in timeout.") 8 | .addUserOption((option) => option.setName("member").setDescription('Person who you want to put in timeout.').setRequired(true)) 9 | .addStringOption((option) => option.setName("time").setDescription('For how much time you want to timeout member').setRequired(true)) 10 | .addStringOption((option) => option.setName("reason").setDescription('Reason to put member in timeout')), 11 | run: async (client, interaction) => { 12 | 13 | if(!interaction.member.permissions.has("ADMINISTRATOR")) return interaction.followUp({ content: "You do not have permission to use this command." }); 14 | 15 | const member = interaction.options.getMember('member') 16 | const reason = interaction.options.getString('reason') || null 17 | const time = ms(interaction.options.getString('time')) 18 | 19 | if(!time) return interaction.followUp({ content: "Given time is not valid, it is necessary that you provide valid time."}) 20 | const response = await member.timeout(time, reason) 21 | 22 | if(!response) return interaction.followUp({ content: "I am sorry but for some reason I am unable to timeout this member."}) 23 | return interaction.followUp({ content: `${member} has been timed out for ${ms(time, { long: true })}`}) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /slash_commands/miscellaneous/userinfo.js: -------------------------------------------------------------------------------- 1 | const { SlashCommandBuilder } = require('@discordjs/builders'); 2 | const { MessageEmbed } = require("discord.js") 3 | 4 | module.exports = { 5 | data: new SlashCommandBuilder() 6 | .setName("userinfo") 7 | .setDescription("Retrive the information of a server member.") 8 | .addUserOption(option => option.setName("member").setDescription("The memeber whose details you want.")), 9 | run: async (client, interaction) => { 10 | const member = interaction.options.getMember("member") || interaction.member 11 | const activities = member.presence?.activities || [] 12 | 13 | const focusActivity = activities.find(x => x.assets) 14 | const embed = new MessageEmbed() 15 | .setAuthor(member.user.tag, member.user.displayAvatarURL()) 16 | .setColor(member.displayHexColor === "#000000" ? "#ffffff" : member.displayHexColor) 17 | .setThumbnail(focusActivity ? `https://cdn.discordapp.com/app-assets/${focusActivity.applicationId}/${focusActivity.assets.largeImage}` : member.user.displayAvatarURL()) 18 | .setDescription(activities.map((x, i) => `**${x.type}**: \`${x.name || "None"} : ${x.details || "None"} : ${x.state || "None"}\``).join("\n")) 19 | .addField("JoinedAt", member.joinedAt.toLocaleString(), true) 20 | .addField("Account Created At", member.user.createdAt.toLocaleString(), true) 21 | .addField("Common Information", [ 22 | `Display Name: \`${member.displayName}\``, 23 | `Pending Member: \`${member.pending ? 'Yes' : 'No'}\``, 24 | `Booster: \`${member.premiumSince ? 'since ' + member.premiumSince.toLocaleString() : 'Nope'}\`` 25 | ].join("\n")) 26 | 27 | return interaction.followUp({ embeds: [embed] }) 28 | }, 29 | }; 30 | -------------------------------------------------------------------------------- /slash_commands/moderation/ban.js: -------------------------------------------------------------------------------- 1 | const { SlashCommandBuilder } = require('@discordjs/builders'); 2 | const { MessageEmbed } = require("discord.js") 3 | 4 | module.exports = { 5 | data: new SlashCommandBuilder() 6 | .setName("ban") 7 | .setDescription("Allows the admin or owner to ban the member.") 8 | .addUserOption((option) => option.setName('user').setDescription('The person who you want to ban').setRequired(true)) 9 | .addStringOption(option => option.setName('reason').setDescription('Reason to ban member').setRequired(true)), 10 | run: async (client, interaction) => { 11 | 12 | if(!interaction.member.permissions.has("BAN_MEMBERS")) return interaction.followUp({ content: "You do not have enough permissions to use this command.", ephemeral: true }) 13 | 14 | const user = interaction.options.getUser('user') 15 | const member = interaction.guild.members.cache.get(user.id) || await interaction.guild.members.fetch(user.id).catch(err => {}) 16 | 17 | if(!member) return interaction.followUp("😅 | Unable to get details related to given member."); 18 | const reason = interaction.options.getString('reason') 19 | 20 | if(!member.bannable || member.user.id === client.user.id) 21 | return interaction.followUp("😅 | I am unable to ban this member"); 22 | 23 | if(interaction.member.roles.highest.position <= member.roles.highest.position) 24 | return interaction.followUp('Given member have higher or equal rank as you so i can not ban them.') 25 | 26 | const embed = new MessageEmbed() 27 | .setDescription(`**${member.user.tag}** is banned from the server for \`${reason}\``) 28 | .setColor("GREEN") 29 | .setFooter("Ban Member") 30 | .setTimestamp() 31 | 32 | await member.user.send(`You are banned from **\`${interaction.guild.name}\`** for \`${reason}\``).catch(err => {}) 33 | member.ban({ reason }) 34 | 35 | return interaction.followUp({ embeds: [ embed ]}) 36 | 37 | }, 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /slash_commands/moderation/kick.js: -------------------------------------------------------------------------------- 1 | const { SlashCommandBuilder } = require('@discordjs/builders'); 2 | const { MessageEmbed } = require("discord.js") 3 | 4 | module.exports = { 5 | data: new SlashCommandBuilder() 6 | .setName("kick") 7 | .setDescription("Allows the admin or owner to kick the member.") 8 | .addUserOption((option) => option.setName('user').setDescription('The person who you want to kick').setRequired(true)) 9 | .addStringOption(option => option.setName('reason').setDescription('Reason to kick member').setRequired(true)), 10 | run: async (client, interaction) => { 11 | 12 | if(!interaction.member.permissions.has("KICK_MEMBERS")) return interaction.followUp({ content: "You do not have enough permissions to use this command.", ephemeral: true }) 13 | 14 | const user = interaction.options.getUser('user') 15 | const member = interaction.guild.members.cache.get(user.id) || await interaction.guild.members.fetch(user.id).catch(err => {}) 16 | 17 | if(!member) return interaction.followUp("😅 | Unable to get details related to given member."); 18 | const reason = interaction.options.getString('reason') 19 | 20 | if(!member.kickable || member.user.id === client.user.id) 21 | return interaction.followUp("😅 | I am unable to kick this member"); 22 | 23 | if(interaction.member.roles.highest.position <= member.roles.highest.position) 24 | return interaction.followUp('Given member have higher or equal rank as you so i can not kick them.') 25 | 26 | const embed = new MessageEmbed() 27 | .setDescription(`**${member.user.tag}** is kicked out from the server for \`${reason}\``) 28 | .setColor("GREEN") 29 | .setFooter("Kick Member") 30 | .setTimestamp() 31 | 32 | await member.user.send(`You are kicked from **\`${interaction.guild.name}\`** for \`${reason}\``).catch(err => {}) 33 | member.kick({ reason }) 34 | 35 | return interaction.followUp({ embeds: [ embed ]}) 36 | 37 | }, 38 | 39 | }; 40 | --------------------------------------------------------------------------------