my / src /handlers /registrationHandler.js
understanding's picture
Upload 13 files
14960b8 verified
// src/handlers/registrationHandler.js (previously selfReg.js)
const logger = require('../logger');
const whatsapp = require('../services/whatsappService');
const { User } = require('../database'); // Import User model directly
const config = require('../config'); // Import config for delays
const { sleep } = require('../utils'); // Import sleep directly if needed
const userState = {};
const REGISTRATION_DELAY_MIN = 2000; // 2 seconds
const REGISTRATION_DELAY_MAX = 3000; // 3 seconds
/**
* Handles the multi-step registration process. Uses whatsappService for communication.
* /restart command functionality has been removed.
*/
async function handleRegistration(jid, messageContent) { // Renamed remoteJid to jid for consistency
logger.debug({ jid }, `[RegistrationHandler] Handling step.`);
const currentState = userState[jid] || { step: 'START', data: {} };
const delayOptions = { minDelay: config.registrationMinDelay, maxDelay: config.registrationMaxDelay };
// REMOVED: Global /restart check is removed from here.
try { // Wrap steps in try-catch
switch (currentState.step) {
case 'START':
userState[jid] = { step: 'ASKING_NAME', data: {} };
// REMOVED: Mention of /restart removed from the prompt
await whatsapp.sendMessageWithTyping(jid, { text: "Hi there! Let's get you registered.\n\nWhat is your full Name?" }, delayOptions);
break;
case 'ASKING_NAME':
if (!messageContent.trim()) {
await whatsapp.sendMessageWithTyping(jid, { text: "Please enter a valid name." }, delayOptions);
break;
}
currentState.data.name = messageContent.trim();
currentState.step = 'ASKING_REGNO';
userState[jid] = currentState;
logger.debug({ jid, data: currentState.data }, `[RegistrationHandler] Name received.`);
await whatsapp.sendMessageWithTyping(jid, { text: `Got it, ${currentState.data.name}.\n\nWhat is your Registration Number?` }, delayOptions);
break;
case 'ASKING_REGNO':
if (!messageContent.trim()) {
await whatsapp.sendMessageWithTyping(jid, { text: "Please enter a valid registration number." }, delayOptions);
break;
}
currentState.data.regNo = messageContent.trim();
currentState.step = 'ASKING_SEMESTER';
userState[jid] = currentState;
logger.debug({ jid, data: currentState.data }, `[RegistrationHandler] RegNo received.`);
await whatsapp.sendMessageWithTyping(jid, { text: "Great!\n\nWhich Semester are you in? (e.g., 1st, 2nd, 3rd, 4th)" }, delayOptions);
break;
case 'ASKING_SEMESTER':
if (!messageContent.trim()) {
await whatsapp.sendMessageWithTyping(jid, { text: "Please enter a valid semester." }, delayOptions);
break;
}
currentState.data.semester = messageContent.trim();
currentState.step = 'CONFIRMING';
userState[jid] = currentState;
logger.debug({ jid, data: currentState.data }, `[RegistrationHandler] Semester received.`);
const confirmationText = `?? *Please confirm your details:* ??\n\n*Name:* ${currentState.data.name}\n*Reg No:* ${currentState.data.regNo}\n*Semester:* ${currentState.data.semester}\n\nIs this correct? Reply with *yes* or *no*.`;
await whatsapp.sendMessageWithTyping(jid, { text: confirmationText }, delayOptions);
break;
case 'CONFIRMING':
const confirmation = messageContent.trim().toLowerCase();
if (confirmation === 'yes') {
try {
logger.info({ jid, data: currentState.data }, `[RegistrationHandler] User confirmed. Saving data.`);
await sleep(300); // Small pause before DB write
const updateResult = await User.updateOne(
{ remoteJid: jid },
{
$set: {
name: currentState.data.name,
regNo: currentState.data.regNo,
semester: currentState.data.semester,
isRegistered: true,
registrationTimestamp: new Date()
}
},
{ upsert: true }
);
logger.info({ jid, result: updateResult }, `[RegistrationHandler] MongoDB update result.`);
if (updateResult.acknowledged) {
await whatsapp.sendMessageWithTyping(jid, { text: "βœ… Registration successful! Your details have been saved." }, delayOptions);
delete userState[jid]; // Clear state
} else { throw new Error("Database update not acknowledged."); }
} catch (dbError) {
logger.error({ jid, err: dbError }, `[RegistrationHandler] Error saving data during confirmation.`);
// REMOVED: Mention of /restart in error message
await whatsapp.sendMessageWithTyping(jid, { text: "❌ Sorry, there was an error saving your details. Please reply 'yes' again or 'no' to start over." }, delayOptions);
}
} else if (confirmation === 'no') { // Only 'no' triggers restart now
logger.info({ jid }, `[RegistrationHandler] User replied 'no' at confirmation.`);
delete userState[jid];
userState[jid] = { step: 'ASKING_NAME', data: {} };
await whatsapp.sendMessageWithTyping(jid, { text: "Okay, let's start over.\n\nWhat is your full Name?" }, delayOptions);
} else {
await whatsapp.sendMessageWithTyping(jid, { text: "Please reply with *yes* or *no*." }, delayOptions);
}
break;
default: // Unhandled state
logger.warn({ jid, state: currentState.step }, `[RegistrationHandler] Unhandled state step.`);
delete userState[jid];
await whatsapp.sendMessageWithTyping(jid, { text: "Something went wrong during registration. Please send any message to try starting again." }, delayOptions); // Updated generic error
break;
}
} catch (stepError) { // Catch errors in the switch/case logic itself
logger.error({ jid, err: stepError, step: currentState.step }, "[RegistrationHandler] Error during registration step execution.");
try {
// REMOVED: Mention of /restart in generic error message
await whatsapp.sendMessageWithTyping(jid, { text: "An unexpected error occurred during registration. Please try starting again by sending any message." });
delete userState[jid]; // Reset state on error
} catch (sendErr) {
logger.error({ jid, err: sendErr }, "[RegistrationHandler] Failed to send error message during step error handling.");
}
}
}
module.exports = { handleRegistration };