diff --git a/src/discord/Interaction.ts b/src/discord/Interaction.ts deleted file mode 100644 index 071304b..0000000 --- a/src/discord/Interaction.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Message } from "discord.js"; -import { makeInfoEmbed, makeErrorEmbed, makeSuccessEmbed, makeProcessingEmbed, sendMessage, sendReply } from "../utils/DiscordMessage"; -import DiscordProvider from "../providers/Discord"; -import {registerAllGuildsCommands, unregisterAllGuildsCommands} from "../utils/DiscordInteraction"; -import Prisma from "../providers/Prisma"; - -export default class Interaction { - async onCommand(command: string, args: any, message: Message) { - if(command.toLowerCase() !== 'interaction') return; - - if(!message.guildId) return; - if(message.member === null) return; - if(message.guild === null) return; - - // TODO: Add dev check - - if(args.length === 0) - return await sendReply(message, { - embeds: [makeInfoEmbed ({ - title: 'Interaction', - description: `Manage interaction`, - fields: [ - { - name: 'Available arguments', - value: '``reloadAll``' - } - ], - user: message.author - })] - }); - else { - if(args[0].toLowerCase() === "reloadall") { - try { - await unregisterAllGuildsCommands(); - await registerAllGuildsCommands(); - return await sendReply(message, { - embeds: [makeSuccessEmbed ({ - title: 'Reloaded all Interaction', - user: message.author - })] - }); - } catch (err) { - return await sendReply(message, { - embeds: [makeErrorEmbed ({ - title: 'An error occurred while trying to reload interaction', - description: '```' + err + '```', - user: message.author - })] - }); - } - } - } - } -} \ No newline at end of file diff --git a/src/discord/InteractionManager.ts b/src/discord/InteractionManager.ts new file mode 100644 index 0000000..3dc0b63 --- /dev/null +++ b/src/discord/InteractionManager.ts @@ -0,0 +1,142 @@ +import { Message, Interaction, CommandInteraction } from "discord.js"; +import { makeInfoEmbed, makeErrorEmbed, makeSuccessEmbed, makeProcessingEmbed, sendMessageOrInteractionResponse, sendReply } from "../utils/DiscordMessage"; +import DiscordProvider from "../providers/Discord"; +import {registerAllGuildsCommands, unregisterAllGuildsCommands} from "../utils/DiscordInteraction"; +import Prisma from "../providers/Prisma"; +import Users from "../services/Users"; + +const EMBEDS = { + INTERACTION_INFO: (data: Message | Interaction) => { + return makeInfoEmbed({ + title: 'Interaction', + description: `This module contains management tool for interaction based contents`, + fields: [ + { + name: 'Available arguments', + value: '``reloadAll``' + } + ], + user: (data instanceof Interaction) ? data.user : data.author + }); + }, + PROCESSING: (data: Message | Interaction) => { + return makeProcessingEmbed({ + icon: (data instanceof Message) ? undefined : '⌛', + title: `Performing actions`, + user: (data instanceof Interaction) ? data.user : data.author + }); + }, + NOT_DEVELOPER: (data: Message | Interaction) => { + return makeErrorEmbed({ + title: 'Developer only', + description: `This command is restricted to the developers only`, + user: (data instanceof Interaction) ? data.user : data.author + }); + }, + RELOADALL_SUCCESS: (data: Message | Interaction) => { + return makeSuccessEmbed({ + title: 'Reloaded all Interaction', + user: (data instanceof Interaction) ? data.user : data.author + }); + }, + RELOADALL_ERROR: (data: Message | Interaction, err: any) => { + return makeErrorEmbed ({ + title: 'An error occurred while trying to reload interaction', + description: '```' + err + '```', + user: (data instanceof Interaction) ? data.user : data.author + }) + } +} + +export default class InteractionManager { + async onCommand(command: string, args: any, message: Message) { + if(command.toLowerCase() !== 'interaction') return; + await this.process(message, args); + } + + async interactionCreate(interaction: CommandInteraction) { + if(interaction.isCommand()) { + if(typeof interaction.commandName === 'undefined') return; + if((interaction.commandName).toLowerCase() !== 'interaction') return; + await this.process(interaction, interaction.options); + } + } + + async process(data: Interaction | Message, args: any) { + const isSlashCommand = data instanceof CommandInteraction && data.isCommand(); + const isMessage = data instanceof Message; + + if(!isSlashCommand && !isMessage) return; + + if(!Users.isDeveloper(data.member?.user.id!)) + return await sendMessageOrInteractionResponse(data, { embeds:[EMBEDS.NOT_DEVELOPER(data)] }); + + const funct = { + reloadAll: async(data: Message | Interaction) => { + let placeholder = await sendMessageOrInteractionResponse(data, { embeds: [EMBEDS.PROCESSING(data)] }); + try { + await unregisterAllGuildsCommands(); + await registerAllGuildsCommands(); + if(isMessage) + return (placeholder as Message).edit({ embeds: [EMBEDS.RELOADALL_SUCCESS(data)] }); + else if(isSlashCommand) + return await sendMessageOrInteractionResponse(data, { embeds: [EMBEDS.RELOADALL_SUCCESS(data)]}, true); + } catch (err) { + if(isMessage) + (placeholder as Message).edit({ embeds: [EMBEDS.RELOADALL_ERROR(data, err)] }); + else if(isSlashCommand) + return await sendMessageOrInteractionResponse(data, { embeds: [EMBEDS.RELOADALL_ERROR(data, err)] }, true); + } + } + } + + let query; + + if(isMessage) { + if(data === null || !data.guildId || data.member === null || data.guild === null) return; + + if(args.length === 0) { + return await sendMessageOrInteractionResponse(data, { embeds: [EMBEDS.INTERACTION_INFO(data)] }); + } + query = args[0].toLowerCase(); + + } + else if(isSlashCommand) { + query = args.getSubcommand(); + } + + switch(query) { + case "info": + return await sendMessageOrInteractionResponse(data, { embeds: [EMBEDS.INTERACTION_INFO(data)] }); + case "reloadall": + return await funct.reloadAll(data); + } + + } +} + + +export class AInteractionManager { + async onCommand(command: string, args: any, message: Message) { + if(command.toLowerCase() !== 'interaction') return; + + if(!message.guildId) return; + if(message.member === null) return; + if(message.guild === null) return; + + // TODO: Add dev check + + if(args.length === 0) + return await sendReply(message, { + embeds: [makeInfoEmbed ({ + + user: message.author + })] + }); + else { + if(args[0].toLowerCase() === "reloadall") { + + } + } + } +} \ No newline at end of file diff --git a/src/providers/Discord.ts b/src/providers/Discord.ts index bf28f38..de20ea2 100644 --- a/src/providers/Discord.ts +++ b/src/providers/Discord.ts @@ -8,7 +8,7 @@ import Discord_Ping from "../discord/Ping"; import Discord_Help from "../discord/Help"; import Discord_Invite from "../discord/Invite"; import Discord_Say from "../discord/Say"; -import Discord_Interaction from "../discord/Interaction"; +import Discord_InteractionManager from "../discord/InteractionManager"; import Discord_MembershipScreening from "../discord/MembershipScreening"; import Cache from "./Cache"; @@ -35,7 +35,7 @@ class Discord { this.loaded_module["Ping"] = new Discord_Ping(); this.loaded_module["Discord_Help"] = new Discord_Help(); this.loaded_module["Discord_Invite"] = new Discord_Invite(); - this.loaded_module["Discord_Interaction"] = new Discord_Interaction(); + this.loaded_module["Discord_InteractionManager"] = new Discord_InteractionManager(); this.loaded_module["Discord_Say"] = new Discord_Say(); this.loaded_module["MembershipScreening"] = new Discord_MembershipScreening(); diff --git a/src/utils/DiscordInteraction.ts b/src/utils/DiscordInteraction.ts index 233c102..92eeb24 100644 --- a/src/utils/DiscordInteraction.ts +++ b/src/utils/DiscordInteraction.ts @@ -7,9 +7,18 @@ export const GLOBAL_COMMANDS: Object[] = []; export const GUILD_COMMANDS: Object[] = []; -GUILD_COMMANDS.push(new SlashCommandBuilder().setName('help').setDescription('Show help menu').toJSON()); -GUILD_COMMANDS.push(new SlashCommandBuilder().setName('ping').setDescription('Measure network latency').toJSON()); -GUILD_COMMANDS.push(new SlashCommandBuilder().setName('invite').setDescription('Invite me to your server!').toJSON()); +GUILD_COMMANDS.push(new SlashCommandBuilder() + .setName('help') + .setDescription('Show help menu') +); +GUILD_COMMANDS.push(new SlashCommandBuilder() + .setName('ping') + .setDescription('Measure network latency') +); +GUILD_COMMANDS.push(new SlashCommandBuilder() + .setName('invite') + .setDescription('Invite me to your server!') +); GUILD_COMMANDS.push(new SlashCommandBuilder() .setName('say') .setDescription('Make me say something') @@ -19,39 +28,54 @@ GUILD_COMMANDS.push(new SlashCommandBuilder() .setRequired(true) ) ); - +GUILD_COMMANDS.push(new SlashCommandBuilder() + .setName('interaction') + .setDescription('[Developer Only] Manage interaction') + .addSubcommand(info => info + .setName('info') + .setDescription('[Developer Only] Interaction modules information') + ) + .addSubcommand(reloadAll => reloadAll + .setName('reloadall') + .setDescription('[Developer Only] Reload interaction for global and all guilds') + ) +); GUILD_COMMANDS.push(new SlashCommandBuilder() .setName('membershipscreening') .setDescription('Membership screening') + .addSubcommand(info => info + .setName('info') + .setDescription('Show more information for membership screening') + ) .addSubcommand(enable => enable .setName('enable') - .setDescription('Enable Membership screening') + .setDescription('Enable membership screening') ) .addSubcommand(enable => enable .setName('disable') - .setDescription('Disable Membership screening') + .setDescription('Disable membership screening') ) .addSubcommand(setrole => setrole .setName('setrole') - .setDescription('Configure role of Membership screening') + .setDescription('Set a role that user will be granted when approved to join') .addRoleOption(option => option .setName('role') - .setDescription('Role to give to user') + .setDescription('Select a role that user will be granted when approved to join') .setRequired(true) ) ) .addSubcommand(setchannel => setchannel .setName('setchannel') - .setDescription('Configure channel of Membership screening') + .setDescription('Set channel where membership screening approval request will be sent') .addChannelOption(option => option .setName('channel') - .setDescription('Channel to send request to') + .setDescription('Select a channel where approval request will be sent') .setRequired(true) ) ) .addSubcommand(createmessage => createmessage .setName('createmessage') - .setDescription('Create message for Membership screening') + .setDescription('Create greeting message for membership screening into the channel. A message for new commers to read') ) ); @@ -61,15 +85,16 @@ export const registerAllGlobalCommands = async () => { } export const unregisterAllGlobalCommands = async () => { - const commands = await DiscordProvider.client.application?.commands.fetch(); + //const commands = await DiscordProvider.client.application?.commands.fetch(); - if(typeof commands === 'undefined') return; - if(commands.size === 0) return; + //if(typeof commands === 'undefined') return; + //if(commands.size === 0) return; Logger.log('info', `Unregistering all global interaction commands`); - for(const command of commands) { + await DiscordProvider.client.application?.commands.set([]); + /*for(const command of commands) { await DiscordProvider.client.application?.commands.delete(command[1]); - } + }*/ } @@ -95,17 +120,19 @@ export const unregisterAllGuildsCommands = async () => { if(!guildObject) continue; - const commands = await guildObject.commands.fetch(); - - if(commands.size === 0) continue; - Logger.log('info', `Unregistering all interaction commands on guild ${guildObject.name} (${guildObject.id})`); - for(const command of commands) { + await DiscordProvider.client.guilds.cache.get(guildObject.id)?.commands.set([]); + + //const commands = await guildObject.commands.fetch(); + + //if(commands.size === 0) continue; + /*for(const command of commands) { try { await DiscordProvider.client.guilds.cache.get(guildObject.id)?.commands.delete(command[1]); } catch(err) { Logger.log('error', `Cannot unregister all interaction commands on guild ${guildObject.name} (${guildObject.id})`); } - } + }*/ + } } \ No newline at end of file diff --git a/src/utils/DiscordMessage.ts b/src/utils/DiscordMessage.ts index af9b4bc..1336c26 100644 --- a/src/utils/DiscordMessage.ts +++ b/src/utils/DiscordMessage.ts @@ -86,7 +86,7 @@ export async function sendReply(rMessage: Message, options: string | MessagePayl } -export async function sendMessageOrInteractionResponse(data: Message | Interaction, payload: MessageOptions | InteractionReplyOptions) { +export async function sendMessageOrInteractionResponse(data: Message | Interaction, payload: MessageOptions | InteractionReplyOptions, replace?: boolean) { const isSlashCommand = data instanceof Interaction && data.isCommand(); const isMessage = data instanceof Message; @@ -103,7 +103,12 @@ export async function sendMessageOrInteractionResponse(data: Message | Interacti } else { let message; - try { return await data.followUp(payload); } + try { + if(replace) + return await data.editReply(payload); + else + return await data.followUp(payload); + } catch(errorDM) { Logger.error(`Cannot find available destinations to send the message CID: ${data.channel!.id} UID: ${data.user.id} DM_ERR: ${errorDM}`); return;