Skip to content

Repository files navigation

SofIA – Sistema de Automatización de Reclutamiento

Backend inteligente para contactar candidatos mediante llamadas automáticas y chatbot de WhatsApp.


Tabla de Contenidos

  1. ¿Qué hace SofIA?
  2. Flujo Completo del Sistema
  3. Configuración Inicial
  4. Cómo Correr el Servidor
  5. Todos los Scripts Disponibles
  6. Flujo del Chatbot (JSON de Ida y Vuelta)
  7. Cómo Hacer la Prueba Real Completa
  8. Endpoints del Servidor
  9. Solución de Problemas

¿Qué hace SofIA?

SofIA automatiza el proceso de contactar candidatos para reclutamiento:

  1. Llamadas automáticas (ElevenLabs): Llama a los candidatos en horarios programados.
  2. Chatbot de respaldo (WhatsApp): Cuando un candidato acumula 9 intentos fallidos (intentos_llamada >= 9), SofIA activa el chatbot de la compañera, que le escribe por WhatsApp.
  3. Actualización automática: Cuando el candidato responde en WhatsApp, el chatbot notifica a SofIA y la base de datos se actualiza (agendado, no interesado, etc.).

Flujo Completo del Sistema

[SofIA] Detecta 9 llamadas fallidas
↓
[SofIA → Chatbot] Envía JSON con datos del candidato a la URL de tu compañera
↓
[WhatsApp] El candidato recibe mensaje y agenda su cita
↓
[Chatbot → SofIA] Envía JSON con resultado al webhook público de SofIA
↓
[SofIA] Actualiza la base de datos (estado, evento, nota)

Configuración Inicial

1. Instalar dependencias

npm install

2. Configurar el archivo .env

Crea o edita .env en la raíz del proyecto:

# ── Base de Datos (Supabase / PostgreSQL) ──────────────────────────────DATABASE_URL=postgresql://postgres:[PASSWORD]@db.[SUPABASE_ID].supabase.co:5432/postgres
# ── Servidor ────────────────────────────────────────────────────────────PORT=3000
# ── ElevenLabs (Llamadas Automáticas) ──────────────────────────────────ELEVENLABS_API_KEY=sk_...
ELEVENLABS_AGENT_ID=agent_...
ELEVENLABS_PHONE_NUMBER_ID=phnum_...
ELEVENLABS_MOCK=false # true = no hace llamadas reales (modo prueba)# ── Chatbot de WhatsApp (URL de tu compañera) ───────────────────────────CHATBOT_WEBHOOK_URL=https://su-ngrok.ngrok-free.app/solicitar-chat
# ── Control de Llamadas ─────────────────────────────────────────────────MAX_CONCURRENT_CALLS=4
STALE_CALL_MINUTES=30

Cómo Correr el Servidor

Producción

npm start

Desarrollo (se reinicia al guardar cambios)

npm run dev

El servidor queda escuchando en http://localhost:3000. Verás:

HTTP server listening on :3000
✅ SofIA Chatbot Service is running

Abrir túnel público (Para recibir respuestas del chatbot)

npm run tunnel

Ngrok te dará una URL pública como https://a1b2.ngrok-free.app. Dásela a tu compañera para que configure su webhook de respuesta a:

https://a1b2.ngrok-free.app/api/chatbot/webhook

⚠️No cierres esta terminal. Si la cierras, la URL deja de funcionar.


Todos los Scripts Disponibles

Comandos npm run

ComandoDescripción
npm run devServidor en modo desarrollo con auto-reinicio
npm startServidor en modo producción
npm run test:waEnvía JSON de prueba a la URL de tu compañera (candidata ficticia "Andrea")
npm run test:chatbot:direct -- [UUID]Fuerza el chatbot para un candidato específico
npm run tunnelAbre el túnel ngrok en el puerto 3000

Scripts en /scripts

node scripts/trigger-masivo-chatbot.js

Script principal de producción. Busca todos los candidatos con intentos_llamada >= 9 y envía su JSON al chatbot en lotes de 4.

node scripts/trigger-masivo-chatbot.js

node scripts/ver-payload-candidato.js [UUID]

Muestra el JSON que se le enviaría al chatbot para un candidato, sin enviarlo. Útil para revisar que horarios y eventos estén bien formados.

node scripts/ver-payload-candidato.js 0dd9d7da-525f-44ad-997a-8e52103b765b

node scripts/check-candidate.js

Muestra el estado actual en BD de los candidatos de prueba (Maryhug, Angelo, Emmanuel, Daniela, Andrea). Confirma si la BD se actualizó tras una conversación.

node scripts/check-candidate.js

node scripts/test-ngrok.js [URL]

Verifica si tu túnel ngrok está activo enviando un JSON de prueba real a tu propio servidor.

node scripts/test-ngrok.js https://tu-url.ngrok-free.app
# Resultado esperado: ✅ ¡ÉXITO! El servidor local respondió correctamente

node scripts/test-webhook-respuesta.js [UUID] [RESULTADO] [EVENTO_ID] ["NOTA"]

Simula que tu compañera te envía el JSON de resultado. Actualiza la BD directamente. Úsalo para probar la recepción sin que ella esté disponible.

# Candidato agendado con evento y nota
node scripts/test-webhook-respuesta.js "0dd9d7da-525f-44ad-997a-8e52103b765b""AGENDADO""3""Prefiere tarde"# Candidato no interesado
node scripts/test-webhook-respuesta.js "0dd9d7da-525f-44ad-997a-8e52103b765b""NO_INTERESADO"

node scripts/reset-maryhug.js

Resetea a Maryhug a estado PENDIENTE con 9 intentos de llamada, lista para volver a probar el flujo completo.

node scripts/reset-maryhug.js

node scripts/list-events.js

Lista los eventos disponibles en la BD (ID, fecha, tipo). Útil para saber qué evento_id usar en las pruebas.

node scripts/list-events.js

node scripts/llenar-cola.js

Llena la cola de llamadas simulando el horario del día. Necesario para que el sistema de llamadas tenga candidatos en cola.

node scripts/llenar-cola.js

node scripts/resetear-bd.js

⚠️¡Solo para pruebas! Borra el historial de llamadas de la BD.

node scripts/resetear-bd.js

node scripts/test-db-connection.js

Verifica que la conexión a PostgreSQL (Supabase) funciona.

node scripts/test-db-connection.js

Flujo del Chatbot

JSON que SofIA envía a tu compañera

POST a CHATBOT_WEBHOOK_URL (el endpoint de tu compañera):

{
"candidato_id": "0dd9d7da-525f-44ad-997a-8e52103b765b",
"telefono": "3112790495",
"nombre": "Maryhug",
"motivo": "ENTREVISTA",
"ciudad": "Bogotá",
"mensaje": "Hola Maryhug, hemos intentado contactarte...\n\n1) lunes 3:00 PM\n2) martes 7:00 AM",
"lista_horarios": "1) lunes 3:00 PM\n2) martes 7:00 AM",
"eventos_disponibles": [
{ "fecha_legible": "lunes a las 3:00 PM", "evento_id": "3" },
{ "fecha_legible": "martes a las 7:00 AM", "evento_id": "4" }
]
}

JSON que SofIA espera recibir de tu compañera

POST a https://[TU_URL_NGROK]/api/chatbot/webhook:

{
"candidato_id": "0dd9d7da-525f-44ad-997a-8e52103b765b",
"telefono": "3112790495",
"resultado_agenda": "AGENDADO",
"evento_id": "3",
"nota": "La candidata prefiere horarios de tarde"
}
CampoObligatorioDescripción
candidato_id✅ (o telefono)UUID del candidato
telefono✅ (o candidato_id)Teléfono sin +
resultado_agendaAGENDADO o NO_INTERESADO
evento_id❌ OpcionalID del evento elegido (solo si agendó)
nota❌ OpcionalComentario de la conversación

Cómo Hacer la Prueba Real Completa

Necesitas 3 terminales abiertas:

Terminal 1 – Servidor

npm run dev

Déjala abierta. Aquí verás los logs cuando llegue el JSON de tu compañera.

Terminal 2 – Túnel Ngrok

npm run tunnel

Copia la URL pública (ej: https://a1b2.ngrok-free.app) y dásela a tu compañera.

Terminal 3 – Comandos

# Paso 1: Preparar candidato de prueba
node scripts/reset-maryhug.js
# Paso 2: Verificar que el túnel funciona
node scripts/test-ngrok.js https://a1b2.ngrok-free.app
# Paso 3: Disparar el chatbot (SofIA → Compañera)
node scripts/trigger-masivo-chatbot.js
# Paso 4: Esperar a que Maryhug responda en WhatsApp...# (Cuando lo haga, verás el log en Terminal 1)# Paso 5: Verificar que la BD se actualizó
node scripts/check-candidate.js

Resultado esperado en check-candidate.js:

Maryhug | AGENDADO | evento_asignado_id: 3 | nota: "..."

Endpoints del Servidor

MétodoRutaDescripción
GET/healthEstado del servidor y la BD
POST/webhookRecibe resultados de llamadas (ElevenLabs)
POST/api/chatbot/webhookRecibe el resultado del chat (de tu compañera)
POST/api/chatbot/trigger-manualDispara el chatbot manualmente (body: { "candidato_id": "..." })

Solución de Problemas

ErrorCausaSolución
Status 503 / endpoint offlineNgrok se cerró o expiróVuelve a correr npm run tunnel y dale la nueva URL a tu compañera
Status 404 en ngrokURL de ngrok cambióNgrok gratuito cambia la URL cada sesión. Actualízala en .env y con tu compañera
unable to verify first certificateSSL de ngrokYa está corregido en el código (rejectUnauthorized: false)
Status 403 ForbiddenFirewall corporativo bloquea ngrokCambia a datos del celular o usa: ssh -p 443 -R0:localhost:3000 a.pinggy.io
Connection timeout en BDRed inestable a SupabaseLos scripts tienen reintentos automáticos. Intenta de nuevo
No se encontraron candidatos en trigger masivoNinguno tiene intentos_llamada >= 9Ejecuta node scripts/reset-maryhug.js
Status 422 al enviar al chatbotFalta campo requerido en el JSONVerifica que CHATBOT_WEBHOOK_URL apunte al endpoint correcto de tu compañera
Logs en npm run dev no aparecenEl JSON no está llegando a tu servidorTu túnel ngrok no está activo o tu compañera tiene la URL vieja

About

Modularized backend architecture for SofIA. Built with Node.js.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages