Bot responde a mensajes entrantes: recupera lead por teléfono + fix matching

El bot no respondía a las réplicas del cliente: la sesión lead↔teléfono vivía
solo en memoria y no casaba (se pierde al reiniciar el contenedor). Ahora si no
está en memoria, getOrCreateContext busca el lead en la BD por teléfono vía un
EP nuevo GET /api/leads/by-phone (match por últimos 9 dígitos) y re-registra la
sesión. Aparte, los ids de modelo de Claude del bot estaban mal (-4-5 vs 4.5).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Carlos Narro
2026-06-09 17:28:56 +02:00
parent 0a00d42553
commit a8b6d62dd6
4 changed files with 69 additions and 1 deletions

View File

@@ -0,0 +1,37 @@
import { desc, like } from 'drizzle-orm';
import { db } from '@/db';
import { leads } from '@/db/schema';
import { autorizado, jsonResponse } from '@/lib/api/funnel-auth';
export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';
// Busca el lead más reciente por teléfono (comparando los últimos 9 dígitos, ignorando prefijos y
// formato). Lo usa el bot de WhatsApp para recuperar el leadId de un mensaje entrante cuando no
// tiene la sesión en memoria (p. ej. tras un reinicio del contenedor).
export async function GET(req: Request) {
if (!autorizado(req)) return jsonResponse({ ok: false, error: 'No autorizado.' }, 401);
const tel = (new URL(req.url).searchParams.get('telefono') ?? '').replace(/\D/g, '');
if (tel.length < 6) return jsonResponse({ ok: false, error: 'telefono inválido.' }, 422);
const last9 = tel.slice(-9);
const [lead] = await db
.select({
id: leads.id,
nombre: leads.nombre,
telefono: leads.telefono,
botStep: leads.botStep,
viable: leads.viable,
})
.from(leads)
.where(like(leads.telefono, `%${last9}%`))
.orderBy(desc(leads.createdAt))
.limit(1);
if (!lead) return jsonResponse({ ok: false, error: 'Lead no encontrado.' }, 404);
return jsonResponse(
{ leadId: lead.id, nombre: lead.nombre, telefono: lead.telefono, botStep: lead.botStep, viable: lead.viable },
200,
);
}