diff --git a/src/commands/unban.js b/src/commands/unban.js new file mode 100644 index 0000000..ef30b60 --- /dev/null +++ b/src/commands/unban.js @@ -0,0 +1,58 @@ +const { SlashCommandBuilder, PermissionFlagsBits, userMention } = require("discord.js") +const { color } = require("../../config/options.json") + +module.exports = { + name: "unban", + description: "Unban a user from the server", + type: "slash", + dev: true, + + data: new SlashCommandBuilder() + .setName("unban") + .setDescription("Unban a user from the server") + .addStringOption(option => + option + .setName("user") + .setDescription("The user to unban") + .setAutocomplete(true) + .setRequired(true) + ) + .addStringOption(option => + option + .setName("reason") + .setDescription("The reason for unbanning the user") + .setRequired(false) + ), + + /** @param { import("discord.js").ChatInputCommandInteraction } interaction */ + + async execute(interaction) { + await interaction.deferReply() + + const userid = interaction.options.getString("user") + const reason = interaction.options.getString("reason") || "No reason provided" + const mod = interaction.user + const embedColor = Number(color.replace("#", "0x")) + + const user = await interaction.client.users.fetch(userid) + await interaction.guild.members.unban(user.id, reason) + + await interaction.editReply({ + embeds: [{ + title: "User unbanned", + description: "The user " + user.username + " has been unbanned.\n" + + "**Reason:** `" + reason + "`\n" + + "**Moderator:** " + userMention(mod.id), + color: embedColor, + thumbnail: { + url: user?.avatarURL({ dynamic: true }) || null + }, + footer: { + text: "ID: " + user.id, + icon_url: interaction.guild.iconURL({ dynamic: true }) + }, + timestamp: new Date() + }] + }) + } +} diff --git a/src/events/autocomplete/unban.js b/src/events/autocomplete/unban.js new file mode 100644 index 0000000..bf9dae0 --- /dev/null +++ b/src/events/autocomplete/unban.js @@ -0,0 +1,28 @@ +module.exports = { + name: "unban", + description: "Unban a user from the server", + type: "autocomplete", + + /** @param { import("discord.js").AutocompleteInteraction } interaction */ + + async execute(interaction) { + if (!interaction.isAutocomplete()) return + if (interaction.commandName !== "unban") return + const focusedOption = interaction.options.getFocused(true) + if (focusedOption.name !== "user") return + + console.log + + const bannedUsers = await interaction.guild.bans.fetch() + const filteredUsers = bannedUsers.filter((user) => + user.user.username.toLowerCase().includes(focusedOption.value.toLowerCase()) + ) + + const results = filteredUsers.map((user) => ({ + name: user.user.username, + value: user.user.id, + })) + + await interaction.respond(results.slice(0, 25)).catch((err) => { console.log(err) }) + } +} diff --git a/src/index.js b/src/index.js index b72d6d5..b29f3a9 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,5 @@ const { Client, GatewayIntentBits, Partials, Collection } = require("discord.js") -const { loadSlashCommandsEvents, loadContextMenuEvents, loadModalEvents, loadButtonEvents, loadEvents } = require("./utils/eventHandler.js") +const { loadSlashCommandsEvents, loadContextMenuEvents, loadModalEvents, loadButtonEvents, loadEvents, loadAutocompleteEvents } = require("./utils/eventHandler.js") const { autoDeployCommands } = require("./utils/autodeploy.js") require("dotenv").config() const mongoURI = process.env.MONGOURI @@ -27,6 +27,7 @@ client.events = new Collection() client.modals = new Collection() loadSlashCommandsEvents(client) +loadAutocompleteEvents(client) loadContextMenuEvents(client) loadButtonEvents(client) loadModalEvents(client) diff --git a/src/utils/eventHandler.js b/src/utils/eventHandler.js index aac65f3..526250d 100644 --- a/src/utils/eventHandler.js +++ b/src/utils/eventHandler.js @@ -3,11 +3,13 @@ const { loadSlashCommandsEvents } = require("./eventHandlers/command.js") const { loadContextMenuEvents } = require("./eventHandlers/contextmenu.js") const { loadModalEvents } = require("./eventHandlers/modal.js") const { loadEvents } = require("./eventHandlers/events.js") +const { loadAutocompleteEvents } = require("./eventHandlers/autocomplete.js") module.exports = { loadSlashCommandsEvents, loadButtonEvents, loadContextMenuEvents, loadModalEvents, - loadEvents + loadEvents, + loadAutocompleteEvents } diff --git a/src/utils/eventHandlers/autocomplete.js b/src/utils/eventHandlers/autocomplete.js new file mode 100644 index 0000000..8916e14 --- /dev/null +++ b/src/utils/eventHandlers/autocomplete.js @@ -0,0 +1,24 @@ +const { Events } = require("discord.js") +const path = require("path") +const fs = require("fs") + +/** @param { import('discord.js').Client } client */ + +function loadAutocompleteEvents(client) { + const autocompletePath = path.join(__dirname, "..", "..", "events", "autocomplete") + const autocompleteFiles = fs.readdirSync(autocompletePath).filter(file => file.endsWith(".js")) + + for (const file of autocompleteFiles) { + + const filePath = path.join(autocompletePath, file) + const autocomplete = require(filePath) + + if ("name" in autocomplete && "execute" in autocomplete && autocomplete.type === "autocomplete") { + client.on(Events.InteractionCreate, autocomplete.execute) + } else { + console.log(`[WARNING] The autocomplete at ${filePath} is missing a required "name", "execute" or "type" property.`) + } + } +} + +module.exports = { loadAutocompleteEvents }