my / src /handlers /adminHandler.js
understanding's picture
Upload 13 files
14960b8 verified
// 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 };