From 166d52f46df1d7d7661c02c21365eed87e484e50 Mon Sep 17 00:00:00 2001 From: Carlos Narro Date: Wed, 10 Jun 2026 11:56:05 +0200 Subject: [PATCH] =?UTF-8?q?Bot:=20dispara=20el=20post-an=C3=A1lisis=20al?= =?UTF-8?q?=20cerrar=20la=20cualificaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cuando la conversación llega al cierre (estado presupuesto/fin_*, o Luisa anuncia que prepara/envía el presupuesto), el bot llama una vez a POST /api/leads/:id/analizar para que la app capture todos los datos clave de la conversación de una pasada. Co-Authored-By: Claude Opus 4.8 --- mvp/Whatsapp-bot/src/api/api-client.service.ts | 5 +++++ .../src/whatsapp/whatsapp.service.ts | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/mvp/Whatsapp-bot/src/api/api-client.service.ts b/mvp/Whatsapp-bot/src/api/api-client.service.ts index 6ebe0c2..83e1a08 100644 --- a/mvp/Whatsapp-bot/src/api/api-client.service.ts +++ b/mvp/Whatsapp-bot/src/api/api-client.service.ts @@ -45,6 +45,11 @@ export class ApiClient { } } + // Post-análisis: la app lee toda la conversación del lead y extrae los datos clave de una pasada. + async analizarConversacion(leadId: string): Promise { + return this.post(`/api/leads/${leadId}/analizar`, {}); + } + async buscarLeadPorTelefono(telefono: string): Promise { try { const { data } = await axios.get(`${this.baseUrl}/api/leads/by-phone`, { diff --git a/mvp/Whatsapp-bot/src/whatsapp/whatsapp.service.ts b/mvp/Whatsapp-bot/src/whatsapp/whatsapp.service.ts index cb7f3c7..e88bd11 100644 --- a/mvp/Whatsapp-bot/src/whatsapp/whatsapp.service.ts +++ b/mvp/Whatsapp-bot/src/whatsapp/whatsapp.service.ts @@ -49,6 +49,8 @@ export class WhatsappService implements OnModuleInit, OnModuleDestroy { private readonly jidToLeadId = new Map(); // contexto de lead por leadId private readonly leadCache = new Map(); + // leads cuya conversación ya se mandó a post-análisis (para no repetir). + private readonly leadsAnalizados = new Set(); constructor( private readonly leadsService: LeadsService, @@ -449,6 +451,20 @@ export class WhatsappService implements OnModuleInit, OnModuleDestroy { this.logger.log(`Lead ${ctx.leadId} persistido — estado=${nuevoEstado || ctx.botStep}`); } + // Al cerrar la cualificación, dispara el post-análisis de toda la conversación (una sola vez). + // Por estado (errático) O porque Luisa anuncia el presupuesto en su mensaje. + const cierre = ['presupuesto', 'fin_viable', 'fin_no_viable']; + const anunciaPresupuesto = + /presupuesto/i.test(respuesta) && + /prepar|recib|enseguida|en un momento|te lo env|lo env|aqu[ií] mismo/i.test(respuesta); + if ((cierre.includes(ctx.botStep) || anunciaPresupuesto) && !this.leadsAnalizados.has(ctx.leadId)) { + this.leadsAnalizados.add(ctx.leadId); + this.api + .analizarConversacion(ctx.leadId) + .then((ok) => this.logger.log(`[ANALISIS] lead ${ctx.leadId}: ${ok ? 'ok' : 'fallo'}`)) + .catch((e: any) => this.logger.error(`[ANALISIS] ${e.message}`)); + } + await this.conversacionService.guardarMensaje(ctx.leadId, 'assistant', respuesta, { botStep: ctx.botStep, });