From 7860aab0e878ef021571f5ba1c368fd0310634ce Mon Sep 17 00:00:00 2001 From: Noah Pombas Date: Thu, 13 Feb 2025 04:42:11 +0100 Subject: [PATCH] Added more Commands --- .env | 2 +- README.md | 69 -------------- commands/admin/add.js | 45 +++++++++ commands/admin/ban.js | 92 ++++++++++++++++++ commands/admin/banlist.js | 49 ++++++++++ commands/admin/clear.js | 92 ++++++++++++++++++ commands/admin/lock.js | 30 ++++++ .../moveuser.js => admin/mover-membro.js} | 45 +++++---- commands/admin/remove.js | 44 +++++++++ commands/admin/say.js | 94 +++++++++++++++++++ commands/admin/unban.js | 48 ++++++++++ commands/admin/unlock.js | 34 +++++++ commands/moderation/ban.js | 55 ----------- commands/public/server-info.js | 42 +++++++++ commands/public/user-info.js | 36 +++++++ events/client/interactionCreate.js | 36 +++---- events/client/messageCreate.js | 35 ------- events/client/ready.js | 37 ++------ handler/index.js | 28 +++--- index.js | 11 ++- package.json | 13 ++- 21 files changed, 684 insertions(+), 253 deletions(-) delete mode 100644 README.md create mode 100644 commands/admin/add.js create mode 100644 commands/admin/ban.js create mode 100644 commands/admin/banlist.js create mode 100644 commands/admin/clear.js create mode 100644 commands/admin/lock.js rename commands/{moderation/moveuser.js => admin/mover-membro.js} (57%) create mode 100644 commands/admin/remove.js create mode 100644 commands/admin/say.js create mode 100644 commands/admin/unban.js create mode 100644 commands/admin/unlock.js delete mode 100644 commands/moderation/ban.js create mode 100644 commands/public/server-info.js create mode 100644 commands/public/user-info.js delete mode 100644 events/client/messageCreate.js diff --git a/.env b/.env index 09204b0..8289d04 100644 --- a/.env +++ b/.env @@ -1 +1 @@ -token=yourtoken \ No newline at end of file +TOKEN=your_discord_token \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 0c6879e..0000000 --- a/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# πŸ€– User-Friendly Discord Bot - Working in Progress - -Welcome to the **User-Friendly Discord Bot**! 🌟 - -This bot is designed to enhance your Discord experience with easy-to-use commands, moderation tools, and more! Whether you're managing a community or just want some fun commands, this bot has you covered! - -### ✨ Features -- **πŸ› οΈ Moderation Commands:** Tools to help manage your server effectively. -- **πŸ‘₯ User-Friendly Commands:** Simple and intuitive commands for all users. - -### πŸ’» Technologies -- **Node.js:** The backbone of the bot, providing a robust runtime environment. -- **Discord.js:** A powerful library for interacting with the Discord API. -- **dotenv:** For managing environment variables securely. -- **JavaScript:** The core language for logic and command handling. - -### 🎯 Purpose -This project was created to practice coding skills while providing a valuable tool for Discord communities. Feel free to explore, give feedback, or contribute! - -## πŸš€ About Me -πŸ‘‹ Hi there! I'm Noah Pombas, a 14-year-old aspiring developer and tech enthusiast from Switzerland. My journey into coding began with a curiosity about technology, which quickly evolved into a passion for creating and problem-solving. - -I’m currently diving into various programming languages and tools, with a strong interest in web development and bot creation. I love tackling new challenges and learning something new every day. - -On this GitHub, you'll find a collection of my projects, experiments, and contributions as I continue to grow my skills. Whether it's a web app or a Discord bot, I’m always looking to push my creative boundaries. - -When I'm not coding, you can find me exploring the outdoors, playing video games, or experimenting with new tech gadgets. - -Feel free to check out my projects, provide feedback, or connect with me at [portfolio.noahpombas.ch](https://portfolio.noahpombas.ch). I'm excited to be part of the coding community and can't wait to see where this journey takes me! - -πŸš€ Let’s build something amazing together! - -## πŸ”— Links -[![Check it out](https://img.shields.io/badge/Visit-Bot_Repo-blue?style=for-the-badge)](https://github.com/noahpombas-dev/discord-bot) - -[![Portfolio](https://img.shields.io/badge/my_portfolio-000?style=for-the-badge&logo=ko-fi&logoColor=white)](https://portfolio.noahpombas.ch/) - -## Support -Need help? Send an email to [info@noahpombas.ch](mailto:info@noahpombas.ch). - -## License -[![MIT License](https://img.shields.io/badge/License-MIT-green.svg)](https://choosealicense.com/licenses/mit/) - - -## FAQ - -#### Does it work without being hosted on a server? -No! You will need to run it on your local machine or a server to have it active in your Discord server. - -#### How do I add the bot to my Discord server? -To add the bot, you need to generate an invite link using your bot's client ID and the necessary permissions. You can find detailed instructions in the Discord Developer Portal. - -#### How can I report issues or request features? -You can report issues or suggest features by opening an issue on the GitHub repository. Please provide as much detail as possible! - -#### Is there a way to contribute to the bot? -Definitely! Contributions are welcome! Feel free to fork the repository, make changes, and submit a pull request. - -#### What if I encounter bugs? -If you find any bugs, please report them on the GitHub issues page. Include steps to reproduce the issue, and I'll do my best to address it. - -#### How often will the bot be updated? -Updates will be made regularly as new features are developed and bugs are fixed. Check the repository for the latest changes! - -#### Can I use this bot for multiple servers? -Yes! You can run multiple instances of the bot or use it in different servers by adding it to each one separately. - -#### Do I need any programming knowledge to use this bot? -Basic understanding of JavaScript and Node.js will help you set up and customize the bot, but the default features are ready to use out of the box. diff --git a/commands/admin/add.js b/commands/admin/add.js new file mode 100644 index 0000000..a74669f --- /dev/null +++ b/commands/admin/add.js @@ -0,0 +1,45 @@ +const Discord = require("discord.js"); +module.exports = { + name: 'add', + description: 'Give a user permissions to see the actual channel.', + options: [ + { + name: "user", + description: "Select User!", + type: Discord.ApplicationCommandOptionType.User, + required: true + }, + + ], + + run: async(client, interaction) => { + let nopermissionembed = new Discord.EmbedBuilder() + .setTitle("**Permission Error**") + .setDescription(` + **Discord BOT** + + + 🚫 Access Denied! 🚫 + + + ${interaction.user} + `) + .setAuthor({ name: `${interaction.user.username}`, iconURL: `${interaction.user.displayAvatarURL()}`}) + .setColor("Red") + + if(!interaction.member.permissions.has(Discord.PermissionsBitField.Flags.Administrator)) { + interaction.reply({embeds: [nopermissionembed], ephemeral: true}) + } else { + let user = interaction.options.getUser("user"); + + interaction.channel.permissionOverwrites.edit(user.id, { ViewChannel: true }); + + let embed = new Discord.EmbedBuilder() + .setTitle("Tickets") + .setDescription(`${user} foi adicionado ao Ticket!`); + + interaction.reply({content: `FEITO!`, ephemeral: true}) + interaction.channel.send({embeds: [embed]}) + } + } +} \ No newline at end of file diff --git a/commands/admin/ban.js b/commands/admin/ban.js new file mode 100644 index 0000000..9fba2d5 --- /dev/null +++ b/commands/admin/ban.js @@ -0,0 +1,92 @@ +const Discord = require("discord.js"); +module.exports = { + name: 'ban', + description: '[ 🚫 Ban ] Ban User', + options: [ + { + name: "user", + description: "Select an user", + type: Discord.ApplicationCommandOptionType.User, + required: true + }, + { + name: "reason", + description: "Ban Reason", + type: Discord.ApplicationCommandOptionType.String, + required: true + } + ], + + run: async(client, interaction) => { + let nopermission = new Discord.EmbedBuilder() + .setColor('Red') + .setTitle('Command Error!') + .setDescription(` + **Discord BOT** + + 🚫 Access Denied! 🚫 + + + ${interaction.user}`); + + if (!interaction.member.permissions.has(Discord.PermissionsBitField.Flags.BanMembers)) { + interaction.reply({embeds: [nopermission], ephemeral: true}) + } else { + let member = interaction.options.getUser("user"); + let reason = interaction.options.getString("reason"); + let staff = interaction.user.displayName + + let userInv = new Discord.EmbedBuilder() + .setColor('Red') + .setTitle("Ban Failed") + .setDescription(`**Invalid User | Please insert a valid User.**`) + .setTimestamp(new Date()); + if (!member) + return interaction.reply({ embeds: [userInv], ephemeral: true }); + + let banreply = new Discord.EmbedBuilder() + .setColor('Red') + .setTitle(`**New Ban**`) + .setDescription(`**${member} was banned successfully \n Reason: ${reason}**`) + .setFooter({ text: `Responsible: ${staff}`, iconURL: interaction.user.displayAvatarURL({ format: "png" }) }) + .setTimestamp(new Date()) + + + let errban = new Discord.EmbedBuilder() + .setColor('DarkRed') + .setTitle('Ban Failed') + .setDescription(`Error while banning ${member.user}`) + .setTimestamp(new Date()); + + + try { + if(!member){ + return; + } else { + + + + + if(member.bot){ + interaction.guild.bans.create(member, {reason}); + interaction.reply({ embeds: [banreply], ephemeral: true }) + } else { + setTimeout(() => { + interaction.guild.bans.create(member, {reason}); + interaction.reply({ embeds: [banreply], ephemeral: true }) + + }, 1000); + } + } + + } + + catch (err) { + if (err) { + interaction.reply({ embeds: [errban], ephemeral: true }); + } + } + + } + } +} \ No newline at end of file diff --git a/commands/admin/banlist.js b/commands/admin/banlist.js new file mode 100644 index 0000000..72bc187 --- /dev/null +++ b/commands/admin/banlist.js @@ -0,0 +1,49 @@ +const Discord = require("discord.js"); +module.exports = { + name: 'banlist', + description: '[ 🚫 Banlist ] See all Banned users.', + + run: async(client, interaction) => { + let nopermissionembed = new Discord.EmbedBuilder() + .setTitle("**Erro de PermissΓ£o**") + .setDescription(` + **Discord BOT** + + + 🚫 Access Denied! 🚫 + + + ${interaction.user} + `) + .setAuthor({ name: `${interaction.user.username}`, iconURL: `${interaction.user.displayAvatarURL()}`}) + .setColor("Red") + + if(!interaction.member.permissions.has(Discord.PermissionsBitField.Flags.BanMembers)) { + interaction.reply({embeds: [nopermissionembed], ephemeral: true}) + } else { + let fetchBans = interaction.guild.bans.fetch() + let banMembers = (await fetchBans).map((member) => "<@" + member.user + ">" + " | ID " + member.user.id).join("\n") + + let noBannedMembers = new Discord.EmbedBuilder() + .setDescription("**No Bans...**") + .setTimestamp(new Date()) + .setColor("Red") + .setAuthor({ name: `${interaction.user.username}`, iconURL: `${interaction.user.displayAvatarURL()}`}); + + if(!banMembers) return interaction.reply({embeds: [noBannedMembers], ephemeral: true}) + + let BannedMembers = new Discord.EmbedBuilder() + .setColor("Yellow") + .setDescription(`${banMembers} + + *You need the User ID to unban someone.* + See all IDs on /banlist + Unban a user using /unban (user id) + `) + .setTimestamp(new Date()) + .setAuthor({ name: `${interaction.user.tag}`, iconURL: `${interaction.user.displayAvatarURL()}`}); + + interaction.reply({ embeds: [BannedMembers], ephemeral: true }) + } + } +} \ No newline at end of file diff --git a/commands/admin/clear.js b/commands/admin/clear.js new file mode 100644 index 0000000..6f0dd8d --- /dev/null +++ b/commands/admin/clear.js @@ -0,0 +1,92 @@ +const Discord = require("discord.js"); +module.exports = { + name: 'clear', + description: '[ 🧹 Clear ] Delete 1-100 Messages', + options: [ + { + name: "quantity", + description: "1-100 Number of Messages you want to delete!", + type: Discord.ApplicationCommandOptionType.String, + required: true + }, + ], + + run: async(client, interaction) => { + let noPermission = new Discord.EmbedBuilder() + .setColor('Red') + .setTitle('Permission Error!') + .setDescription(` + **Dicord BOT** + + Access denied for this command! + + ${interaction.user}`); + + if (!interaction.member.permissions.has(Discord.PermissionsBitField.Flags.ManageMessages)) { + interaction.reply({embeds: [noPermission], ephemeral: true}) + } else { + let quantity = interaction.options.getString("quantity"); + + if(parseInt(quantity) > 100 || parseInt(quantity) <= 0){ + let invalidQuantity = new Discord.EmbedBuilder() + .setColor('Red') + .setTitle("Invalid Quantity!") + .setDescription(` + **Dicord BOT** + + 🚫 Please enter a number between 1 and 100! 🚫 + + + ${interaction.user}`); + + await interaction.reply({embeds: [invalidQuantity], ephemeral: true}) + } else { + interaction.channel.bulkDelete(parseInt(quantity)) + + if(quantity < 1){ + const message = "1 message has been successfully deleted!" + + let clearEmbed = new Discord.EmbedBuilder() + .setColor('Green') + .setTitle("Message Cleaner") + .setAuthor({name: interaction.guild.name, iconURL: interaction.guild.iconURL({ dynamic: true }) }) + .setDescription(` + **Dicord BOT** + + βœ… ${message} βœ… + + + ${interaction.user}`) + + interaction.reply({embeds: [clearEmbed]}); + } else { + const message = `${quantity} messages have been successfully deleted!` + + let clearEmbed = new Discord.EmbedBuilder() + .setColor('Green') + .setTitle("Message Cleaner") + .setAuthor({name: interaction.guild.name, iconURL: interaction.guild.iconURL({ dynamic: true }) }) + .setDescription(` + **Discord BOT** + + βœ… ${message} βœ… + + + ${interaction.user}`) + + interaction.reply({embeds: [clearEmbed]}); + } + + let deleteMessage = "yes" + + if(deleteMessage === "yes"){ + setTimeout(() => { + interaction.deleteReply() + }, 2500); + } else if(deleteMessage === "no"){ + return; + } + } + } + } +} diff --git a/commands/admin/lock.js b/commands/admin/lock.js new file mode 100644 index 0000000..14270e6 --- /dev/null +++ b/commands/admin/lock.js @@ -0,0 +1,30 @@ +const Discord = require("discord.js") + +module.exports = { + name: "lock", + description: "Lock a Channel", + type: Discord.ApplicationCommandType.ChatInput, + + run: async (client, interaction, args) => { + if (!interaction.member.permissions.has("MANAGE_CHANNELS")) { + interaction.reply(` + **Dicord BOT** + + 🚫 Access denied for this command! 🚫 + + ${interaction.user}`) + } else { + let embed = new Discord.EmbedBuilder() + .setTitle("Channel locked.") + .setColor('Blue') + .addFields() + interaction.reply({ embeds: [embed] }).then(msg => { + interaction.channel.permissionOverwrites.edit(interaction.guild.id, { SendMessages: false }).catch(e => { + console.log(e) + interaction.editReply(`Oops, something went wrong while trying to lock this chat.`) + }) + }) + + } + } +} diff --git a/commands/moderation/moveuser.js b/commands/admin/mover-membro.js similarity index 57% rename from commands/moderation/moveuser.js rename to commands/admin/mover-membro.js index f5a3d5a..5d8bf57 100644 --- a/commands/moderation/moveuser.js +++ b/commands/admin/mover-membro.js @@ -2,41 +2,43 @@ const Discord = require("discord.js"); module.exports = { name: "move-user", - description: "[ 🧹 Mover Members ] Move a member from a voice channel to another.", + description: "[ 🧹 Move Members ] Moves a member from one voice channel to another.", type: Discord.ApplicationCommandType.ChatInput, options: [ { name: "channel", - description: "The new Channel you want to move the User.", + description: "Choose a voice channel.", channelTypes: [ Discord.ChannelType.GuildVoice ], type: Discord.ApplicationCommandOptionType.Channel, - required: true, + required: false, }, { name: "member", description: "Choose a member", type: Discord.ApplicationCommandOptionType.User, - required: true, + required: false, }, ], run: async (client, interaction) => { if (!interaction.member.permissions.has(Discord.PermissionFlagsBits.MoveMembers)) - return interaction.reply({ content: `**Error: Permission Denied!**`, ephemeral: true }) + return interaction.reply({ content: `**❌ - You do not have permission to use this command!**`, ephemeral: true }) - let channel = interaction.options.getChannel("channel") let user = interaction.options.getUser("member") + let voiceChannel = interaction.options.getChannel("channel") + if (!user) user = interaction.user + if (!voiceChannel) voiceChannel = interaction.member.voice.channel let member = interaction.guild.members.cache.get(user.id) if (!member) - return interaction.reply({ content: `**Error: Member not found**`, ephemeral: true }) + return interaction.reply({ content: `**❌ - I couldn't find this member, please try again!**`, ephemeral: true }) if (!member.voice.channel) - return interaction.reply({ content: `**Error: This member is not in a voice channel**`, ephemeral: true }) + return interaction.reply({ content: `**❌ - This member is not in a voice channel!**`, ephemeral: true }) try { @@ -44,47 +46,42 @@ module.exports = { await interaction.deferReply({}) let embedVoice = new Discord.EmbedBuilder() - .setAuthor({ name: `Admin: ${interaction.user.username}`, iconURL: interaction.user.displayAvatarURL() }) + .setAuthor({ name: `Requested by: ${interaction.user.username}`, iconURL: interaction.user.displayAvatarURL() }) .setColor("Green") .setFooter({ text: `Member moved: ${member.user.username}`, iconURL: member.user.displayAvatarURL() }) .setTimestamp() + .setURL(`https://discord.com/channels/${interaction.guild.id}/${voiceChannel.id}`) .setTitle("🧹 - Member Moved!") .setThumbnail(interaction.guild.iconURL({ dynamic: true, extension: 'png' })) + .setDescription("*βœ… - The member was successfully moved!*") .setFields( { name: "πŸŽ™ - Voice Channel:", - value: `*${channel}*`, + value: `*${voiceChannel}*`, inline: true }, { - name: "πŸ†” - Voice Chanel ID:", - value: `*${channel.id}*`, + name: "πŸ†” - Voice Channel ID:", + value: `*${voiceChannel.id}*`, inline: true }, - { - name: " ", - value: ` `, - inline: false - }, { name: "πŸ‘€ - Moved Member:", value: `*${member}*`, inline: true }, { - name: "πŸ†” - Moved member ID:", + name: "πŸ†” - Moved Member ID:", value: `*${member.id}*`, inline: true } ) await interaction.editReply({ embeds: [embedVoice] }) - member.voice.setChannel(channel) + member.voice.setChannel(voiceChannel) - } catch (err) { - interaction.editReply({ content: `**Error: Something didn't work...** ${err}`, ephemeral: true }) + } catch { + interaction.editReply({ content: `**❌ - Something went wrong...**`, ephemeral: true }) } - - } -} \ No newline at end of file +} diff --git a/commands/admin/remove.js b/commands/admin/remove.js new file mode 100644 index 0000000..606866e --- /dev/null +++ b/commands/admin/remove.js @@ -0,0 +1,44 @@ +const Discord = require("discord.js"); +module.exports = { + name: 'remove', + description: '[ remove ] Remove someone from the ticket!', + options: [ + { + name: "user", + description: "Select the user you want to remove from the ticket!", + type: Discord.ApplicationCommandOptionType.User, + required: true + }, + ], + + run: async(client, interaction) => { + let noPermissionEmbed = new Discord.EmbedBuilder() + .setTitle("**Permission Error**") + .setDescription(` + **Discord BOT** + + + 🚫 Access denied for this command! 🚫 + + + ${interaction.user} + `) + .setAuthor({ name: `${interaction.user.username}`, iconURL: `${interaction.user.displayAvatarURL()}`}) + .setColor("Red") + + if(!interaction.member.permissions.has(Discord.PermissionsBitField.Flags.Administrator)) { + interaction.reply({embeds: [noPermissionEmbed], ephemeral: true}) + } else { + let user = interaction.options.getUser("user"); + + interaction.channel.permissionOverwrites.edit(user.id, { ViewChannel: false }); + + let embed = new Discord.EmbedBuilder() + .setTitle("Tickets") + .setDescription(`${user} has been removed from the ticket!`); + + interaction.reply({content: `DONE!`, ephemeral: true}) + interaction.channel.send({embeds: [embed]}) + } + } +} diff --git a/commands/admin/say.js b/commands/admin/say.js new file mode 100644 index 0000000..3afa147 --- /dev/null +++ b/commands/admin/say.js @@ -0,0 +1,94 @@ +const Discord = require("discord.js"); +module.exports = { + name: 'say', + description: '[ πŸ’­ Say ] Send a message in an Embed', + options: [ + { + name: "channel", + description: "Select the channel where you want to send the Embed message!", + type: Discord.ApplicationCommandOptionType.Channel, + channelTypes: [ + Discord.ChannelType.GuildText, + Discord.ChannelType.GuildAnnouncement, + ], + required: true + }, + ], + + run: async(client, interaction) => { + let noPermissionEmbed = new Discord.EmbedBuilder() + .setTitle("**Permission Error**") + .setDescription(` + **Discord BOT** + + + 🚫 Access denied for this command! 🚫 + + + ${interaction.user} + `) + .setAuthor({ name: `${interaction.user.username}`, iconURL: `${interaction.user.displayAvatarURL()}`}) + .setColor("Red") + + if(!interaction.member.permissions.has(Discord.PermissionsBitField.Flags.Administrator)) { + interaction.reply({embeds: [noPermissionEmbed], ephemeral: true}) + } else { + let channel = await interaction.options.getChannel("channel"); + + // Modal + const modal = new Discord.ModalBuilder() + .setCustomId("modalsay") + .setTitle("Embed Say") + + // Modal: Create Inputs + const titleInput = new Discord.TextInputBuilder() + .setCustomId("titleInput") + .setLabel("Embed Title") + .setStyle(Discord.TextInputStyle.Short) + + const descriptionInput = new Discord.TextInputBuilder() + .setCustomId("descriptionInput") + .setLabel("Embed Description") + .setStyle(Discord.TextInputStyle.Paragraph) + .setRequired() + + const colorInput = new Discord.TextInputBuilder() + .setCustomId("colorInput") + .setLabel("Embed Color") + .setStyle(Discord.TextInputStyle.Short) + + // Modal: Add Inputs to Modal + const titleRow = new Discord.ActionRowBuilder().addComponents(titleInput) + const descriptionRow = new Discord.ActionRowBuilder().addComponents(descriptionInput) + const colorRow = new Discord.ActionRowBuilder().addComponents(colorInput) + + modal.addComponents(titleRow, descriptionRow, colorRow) + + await interaction.showModal(modal) + + client.once("interactionCreate", async (interaction) => { + if(!interaction.isModalSubmit()) return; + if (interaction.customId === 'modalsay') { + + // SEND MODAL + const titleEmbed = interaction.fields.getTextInputValue("titleInput") + const descriptionEmbed = interaction.fields.getTextInputValue("descriptionInput") + const colorEmbed = interaction.fields.getTextInputValue("colorInput") + + const embed = new Discord.EmbedBuilder() + .setColor(`${colorEmbed}`) + .setTitle(`${titleEmbed}`) + .setDescription(`${descriptionEmbed}`) + .setThumbnail(interaction.guild.iconURL()) + .setTimestamp() + .setFooter({text: `${interaction.guild.name}`, iconURL: `${interaction.guild.iconURL()}`}); + + await channel.send({embeds: [embed]}); + await interaction.reply({content: `Message successfully sent! ${channel}`, ephemeral: true}); + + // END SEND MODAL + } + }) + } + } +} diff --git a/commands/admin/unban.js b/commands/admin/unban.js new file mode 100644 index 0000000..a1679d8 --- /dev/null +++ b/commands/admin/unban.js @@ -0,0 +1,48 @@ +const Discord = require("discord.js"); +module.exports = { + name: 'unban', + description: '[ 🚫 Unban ] Unban a Player', + options: [ + { + name: "user", + description: "User you want to unban", + type: Discord.ApplicationCommandOptionType.User, + required: true + }, + ], + + run: async(client, interaction) => { + let noPermission = new Discord.EmbedBuilder() + .setColor('Red') + .setTitle('Permission Error!') + .setDescription(` + **Discord BOT** + + Access denied for this command! + + + ${interaction.user}`); + + if (!interaction.member.permissions.has(Discord.PermissionsBitField.Flags.BanMembers)) { + interaction.reply({embeds: [noPermission], ephemeral: true}) + } else { + let staff = interaction.user.displayName + + let user = interaction.options.getUser("user") + + let unbanSuccess = new Discord.EmbedBuilder() + .setColor('Yellow') + .setDescription(`**${user} has been unbanned from the server by ${staff}!**`) + .setFooter({text: `Responsible: ${staff}`, iconURL: interaction.user.displayAvatarURL({ format: "png" }) }) + .setTimestamp(new Date()) + + + interaction.guild.members.unban(user).then(async () => { + + + const channel = await interaction.guild.channels.fetch(logchannelunbans) + await interaction.reply({embeds: [unbanSuccess], ephemeral: true}) + }) + } + } +} diff --git a/commands/admin/unlock.js b/commands/admin/unlock.js new file mode 100644 index 0000000..3e2202c --- /dev/null +++ b/commands/admin/unlock.js @@ -0,0 +1,34 @@ +const Discord = require("discord.js"); + +module.exports = { + name: "unlock", + description: "Unlock a Locked Channel", + type: Discord.ApplicationCommandType.ChatInput, + + run: async (client, interaction) => { + if (!interaction.member.permissions.has(Discord.PermissionsBitField.Flags.ManageChannels)) { + interaction.reply(` + **Discord BOT** + + 🚫 Access denied for this command! 🚫 + + + ${interaction.user}`); + } else { + let unlockEmbed = new Discord.EmbedBuilder() + .setTitle("<:happy:1033518052177887323> Channel Unlocked!") + .addFields({ + name: `This channel has been unlocked, everyone can type again.`, + value: `<:emoji_9:1033560781314342962> Unlocked by: ${interaction.user}` + }) + .setColor('Blue'); + + interaction.reply({ embeds: [unlockEmbed] }).then(msg => { + interaction.channel.permissionOverwrites.edit(interaction.guild.id, { SendMessages: true }).catch(e => { + console.log(e); + msg.edit(`Oops, something went wrong while trying to unlock this chat.`); + }); + }); + } + } +}; diff --git a/commands/moderation/ban.js b/commands/moderation/ban.js deleted file mode 100644 index d8bd58c..0000000 --- a/commands/moderation/ban.js +++ /dev/null @@ -1,55 +0,0 @@ -const Discord = require("discord.js") - -module.exports = { - name: "ban", - description: `Ban a User`, - type: Discord.ApplicationCommandType.ChatInput, - options: [ - { - name: "user", - description: "mention the user that you want to ban", - type: Discord.ApplicationCommandOptionType.User, - required: true - - }, - { - name: "reason", - description: "Ban reason!", - type: Discord.ApplicationCommandOptionType.String - }, - ], - run: async (client, interaction) => { - - let user = interaction.options.getUser("user"); - let reason = interaction.options.getString("reason"); - let member = await interaction.guild.members.fetch(user.id) - let banmessage; - if(reason == "" || reason == null){ - reason = "Ban Hammer has spoken!" - } - - - - const banEmbed = new Discord.EmbedBuilder() - .setColor('#ff0000') // Red color for bans - .setTitle(`User Banned: ${user.username}#${user.discriminator}`) - .setThumbnail(user.displayAvatarURL({ dynamic: true, size: 1024 })) - .addFields( - { name: 'User ID', value: user.id, inline: true }, - { name: 'Account Created', value: user.createdAt.toDateString(), inline: true }, - { name: 'Joined Server', value: member.joinedAt.toDateString(), inline: true }, - { name: 'Roles', value: member.roles.cache.size > 0 ? member.roles.cache.map(role => role.name).join(', ') : 'No Roles', inline: true }, - { name: 'Status', value: user.presence?.status || 'offline', inline: true }, - { name: 'Activity', value: user.presence?.activities.length ? user.presence.activities[0].name : 'None', inline: true }, - { name: 'Banned by', value: `${interaction.user.username}#${interaction.user.discriminator}`, inline: true }, - { name: 'Ban Reason', value: reason, inline: true } - ) - .setFooter({ text: `Action performed on ${new Date().toLocaleDateString()}`, iconURL: interaction.user.displayAvatarURL() }) - .setTimestamp(); - - - - interaction.reply({content: `${user}`, embeds: [banEmbed], ephemeral: true}) - console.log(`OlΓ‘ ${interaction.user}`) - } -} \ No newline at end of file diff --git a/commands/public/server-info.js b/commands/public/server-info.js new file mode 100644 index 0000000..e388e5c --- /dev/null +++ b/commands/public/server-info.js @@ -0,0 +1,42 @@ +const Discord = require("discord.js"); +module.exports = { + name: 'server-info', + description: 'Information about the server', + + run: async(client, interaction) => { + const { guild } = interaction + const { members } = guild + const { name, ownerId, createdTimestamp, memberCount } = guild + const icon = guild.iconURL() + const roles = guild.roles.cache.size + const emojis = guild.emojis.cache.size + const id = guild.id + + let baseVerify = guild.VerificationLevel + + if(baseVerify == 0) baseVerify = "None" + if(baseVerify == 1) baseVerify = "Low" + if(baseVerify == 2) baseVerify = "Medium" + if(baseVerify == 3) baseVerify = "High" + if(baseVerify == 4) baseVerify = "Very High" + + const embed = new Discord.EmbedBuilder() + .setColor("Aqua") + .setThumbnail(icon) + .setAuthor({ name: name, iconURL: icon}) + .setFooter({ text: `Server ID: ${id}` }) + .setTimestamp() + .addFields({ name: "Name", value: `${name}`, inline: false}) + .addFields({ name: "Criation Date", value: ``, inline: true}) + .addFields({ name: "CEO:", value: `<@${ownerId}>`, inline: true}) + .addFields({ name: "Members:", value: `${memberCount}`, inline: true}) + .addFields({ name: "Roles:", value: `${roles}`, inline: true}) + .addFields({ name: "Emojis:", value: `${emojis}`, inline: true}) + .addFields({ name: "Boosts:", value: `${guild.premiumSubscriptionCount}`, inline: true}) + + interaction.reply({embeds: [embed], ephemeral: true}) + + + } + +} \ No newline at end of file diff --git a/commands/public/user-info.js b/commands/public/user-info.js new file mode 100644 index 0000000..b7e7376 --- /dev/null +++ b/commands/public/user-info.js @@ -0,0 +1,36 @@ +const Discord = require("discord.js"); +module.exports = { + name: 'user-info', + description: 'Information about a user', + options: [ + { + name: "user", + description: "Enter a user.", + type: Discord.ApplicationCommandOptionType.User, + required: true, + }, + ], + + run: async(client, interaction) => { + const user = interaction.options.getUser('user') + const member = await interaction.guild.members.fetch(user.id) + const icon = user.displayAvatarURL() + const tag = user.tag + + const embed = new Discord.EmbedBuilder() + .setTitle(`Informations about ${user.username}`) + .setColor("Aqua") + .setAuthor({ name: tag, iconURl: icon}) + .setThumbnail(icon) + .addFields({ name: "User", value: `${user}`, inline: false}) + .addFields({ name: "Roles", value: `${member.roles.cache.map(r => r).join(' ')}`, inline: false}) + .addFields({ name: "Joined Server", value: ``, inline: true}) + .addFields({ name: "Account Created", value: ``, inline: true}) + .setFooter({ text: `User ID: ${user.id}`}) + .setTimestamp() + + + interaction.reply({embeds: [embed], ephemeral: true}) + } +} + diff --git a/events/client/interactionCreate.js b/events/client/interactionCreate.js index 4d7f64c..b5459b3 100644 --- a/events/client/interactionCreate.js +++ b/events/client/interactionCreate.js @@ -1,39 +1,39 @@ -const {InteractionType} = require("discord.js") +const { InteractionType } = require('discord.js'); module.exports = { name: 'interactionCreate', - /** - * @param {CommandInteraction} interaction - * @param {Client} client + /** + * @param {CommandInteraction} interaction + * @param {Client} client */ + async execute(interaction, client) { - if (interaction.type !== InteractionType.ApplicationCommand) return; - + const command = client.slash.get(interaction.commandName); - if (!command) return interaction.reply({ content: `Command doesn't exist!`, ephemeral: true }); - - if (command.ownerOnly) { - if (interaction.user.id !== client.config.ownerID) { - return interaction.reply({ content: `Permission Denied`, ephemeral: true }); + if (!command) return interaction.reply({content: `❌ Error processing this command.`, ephemeral: true }); + + if(command.ownerOnly) { + if(interaction.user.id !== client.config.ownerID) { + return interaction.reply({content: `❌ Permission denied`, ephemeral: true }) } } - + const args = []; - + for (let option of interaction.options.data) { if (option.type === 'SUB_COMMAND') { - if (option.name) args.push(option.name); + if(option.name) args.push(option.name); option.options?.forEach(x => { - if (x.value) args.push(x.value); + if(x.value) args.push(x.value); }); } else if (option.value) args.push(option.value); } - + try { command.run(client, interaction, args) - } catch (e) { - interaction.reply({ content: e.message }); + } catch (error) { + interaction.reply({ content: error.message }) } } } \ No newline at end of file diff --git a/events/client/messageCreate.js b/events/client/messageCreate.js deleted file mode 100644 index d6cce8a..0000000 --- a/events/client/messageCreate.js +++ /dev/null @@ -1,35 +0,0 @@ -module.exports = { - name: 'messageCreate', - - /** - * @param {Message} message - * @param {Client} client - */ - async execute(message, client) { - if (message.author.bot || !message.guild || !message.content.toLowerCase().startsWith(client.config.botPrefix)) return; - const [cmd, ...args] = message.content.slice(client.config.botPrefix.length).trim().split(" "); - const command = client.commands.get(cmd.toLowerCase()) || client.commands.find(c => c.aliases?.includes(cmd.toLowerCase())); - - //Se quiser que o bot nΓ£o retorne nada caso o comando nΓ£o existe - //if (!command) { return } - - //Se quiser que o bot retorne alguma mensagem - if (!command) { - return message.reply({ content: `:x: **|** Comando nΓ£o encontrado` }) - } - - //Se quiser que o bot nΓ£o retorne nada ao usar um comando apenas para dev - /*if (command.ownerOnly) { - if (message.author.id !== client.config.ownerID) { return } - }*/ - - //se quiser que o bot retorne alguma mensagem - if (command.ownerOnly) { - if (message.author.id !== client.config.ownerID) { - return message.reply({ content: `:x: **|** Apenas meu criador pode usar esse comando!` }) - } - } - - await command.run(client, message, args); - } -} \ No newline at end of file diff --git a/events/client/ready.js b/events/client/ready.js index 0de280b..fcb5655 100644 --- a/events/client/ready.js +++ b/events/client/ready.js @@ -1,32 +1,15 @@ -const client = require("../../index"); -const { ActivityType } = require('discord.js') -const chalk = require("chalk"); -const { joinVoiceChannel } = require("@discordjs/voice"); -const Discord = require('discord.js') +const Discord = require('discord.js'); +const chalk = require('chalk'); module.exports = { - name: 'ready', - once: true, - - /** - * @param {Client} client - */ - async execute(client) { - - let status = [ - `by info@noahpombas.ch`, - `Spoiler: novo Servidor de Minecraft brevemente` - ], - i = 0 - setInterval(() => { - client.user.setActivity(`${status[i++ % status.length]}`, { - type: ActivityType.Streaming - }) - }, 5000); + name: 'ready', + once: true, + /** @param {Client} client */ + async execute(client) { + client.setMaxListeners(0); - - console.log(chalk.blueBright(`[READY] Bot Online!`)); - } -} + console.log(chalk.blueBright(`${client.user.username} is Online and inside ${client.guilds.cache.size} servers!`)); + } +} \ No newline at end of file diff --git a/handler/index.js b/handler/index.js index cd47078..256a008 100644 --- a/handler/index.js +++ b/handler/index.js @@ -1,7 +1,7 @@ const fs = require("node:fs"); const chalk = require("chalk"); -//Carregar eventos +// Load Events const loadEvents = async function (client) { const eventFolders = fs.readdirSync("./events"); for (const folder of eventFolders) { @@ -12,14 +12,14 @@ const loadEvents = async function (client) { for (const file of eventFiles) { const event = require(`../events/${folder}/${file}`); - if (event.name) { - console.log(chalk.greenBright(` βœ”οΈ => ${file} Event loaded.`)); + if(event.name) { + console.log(chalk.greenBright(`βœ… => ${file} Event loaded.`)); } else { - console.log(chalk.redBright(` ❌ => ${file} Event not loaded.`)); + console.log(chalk.redBright(`❌ => ${file} Event not loaded.`)) continue; } - if (event.once) { + if(event.once) { client.once(event.name, (...args) => event.execute(...args, client)); } else { client.on(event.name, (...args) => event.execute(...args, client)); @@ -28,12 +28,11 @@ const loadEvents = async function (client) { } } - -//Carregar slashcommands +// Load Slashcommands const loadSlashCommands = async function (client) { - let slash = [] + let slash = []; - const commandFolders = fs.readdirSync("./commands"); + const commandFolders = fs.readdirSync("./commands") for (const folder of commandFolders) { const commandFiles = fs .readdirSync(`./commands/${folder}`) @@ -42,19 +41,20 @@ const loadSlashCommands = async function (client) { for (const file of commandFiles) { const command = require(`../commands/${folder}/${file}`); - if (command.name) { + if(command.name) { client.slash.set(command.name, command); - slash.push(command) - console.log(chalk.greenBright(` βœ”οΈ => ${file} Command loaded`)); + slash.push(command); + console.log(chalk.greenBright(`βœ… => ${file} Slashcommand loaded.`)) } else { - console.log(chalk.redBright(` ❌ => ${file} Command not loaded`)); + console.log(chalk.redBright(`❌ => ${file} Slashcommand not loaded.`)) continue; } + } } client.on("ready", async () => { - await client.guilds.cache.get("serverid").commands.set(slash); + await client.application.commands.set(slash); }) } diff --git a/index.js b/index.js index 95945dd..a7a5420 100644 --- a/index.js +++ b/index.js @@ -1,14 +1,19 @@ +// ============================================= +// = CONSTANTS = +// ============================================= const Discord = require("discord.js"); const client = new Discord.Client({intents: 32767}); const handler = require("./handler/index"); -require("dotenv").config() +require("dotenv").config(); +client.login(process.env.TOKEN); module.exports = client; client.discord = Discord; - client.slash = new Discord.Collection(); handler.loadEvents(client); handler.loadSlashCommands(client); -client.login(process.env.token); +process.on("uncaughtException", function (err) { + console.log("CRASH", err); +}); \ No newline at end of file diff --git a/package.json b/package.json index 8cbb88a..53632df 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,17 @@ { - "name": "project-bot", + "name": "github", "version": "1.0.0", - "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, - "author": "noahpombas.ch", + "keywords": [], + "author": "", "license": "ISC", + "description": "", "dependencies": { - "@discordjs/voice": "^0.16.1", "chalk": "^4.1.2", - "discord.js": "^14.12.1", - "dotenv": "^16.4.5", - "nodemon": "^3.1.7" + "discord.js": "^14.18.0", + "dotenv": "^16.4.7" } }