// Per-user conversation state for menu-driven flows. // Currently tracks: "operator clicked Pair New, waiting for them to type the label". // In-memory only — fine for a single-instance bot. If we ever scale horizontally, // move this to Postgres. const PENDING_TTL_MS = 5 * 60 * 1000; // 5 minutes const pendingPairLabel = new Map(); // userId → expires_at_ms export function setPendingPairLabel(userId: number): void { pendingPairLabel.set(userId, Date.now() + PENDING_TTL_MS); } export function clearPendingPairLabel(userId: number): void { pendingPairLabel.delete(userId); } export function consumePendingPairLabel(userId: number): boolean { const expiresAt = pendingPairLabel.get(userId); if (!expiresAt) return false; pendingPairLabel.delete(userId); return Date.now() < expiresAt; } // "Send a test message to this WhatsApp group" pending state. type PendingSend = { groupId: string; expiresAt: number }; const pendingSendToGroup = new Map(); export function setPendingSendToGroup(userId: number, groupId: string): void { pendingSendToGroup.set(userId, { groupId, expiresAt: Date.now() + PENDING_TTL_MS }); } export function clearPendingSendToGroup(userId: number): void { pendingSendToGroup.delete(userId); } export function consumePendingSendToGroup(userId: number): string | null { const pending = pendingSendToGroup.get(userId); if (!pending) return null; pendingSendToGroup.delete(userId); if (Date.now() >= pending.expiresAt) return null; return pending.groupId; } // Reminder creation wizard state. export type WizardStep = | "pick_account" | "pick_group" | "compose" | "set_time" | "confirm"; export type WizardState = { step: WizardStep; accountId?: string; groupId?: string; text?: string | null; mediaId?: string | null; caption?: string | null; scheduledAt?: Date; expiresAt: number; }; const wizardState = new Map(); const WIZARD_TTL_MS = 30 * 60 * 1000; export function getWizard(userId: number): WizardState | null { const w = wizardState.get(userId); if (!w) return null; if (Date.now() >= w.expiresAt) { wizardState.delete(userId); return null; } return w; } export function startWizard(userId: number): WizardState { const w: WizardState = { step: "pick_account", expiresAt: Date.now() + WIZARD_TTL_MS }; wizardState.set(userId, w); return w; } export function updateWizard(userId: number, patch: Partial): WizardState | null { const w = getWizard(userId); if (!w) return null; const next = { ...w, ...patch, expiresAt: Date.now() + WIZARD_TTL_MS }; wizardState.set(userId, next); return next; } export function clearWizard(userId: number): void { wizardState.delete(userId); }