diff --git a/bot/src/commands/button.js b/bot/src/commands/button.js index 1c11c20..b09dc51 100644 --- a/bot/src/commands/button.js +++ b/bot/src/commands/button.js @@ -20,11 +20,13 @@ export default { }) }, - //run method is called when the command is executed - //To execute this command type !button in the slack channel where the bot is installed - //The paramaters are descructured from the object passed to the run method - //response is used to send the response back to the slack channel - //event is the event object that contains the event details from slack. + /* + run method is called when the command is executed + To execute this command type !button in the slack channel where the bot is installed + The paramaters are descructured from the object passed to the run method + response is used to send the response back to the slack channel + event is the event object that contains the event details from slack. + */ run: ({ response, event }) => { response({ diff --git a/bot/src/index.js b/bot/src/index.js index 4810b37..1638a60 100644 --- a/bot/src/index.js +++ b/bot/src/index.js @@ -17,9 +17,12 @@ const customLogger = { error: (message) => log.error(message), }; -//receiver to integrate express with bolt -//The receiver is what allows Bolt to communicate with Slack's servers. -//The receiver listens for incoming HTTP requests from Slack, and then forwards them to the Bolt app. +/* +receiver to integrate express with bolt +The receiver is what allows Bolt to communicate with Slack's servers. +The receiver listens for incoming HTTP requests from Slack, and then +forwards them to the Bolt app. +*/ const receiver = new ExpressReceiver({ signingSecret: process.env.SIGNING_SECRET, }); diff --git a/command-handler/src/cmd-handler/buttons.js b/command-handler/src/cmd-handler/buttons.js index 2b340be..d1fee66 100644 --- a/command-handler/src/cmd-handler/buttons.js +++ b/command-handler/src/cmd-handler/buttons.js @@ -1,4 +1,14 @@ +/* + This file contains the list of buttons that are registered with the command handler. + This list tells the button handler, which command should handle the button click. + This list contains both regex patterns and static button names. + The static are defined by the programmer while the regex patterns are generated by the command handler. + Each button is a JSON object with the button name as the object name with a key value pair of command + and the command name that should handle the button click. +*/ + const registeredButtons = { + //static buttons that are defined by the programmer button_list_servers: { command: 'vm', }, @@ -8,7 +18,11 @@ const registeredButtons = { button_click: { command: 'button', }, - //regex patterns to match generated buttons + /* + regex patterns to match generated buttons + The regex matches the buttons at the start of the string, + with the trailing _ not being the end of the string in the match + */ "^button_start_": { command: 'vm', isRegex: true, diff --git a/command-handler/src/cmd-handler/command-handler.js b/command-handler/src/cmd-handler/command-handler.js index ef79c03..84b3d42 100644 --- a/command-handler/src/cmd-handler/command-handler.js +++ b/command-handler/src/cmd-handler/command-handler.js @@ -1,3 +1,8 @@ +/* + This file is responsible for handling commands. + It reads all the commands from the commands directory and stores them in a map. +*/ + import path from 'path'; import { fileURLToPath, pathToFileURL } from 'url'; import logger from '../util/logger.js'; @@ -10,49 +15,85 @@ export default class CommandHandler { _commands = new Map(); constructor(commandsDir, handler) { + //throw error if commands directory is not provided if (!commandsDir) throw new Error('Commands directory is required'); + //initialize the command handler + //this function is called because the constructor cannot be async this.init(commandsDir, handler); } + //getter for commands get commands() { return this._commands; } async init(commandsDir, handler) { const registeredCommands = []; + //get all the files in the commands directory const botCommands = getFiles(commandsDir); + //get the current file path and directory const currentFilePath = fileURLToPath(import.meta.url); const currentFileDir = path.dirname(currentFilePath); + //get all the files in the built-in commands directory const builtInCommands = getFiles(path.join(currentFileDir, '..', 'commands')); + //combine the bot commands and built-in commands const commands = [...botCommands, ...builtInCommands]; + //loop through all the commands for (const command of commands) { + //get the command name and file path const commandName = path.basename(command, '.js').toLowerCase(); const filePath = pathToFileURL(command); + //import the command object const commandObject = (await import(filePath)).default; + //warn if the command is empty and continue to the next command if (!commandObject) { log.warn(`Command ${commandName} is empty`); continue; - } + //destructure the command object properties const { aliases = [], delete: del, init = () => {}, } = commandObject; + /* + if del (delete) is true, continue to the next command + skipping the command registration process. This does + not delete the command file from the app, simply does + not register the command with the command handler + */ if (del) { continue; } + /* + call the init function that was destructured + from the command object. Since the init function + is async, we await the function to complete before + continuing. This function is an optional function + that commands can use to run any initialization code + that the command depends on before being registered. + */ await init(handler) + /* + set the command name and object in the commands map + and add the command name to the registered commands array + so the app is aware of the commands that are registered + */ registeredCommands.push(commandName); this._commands.set(commandName, commandObject); + /* + loop through the aliases and set the alias and command object + so commands can be called by their aliases in addition to their + command name. This allows for more flexibility when calling commands + */ for (const alias of aliases) { this._commands.set(alias, commandObject); } diff --git a/command-handler/src/index.js b/command-handler/src/index.js index b9ab5fd..49ad7d4 100644 --- a/command-handler/src/index.js +++ b/command-handler/src/index.js @@ -15,9 +15,11 @@ export default class CommandHandler { // Create a command handler if commands directory is provided if (commandsDir) this._commandHandler = new cmdHandler(commandsDir, app, this); - // Create the command and button event Listeners - // pass the app and this instance of the command handler - // this calls the command and button functions to register the events + /* + Create the command and button event Listeners + pass the app and this instance of the command handler + this calls the command and button functions to register the events + */ command(app, this); button(app, this); }