Spaces:
Paused
Paused
| // 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 }; | |