From 6aee8a4c63eb108800fcb0a23ca61f200d8f1f2a Mon Sep 17 00:00:00 2001 From: GramingFoxTeam Date: Wed, 16 Nov 2022 13:20:47 +0300 Subject: [PATCH] feat(discord-bot): command handler and train cmd --- bots/config.example.json | 3 +- bots/discord/commands/trainMessage.js | 35 ++++++++++++++++++++++ bots/discord/index.js | 42 +++++++++++++++++++++++++-- bots/discord/registerCommands.js | 32 ++++++++++++++++++++ client/index.js | 2 +- 5 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 bots/discord/commands/trainMessage.js create mode 100644 bots/discord/registerCommands.js diff --git a/bots/config.example.json b/bots/config.example.json index 26d9847..3ff5e97 100644 --- a/bots/config.example.json +++ b/bots/config.example.json @@ -1,6 +1,7 @@ { "discord": { - "token": "YOUR-BOT-TOKEN-HERE" + "token": "YOUR-BOT-TOKEN-HERE", + "id": "1038762591805247518" }, "server": { diff --git a/bots/discord/commands/trainMessage.js b/bots/discord/commands/trainMessage.js new file mode 100644 index 0000000..4c2558f --- /dev/null +++ b/bots/discord/commands/trainMessage.js @@ -0,0 +1,35 @@ +import { ContextMenuCommandBuilder, ApplicationCommandType, ActionRowBuilder, SelectMenuBuilder, ComponentType } from 'discord.js'; +export default { + data: new ContextMenuCommandBuilder() + .setName('Train Message') + .setType(ApplicationCommandType.Message), + async execute(interaction) { + const options = []; + + for (const { label } of global.config.responses) { + options.push({ + label: label, + description: `The ${label} label.`, + value: label.toLowerCase() + }); + }; + + const row = new ActionRowBuilder() + .addComponents( + new SelectMenuBuilder() + .setCustomId('select') + .setPlaceholder('Nothing selected') + .addOptions(options), + ); + const reply = await interaction.reply({ content: 'Please select the corresponding label to train the bot.', components: [row], ephemeral: true }); + + const collector = reply.createMessageComponentCollector({ componentType: ComponentType.StringSelect, time: 15000 }); + + collector.on('collect', i => { + i.client.helper.sendTrainData(interaction.targetMessage.content, i.values[0].toUpperCase()); + + i.reply({ content: 'Sent train data to server.', ephemeral: true }); + }); + + } +} \ No newline at end of file diff --git a/bots/discord/index.js b/bots/discord/index.js index c804493..bea58f4 100644 --- a/bots/discord/index.js +++ b/bots/discord/index.js @@ -1,9 +1,15 @@ -import { Client, Events, GatewayIntentBits } from 'discord.js'; -import { readFileSync } from 'node:fs'; +import { Client, Events, GatewayIntentBits, Collection } from 'discord.js'; +import { readFileSync, readdirSync } from 'node:fs'; +// Fix __dirname not being defined in ES modules. (https://stackoverflow.com/a/64383997) +import { fileURLToPath } from 'node:url'; +import { dirname, join } from 'node:path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); import HelperClient from '../../client/index.js'; const configJSON = readFileSync('../config.json', 'utf-8'); -const config = JSON.parse(configJSON); +global.config = JSON.parse(configJSON); const helper = new HelperClient(config); @@ -11,12 +17,42 @@ helper.connect(); const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent] }); +client.commands = new Collection(); +client.helper = helper; + +const commandsPath = join(__dirname, 'commands'); +const commandFiles = readdirSync(commandsPath).filter(file => file.endsWith('.js')); + +for (const file of commandFiles) { + const filePath = join(commandsPath, file); + const command = (await import(`file://${filePath}`)).default; + if ('data' in command && 'execute' in command) { + client.commands.set(command.data.name, command); + } else { + console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`); + } +} + client.on(Events.MessageCreate, async (msg) => { helper.scanText(msg.content, `${msg.channelId}/${msg.id}`); }); client.on(Events.InteractionCreate, async (interaction) => { + if (!interaction.isMessageContextMenuCommand()) return; + const command = interaction.client.commands.get(interaction.commandName); + + if (!command) { + console.error(`No command matching ${interaction.commandName} was found.`); + return; + } + + try { + await command.execute(interaction); + } catch (error) { + console.error(error); + await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true }); + } }); // The ReVanced Helper events. diff --git a/bots/discord/registerCommands.js b/bots/discord/registerCommands.js new file mode 100644 index 0000000..a6ddeff --- /dev/null +++ b/bots/discord/registerCommands.js @@ -0,0 +1,32 @@ +import { REST, Routes } from 'discord.js'; +import { readdirSync, readFileSync } from 'node:fs'; +const configJSON = readFileSync('../config.json', 'utf-8'); +const config = JSON.parse(configJSON); + +const commands = []; +// Grab all the command files from the commands directory you created earlier +const commandFiles = readdirSync('./commands').filter(file => file.endsWith('.js')); + +// Grab the SlashCommandBuilder#toJSON() output of each command's data for deployment +for (const file of commandFiles) { + const command = await import(`./commands/${file}`); + commands.push(command.default.data.toJSON()); +} + +// Construct and prepare an instance of the REST module +const rest = new REST({ version: '10' }).setToken(config.discord.token); + +try { + console.log(`Started refreshing ${commands.length} application (/) commands.`); + + // The put method is used to fully refresh all commands in the guild with the current set + const data = await rest.put( + Routes.applicationCommands(config.discord.id), + { body: commands }, + ); + + console.log(`Successfully reloaded ${data.length} application (/) commands.`); +} catch (error) { + // And of course, make sure you catch and log any errors! + console.error(error); +} \ No newline at end of file diff --git a/client/index.js b/client/index.js index 578a823..b7ba77b 100644 --- a/client/index.js +++ b/client/index.js @@ -60,7 +60,7 @@ class HelperClient extends EventEmitter { sendTrainData(text, label) { this.sendData({ - op: 5, + op: 3, label, text });