Вопрос или проблема
Есть ли способ настроить моего бота так, чтобы он поддерживал как слэш-команды Discord, так и префикс моего бота без headaches
В данный момент мой бот работает с префиксом ; или с любым другим префиксом, установленным в гильдии, мой обработчик команд выглядит так:
const foldersPath = path.join(__dirname, "commands");
try {
const commandFolders = fs.readdirSync(foldersPath);
client.commands = new Map();
// Проходим по папкам с командами и файлам, чтобы заполнить client.commands
for (const folder of commandFolders) {
const commandsPath = path.join(foldersPath, folder);
try {
const commandFiles = fs.readdirSync(commandsPath).filter((file) => file.endsWith(".js"));
for (const file of commandFiles) {
const filePath = path.join(commandsPath, file);
try {
const command = require(filePath);
// Устанавливаем новый элемент в коллекцию с ключом как имя команды и значением как экспортируемый модуль
if ("data" in command && "execute" in command) {
client.commands.set(command.data.name, command);
// Добавляем псевдонимы в коллекцию команд
if (command.data.aliases && Array.isArray(command.data.aliases)) {
command.data.aliases.forEach((alias) => {
client.commands.set(alias, command);
});
}
} else {
console.log(`[WARNING] Команда в ${filePath} не имеет обязательного свойства "data" или "execute".`);
}
} catch (err) {
console.error(`[ERROR] Не удалось загрузить команду из файла: ${filePath}`, err);
}
}
} catch (err) {
console.error(`[ERROR] Не удалось прочитать команды в папке: ${commandsPath}`, err);
}
}
} catch (err) {
console.error(`[ERROR] Не удалось прочитать папки команд из: ${foldersPath}`, err);
}
Довольно запутано и мусорное, но работает, мне интересно, могу ли я как-то изменить это, чтобы каждая команда также поддерживала слэш-команды
Ответ или решение
Краткое содержание: Вы хотите добавить поддержку как префиксных команд, так и слэш-команд для вашего бота на Discord с использованием bibliотеки Discord.js. В данном ответе мы расскажем о том, как это можно реализовать, и предоставим примеры кода для совершенствования вашего текущего подхода.
Введение
Интеграция как префиксных команд, так и слэш-команд в Discord-бота — это отличная идея, которая может значительно улучшить пользовательский опыт. Слэш-команды предоставляют пользователям интуитивно понятный интерфейс, позволяя им выбрать команды из выпадающего меню, тогда как префиксные команды могут быть предпочтительны для опытных пользователей. Наша задача — сделать поддержкой обеих опций без лишних усилий.
Подход
-
Структурирование команд: Используя вашу текущую архитектуру команд, мы можем добавить функционал слэш-команд. Вам нужно будет определить команды как объекты, содержащие как информацию о слэш-команде, так и о префиксной команде.
-
Регистрация команд: После этого необходимо будет зарегистрировать слэш-команды в каждом сервере (гильдии) при инициализации бота.
-
Обработка входящих сообщений: Вам нужно будет настроить обработку событий как для сообщений, так и для взаимодействий с слэш-командами.
Пример кода
Вот как это можно сделать, основываясь на вашей текущей логике:
const { Client, Intents, REST, Routes } = require('discord.js');
const fs = require('fs');
const path = require('path');
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
// Регистрация слэш-команд
const deployCommands = async () => {
const commands = [];
const foldersPath = path.join(__dirname, "commands");
const commandFolders = fs.readdirSync(foldersPath);
for (const folder of commandFolders) {
const commandsPath = path.join(foldersPath, folder);
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith(".js"));
for (const file of commandFiles) {
const filePath = path.join(commandsPath, file);
const command = require(filePath);
if ('data' in command) {
commands.push(command.data.toJSON());
}
}
}
const rest = new REST({ version: '9' }).setToken('YOUR_BOT_TOKEN');
try {
console.log('Начинаем регистрацию команд...');
await rest.put(Routes.applicationGuildCommands('YOUR_CLIENT_ID', 'YOUR_GUILD_ID'), { body: commands });
console.log('Команды успешно зарегистрированы!');
} catch (error) {
console.error(error);
}
};
client.once('ready', async () => {
console.log(`Вход в как ${client.user.tag}`);
await deployCommands();
});
// Обработка префиксных команд
client.on('messageCreate', (message) => {
if (!message.content.startsWith(';') || message.author.bot) return;
const args = message.content.slice(1).trim().split(/ +/);
const commandName = args.shift().toLowerCase();
const command = client.commands.get(commandName);
if (command) {
command.execute(message, args);
}
});
// Обработка слэш-команд
client.on('interactionCreate', async (interaction) => {
if (!interaction.isCommand()) return;
const command = client.commands.get(interaction.commandName);
if (command) {
await command.execute(interaction);
}
});
// Загрузка команд
const loadCommands = () => {
const foldersPath = path.join(__dirname, "commands");
const commandFolders = fs.readdirSync(foldersPath);
client.commands = new Map();
for (const folder of commandFolders) {
const commandsPath = path.join(foldersPath, folder);
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith(".js"));
for (const file of commandFiles) {
const filePath = path.join(commandsPath, folder, file);
const command = require(filePath);
if ('data' in command && 'execute' in command) {
client.commands.set(command.data.name, command);
}
}
}
};
// Инициализация
loadCommands();
client.login('YOUR_BOT_TOKEN');
Заключение
Таким образом, мы разработали систему, которая поддерживает как префиксные команды, так и слэш-команды. При правильной настройке это принесет вашему Discord-боту гибкость и удобство использования. Постепенно вы сможете улучшить и оптимизировать вашу архитектуру команд, а также адаптировать функционал под ваши потребности. Используйте предоставленный код как отправную точку и модифицируйте его в зависимости от ваших требований.