87 lines
2.8 KiB
TypeScript
87 lines
2.8 KiB
TypeScript
import { Injectable, Logger } from '@nestjs/common';
|
|
import { Cron, CronExpression } from '@nestjs/schedule';
|
|
import { LeadsService } from '../leads/leads.service';
|
|
import { ConversacionService } from '../conversacion/conversacion.service';
|
|
import { WhatsappService } from '../whatsapp/whatsapp.service';
|
|
import { ClaudeService } from '../claude/claude.service';
|
|
|
|
@Injectable()
|
|
export class SchedulerService {
|
|
private readonly logger = new Logger(SchedulerService.name);
|
|
|
|
constructor(
|
|
private readonly leadsService: LeadsService,
|
|
private readonly conversacionService: ConversacionService,
|
|
private readonly whatsappService: WhatsappService,
|
|
private readonly claudeService: ClaudeService,
|
|
) {}
|
|
|
|
/**
|
|
* Cada 5 minutos:
|
|
* 1. Busca leads con estado_actual = 'nuevo'
|
|
* 2. Los marca como 'en_proceso'
|
|
* 3. Les envía el mensaje de APERTURA de Luisa
|
|
*
|
|
* También marca como perdidos los leads en_proceso sin actividad > 48h.
|
|
*/
|
|
@Cron(CronExpression.EVERY_5_MINUTES)
|
|
async procesarLeadsNuevos(): Promise<void> {
|
|
this.logger.log('[Scheduler] Buscando leads nuevos...');
|
|
|
|
// Primero limpiar leads inactivos
|
|
await this.leadsService.marcarLeadsPerdidos();
|
|
|
|
// Obtener leads nuevos
|
|
const leadsNuevos = await this.leadsService.findByEstado('nuevo');
|
|
|
|
if (leadsNuevos.length === 0) {
|
|
this.logger.log('[Scheduler] No hay leads nuevos.');
|
|
return;
|
|
}
|
|
|
|
this.logger.log(
|
|
`[Scheduler] Procesando ${leadsNuevos.length} lead(s) nuevo(s).`,
|
|
);
|
|
|
|
for (const lead of leadsNuevos) {
|
|
try {
|
|
// Marcar como en_proceso antes de hacer nada
|
|
await this.leadsService.updateEstado(lead, 'en_proceso');
|
|
this.logger.log(
|
|
`[Scheduler] Lead id=${lead.id} marcado como en_proceso.`,
|
|
);
|
|
|
|
// Generar mensaje de apertura con Claude usando contexto mínimo
|
|
const historialVacio: Array<{ role: string; content: string }> = [];
|
|
const mensajeDeApertura =
|
|
'APERTURA: Este es el primer mensaje. Preséntate y comienza el flujo de cualificación.';
|
|
|
|
const { respuesta } = await this.claudeService.llamarClaude(
|
|
lead,
|
|
historialVacio,
|
|
mensajeDeApertura,
|
|
);
|
|
|
|
// Guardar el mensaje de apertura en historial (como assistant)
|
|
await this.conversacionService.guardarMensaje(
|
|
lead.id,
|
|
'assistant',
|
|
respuesta,
|
|
);
|
|
|
|
// Enviar por WhatsApp
|
|
await this.whatsappService.enviarApertura(lead.telefono, respuesta);
|
|
|
|
this.logger.log(
|
|
`[Scheduler] Apertura enviada a lead id=${lead.id} (${lead.telefono}).`,
|
|
);
|
|
} catch (error) {
|
|
this.logger.error(
|
|
`[Scheduler] Error procesando lead id=${lead.id}: ${error.message}`,
|
|
error.stack,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|