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:
@@ -45,6 +45,20 @@ export class ApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
async buscarLeadPorTelefono(telefono: string): Promise<string | null> {
|
||||
try {
|
||||
const { data } = await axios.get(`${this.baseUrl}/api/leads/by-phone`, {
|
||||
headers: this.headers,
|
||||
params: { telefono },
|
||||
});
|
||||
return data?.leadId ?? null;
|
||||
} catch (err: any) {
|
||||
if (err.response?.status === 404) return null;
|
||||
this.logger.error(`buscarLeadPorTelefono error: ${err.message}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async guardarConversacion(
|
||||
leadId: string,
|
||||
rol: 'user' | 'assistant' | 'system',
|
||||
|
||||
@@ -171,6 +171,14 @@ export class WebhookListener implements OnApplicationBootstrap {
|
||||
}
|
||||
}
|
||||
|
||||
// Re-registra una sesión recuperada de la BD (cuando no estaba en memoria, p. ej. tras reinicio).
|
||||
ensureSession(telefono: string, leadId: string, nombre = '') {
|
||||
const tel = this.normTel(telefono);
|
||||
if (!this.leadSessions.has(tel)) {
|
||||
this.leadSessions.set(tel, { leadId, telefono: tel, nombre, jid: null });
|
||||
}
|
||||
}
|
||||
|
||||
private async handleWhatsappPdf(payload: { leadId: string; telefono: string; pdfBase64: string; filename: string }) {
|
||||
this.logger.log(`[PDF] leadId=${payload.leadId}, filename=${payload.filename}`);
|
||||
const { pdfEmitter } = await import('../whatsapp/whatsapp.service');
|
||||
|
||||
@@ -263,7 +263,16 @@ export class WhatsappService implements OnModuleInit, OnModuleDestroy {
|
||||
}
|
||||
|
||||
private async getOrCreateContext(telefono: string, jid: string): Promise<LeadContext | null> {
|
||||
const leadId = this.webhookListener.getLeadIdByTelefono(telefono);
|
||||
let leadId = this.webhookListener.getLeadIdByTelefono(telefono);
|
||||
|
||||
// Fallback: si no está en memoria (reinicio del bot), recuperarlo de la BD por teléfono.
|
||||
if (!leadId) {
|
||||
leadId = await this.api.buscarLeadPorTelefono(telefono);
|
||||
if (leadId) {
|
||||
this.webhookListener.ensureSession(telefono, leadId);
|
||||
this.logger.log(`Lead ${leadId} recuperado por teléfono ${telefono} (sin sesión en memoria).`);
|
||||
}
|
||||
}
|
||||
|
||||
if (!leadId) {
|
||||
this.logger.log(`Mensaje ignorado de ${telefono}: lead no registrado. Debe iniciarse desde la web.`);
|
||||
|
||||
Reference in New Issue
Block a user