иметь поддержку slash-команд и префикса в Discord.js боте

Вопрос или проблема

Есть ли способ настроить моего бота так, чтобы он поддерживал как слэш-команды 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-бота — это отличная идея, которая может значительно улучшить пользовательский опыт. Слэш-команды предоставляют пользователям интуитивно понятный интерфейс, позволяя им выбрать команды из выпадающего меню, тогда как префиксные команды могут быть предпочтительны для опытных пользователей. Наша задача — сделать поддержкой обеих опций без лишних усилий.

Подход

  1. Структурирование команд: Используя вашу текущую архитектуру команд, мы можем добавить функционал слэш-команд. Вам нужно будет определить команды как объекты, содержащие как информацию о слэш-команде, так и о префиксной команде.

  2. Регистрация команд: После этого необходимо будет зарегистрировать слэш-команды в каждом сервере (гильдии) при инициализации бота.

  3. Обработка входящих сообщений: Вам нужно будет настроить обработку событий как для сообщений, так и для взаимодействий с слэш-командами.

Пример кода

Вот как это можно сделать, основываясь на вашей текущей логике:

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-боту гибкость и удобство использования. Постепенно вы сможете улучшить и оптимизировать вашу архитектуру команд, а также адаптировать функционал под ваши потребности. Используйте предоставленный код как отправную точку и модифицируйте его в зависимости от ваших требований.

Оцените материал
Добавить комментарий

Капча загружается...