Spaces:
Building
Building
// src/handlers/adminHandler.js | |
const logger = require('../logger'); | |
const whatsapp = require('../services/whatsappService'); | |
const { User } = require('../database'); | |
const config = require('../config'); | |
// State to track pending admin actions requiring confirmation | |
// Key: adminJid, Value: { action: 'confirm_clear', semester: '...', timeoutId: ... } | |
const adminState = {}; | |
const CONFIRMATION_TIMEOUT = 60000; // 60 seconds | |
/** | |
* Clears the pending state for an admin. | |
* @param {string} jid - Admin JID. | |
*/ | |
function clearAdminState(jid) { | |
if (adminState[jid]) { | |
clearTimeout(adminState[jid].timeoutId); // Clear the timeout | |
delete adminState[jid]; | |
logger.info({ adminJid: jid }, `[AdminHandler] Cleared pending admin state.`); | |
} | |
} | |
/** | |
* Handles commands sent by recognized admins, including confirmation steps. | |
* Returns true if an admin command (or confirmation) was processed, false otherwise. | |
*/ | |
async function handleAdminCommand(jid, messageContent) { | |
logger.debug({ adminJid: jid, command: messageContent }, `[AdminHandler] Processing potential admin command.`); | |
const pendingAction = adminState[jid]; | |
// --- Step 1: Check if awaiting confirmation --- | |
if (pendingAction) { | |
const confirmation = messageContent.trim().toLowerCase(); | |
const semesterToDelete = pendingAction.semester; // Get semester from stored state | |
if (pendingAction.action === 'confirm_clear') { | |
if (confirmation === 'yes') { | |
logger.warn({ adminJid: jid, semester: semesterToDelete }, `[AdminHandler] Confirmation 'yes' received for .clear`); | |
clearAdminState(jid); // Clear state before performing action | |
try { | |
const deleteResult = await User.deleteMany({ | |
semester: { $regex: new RegExp(`^${semesterToDelete}$`, 'i') } | |
}); | |
const replyText = `β Admin: Successfully deleted ${deleteResult.deletedCount} records matching semester "${semesterToDelete}".`; | |
logger.warn({ result: deleteResult, semester: semesterToDelete }, `[AdminHandler] .clear command executed successfully.`); | |
await whatsapp.sendMessageWithTyping(jid, { text: replyText }); | |
} catch (cmdError) { | |
logger.error({ err: cmdError, semester: semesterToDelete }, `[AdminHandler] .clear command failed during execution.`); | |
await whatsapp.sendMessageWithTyping(jid, { text: `β Admin: Error executing .clear command for semester "${semesterToDelete}" after confirmation. Check logs.` }); | |
} | |
} else { // Includes 'no' or any other reply | |
logger.info({ adminJid: jid, semester: pendingAction.semester, reply: confirmation }, `[AdminHandler] .clear command aborted by admin or invalid confirmation.`); | |
clearAdminState(jid); | |
await whatsapp.sendMessageWithTyping(jid, { text: `β Admin: Aborted deletion for semester "${semesterToDelete}".` }); | |
} | |
} else { | |
// Handle other potential pending actions here if added later | |
logger.warn({ adminJid: jid, pendingAction }, `[AdminHandler] Unknown pending action found.`); | |
clearAdminState(jid); // Clear unknown state | |
} | |
return true; // Confirmation message was processed | |
} | |
// --- Step 2: Check for new commands if not awaiting confirmation --- | |
// ** .clear command ** | |
if (messageContent.startsWith('.clear ')) { | |
const parts = messageContent.split(' '); | |
if (parts.length === 2 && parts[1]) { | |
const semesterToDelete = parts[1].trim(); | |
logger.warn({ adminJid: jid, semester: semesterToDelete }, `[AdminHandler] .clear command received. Requesting confirmation.`); | |
// Set pending state with timeout | |
adminState[jid] = { | |
action: 'confirm_clear', | |
semester: semesterToDelete, | |
timeoutId: setTimeout(() => { | |
if (adminState[jid]?.action === 'confirm_clear') { // Check if still pending this action | |
logger.warn({ adminJid: jid, semester: semesterToDelete }, `[AdminHandler] Confirmation for .clear timed out.`); | |
delete adminState[jid]; // Clear state on timeout | |
whatsapp.sendMessageWithTyping(jid, { text: `β° Admin: Confirmation request for deleting semester "${semesterToDelete}" timed out.` }).catch(err => logger.error({err}, "Failed to send timeout message")); | |
} | |
}, CONFIRMATION_TIMEOUT) | |
}; | |
// Ask for confirmation | |
const promptText = `β *Confirmation Needed* β\n\nAre you sure you want to delete ALL student data for semester *${semesterToDelete}*? This cannot be undone.\n\nReply with *Yes* or *No*. (Expires in 60 seconds)`; | |
await whatsapp.sendMessageWithTyping(jid, { text: promptText }); | |
} else { // Invalid format | |
await whatsapp.sendMessageWithTyping(jid, { text: `β Admin: Invalid .clear command format. Use: \`.clear <semester>\` (e.g., \`.clear 3rd\`)` }); | |
} | |
return true; // .clear command attempt was handled | |
} | |
// --- Add other admin commands here --- | |
// else if (messageContent.startsWith('.some_other_command')) { | |
// logger.info({ adminJid: jid }, `[AdminHandler] Handling other admin command.`); | |
// ... handle command ... | |
// return true; | |
// } | |
// If no known admin command matched | |
logger.debug({ adminJid: jid, command: messageContent }, `[AdminHandler] Not a recognized admin command.`); | |
return false; // No admin command was processed | |
} | |
module.exports = { handleAdminCommand }; | |