mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-15 17:12:59 -04:00
112 lines
4.7 KiB
JavaScript
112 lines
4.7 KiB
JavaScript
// Discord Commands Router
|
|
// Purpose: Routes incoming Discord command messages to one-file-per-command handlers.
|
|
// Scope: Central command dispatcher and permission gate orchestration.
|
|
const { formatHelp } = require('./help');
|
|
const { createStatusCommand } = require('./status');
|
|
const { createReplayCommand } = require('./replay');
|
|
const { createLockCommand } = require('./lock');
|
|
const { createModeCommand } = require('./mode');
|
|
const { createReasonCommand } = require('./reason');
|
|
const { createGoalCommand } = require('./goal');
|
|
const { createVerifyCommand } = require('./verify');
|
|
const { createDeterCommand } = require('./deter');
|
|
const { createBridgeCommand } = require('./bridge');
|
|
const { createTimeStatusCommand } = require('./timeStatus');
|
|
const { createLightsCommand } = require('./lights');
|
|
const { createKickCommand } = require('./kick');
|
|
|
|
function createCommandHandlers(deps) {
|
|
const {
|
|
getMode,
|
|
MODES,
|
|
isAdminUser,
|
|
isLockdownAdminUser,
|
|
} = deps;
|
|
|
|
const handleStatusCommand = createStatusCommand(deps);
|
|
const handleReplayCommand = deps.createReplayTextCommand
|
|
? deps.createReplayTextCommand(deps)
|
|
: createReplayCommand(deps);
|
|
const handleLockCommand = createLockCommand(deps);
|
|
const handleModeCommand = createModeCommand(deps);
|
|
const handleReasonCommand = createReasonCommand(deps);
|
|
const handleGoalCommand = createGoalCommand(deps);
|
|
const handleVerifyCommand = createVerifyCommand(deps);
|
|
const handleDeterCommand = createDeterCommand(deps);
|
|
const handleBridgeCommand = createBridgeCommand(deps);
|
|
const handleTimeStatusCommand = createTimeStatusCommand(deps);
|
|
const handleLightsCommand = createLightsCommand(deps);
|
|
const handleKickCommand = createKickCommand(deps);
|
|
|
|
async function handleCommand(message) {
|
|
if (message.author.bot) return;
|
|
const content = (message.content || '').trim();
|
|
const lower = content.toLowerCase();
|
|
// Commands are intentionally matched as whole prefixes. The previous
|
|
// startsWith checks made ordinary messages such as "rsvp" or "tshirt" look
|
|
// like commands, which is especially bad now that web chat will run the
|
|
// same server-side dispatcher before broadcasting user text.
|
|
if (lower === 'ts') return handleTimeStatusCommand(message);
|
|
if (!/^rs(?:\s|$)/i.test(content)) return;
|
|
|
|
const tokens = content.split(/\s+/);
|
|
tokens.shift();
|
|
const action = (tokens.shift() || '').toLowerCase();
|
|
const rest = tokens.join(' ').trim();
|
|
const isAdmin = isAdminUser(message.author.id);
|
|
const isLockdownAdmin = isLockdownAdminUser(message.author.id);
|
|
const mode = getMode();
|
|
// Actions in this set can change operational safety or access policy, so
|
|
// lockdown mode narrows them from normal admins to lockdown admins. Room
|
|
// light locking belongs here because it can force the physical room lights
|
|
// on and disables ordinary Home Assistant room controls for everyone else.
|
|
const moderationActions = new Set(['lock', 'unlock', 'mode', 'goal', 'reason', 'verify', 'deter', 'lights', 'kick']);
|
|
|
|
if (!isAdmin && action !== '' && action !== 'status' && action !== 'help' && action !== 'replay' && action !== 'bridge' && action !== 'goal' && action !== 'reason' && action !== 'verify' && action !== 'deter') {
|
|
await message.reply({ content: 'Only admins can run that command.', allowedMentions: { parse: [], repliedUser: false } });
|
|
return;
|
|
}
|
|
|
|
if (mode === MODES.LOCKDOWN && moderationActions.has(action) && !isLockdownAdmin) {
|
|
await message.reply({ content: 'Lockdown mode: only lockdown admins can run that command.', allowedMentions: { parse: [], repliedUser: false } });
|
|
return;
|
|
}
|
|
|
|
switch (action) {
|
|
case '':
|
|
case 'status':
|
|
return handleStatusCommand(message, rest);
|
|
case 'help':
|
|
return message.reply(formatHelp());
|
|
case 'replay':
|
|
return handleReplayCommand(message, tokens.join(' '));
|
|
case 'bridge':
|
|
return handleBridgeCommand(message, tokens);
|
|
case 'lights':
|
|
return handleLightsCommand(message, tokens);
|
|
case 'kick':
|
|
return handleKickCommand(message, rest);
|
|
case 'lock':
|
|
return handleLockCommand(message, rest, true);
|
|
case 'unlock':
|
|
return handleLockCommand(message, rest, false);
|
|
case 'mode':
|
|
return handleModeCommand(message, tokens);
|
|
case 'goal':
|
|
return handleGoalCommand(message, tokens);
|
|
case 'reason':
|
|
return handleReasonCommand(message, tokens);
|
|
case 'verify':
|
|
return handleVerifyCommand(message, tokens);
|
|
case 'deter':
|
|
return handleDeterCommand(message, tokens);
|
|
default:
|
|
return message.reply(formatHelp());
|
|
}
|
|
}
|
|
|
|
return { handleCommand };
|
|
}
|
|
|
|
module.exports = { createCommandHandlers };
|