13 KiB
Documentación Técnica del Workflow: Encuesta de Terminación Voluntaria (n8n)
Este documento detalla el diseño, la lógica de negocio y la configuración paso a paso de los nodos del flujo automatizado desarrollado en n8n para la gestión inteligente de encuestas de salida laboral de GomezLee Marketing.
1. Descripción del Proyecto y Alcance
El propósito fundamental de este flujo es optimizar la recolección y análisis de datos procedentes de las encuestas de salida de los empleados con terminación voluntaria.
El Problema
Históricamente, muchos empleados seleccionan o escriben motivos genéricos como "Motivos Personales" o proveen respuestas sin sentido o ambiguas en los formularios de salida. Esto impide que el departamento de Recursos Humanos (RRHH) obtenga información de valor (insights) para implementar planes de retención y mejoras internas.
La Solución Automatizada
El workflow soluciona este problema mediante un ciclo inteligente dividido en tres fases principales:
- Fase de Envío Automatizado: Identifica bajas voluntarias del sistema central (BambooHR) y envía la encuesta formal de manera automatizada.
- Fase de Análisis y Homologación Inicial (IA): Recibe la respuesta del formulario, utiliza Inteligencia Artificial (Google Gemini) para clasificar el motivo real, detectar subcategorías, evaluar el sentimiento e insertarlo en una base de datos (Google Sheets).
- Fase de Excepción y Recolección de Datos (RRHH + Email Loop): Si el motivo detectado o declarado cae bajo "Motivos Personales" o es "No Declarado", se activa un condicional que notifica inmediatamente al analista de RRHH del país correspondiente. RRHH llama al exempleado, obtiene el motivo detallado y responde un correo electrónico formateado. El sistema procesa esta respuesta vía email, re-homologa la información con IA y actualiza el registro inicial en el Google Sheets de manera transparente.
2. Diagrama Estructural del Workflow
El workflow se compone de 4 sub-procesos o bloques lógicos claramente demarcados:
- Sub-proceso 1 (Arriba): Trigger Webhook de terminación y validación en BambooHR de que sea baja voluntaria del mes en curso para el envío de la encuesta de salida.
- Sub-proceso 2 (Centro): Webhook de recepción de respuestas del formulario, procesamiento por IA (Gemini), guardado en Google Sheets, filtro condicional de excepción e inicio del bucle de correos hacia RRHH.
- Sub-proceso 3 (Abajo - Recepción): Listener / Trigger de Gmail que captura los correos de RRHH cuando la información es refinada, re-clasifica el motivo real con IA y actualiza la fila correspondiente en Google Sheets.
- Sub-proceso 4 (Fondo): Flujo técnico de respaldo/automatización interna para guardar copias del JSON del workflow en un repositorio Git centralizado.
3. Configuración Nodo por Nodo y Valores Recomendados
A continuación se detallan los parámetros y valores específicos que deben colocarse en cada nodo para garantizar el funcionamiento preciso del sistema:
Bloque A: Envío de la Encuesta (Bajas Voluntarias)
1. Webhook (Entrada de Terminación)
- Tipo de Nodo:
n8n-nodes-base.webhook - HTTP Method:
POST - Path:
terminacion - Función: Recibe las notificaciones de eventos de personal/bajas desde el core de RRHH.
2. If (Validación de Tipo)
- Tipo de Nodo:
n8n-nodes-base.if - Condición (String):
- Value 1:
{{ $json.body.employees[0].fields['Tipo de despido'] }} - Operator:
Equal - Value 2:
Resignation (Voluntary)
- Value 1:
3. Fecha de terminacion
- Tipo de Nodo:
n8n-nodes-base.httpRequest - Method:
GET - URL:
https://api.bamboohr.com/api/gateway.php/glm/v1/employees/{{ $json.body.employees[0].id }}?fields=terminationDate - Authentication:
HTTP Basic Auth-> Usar credencialesGLM Credential. - Headers:
accept: application/json
4. Code in JavaScript3 (Filtro Temporal)
- Tipo de Nodo:
n8n-nodes-base.code - Código JS:
const terminationDate = $json.terminationDate; if (!terminationDate) return [{ json: { pass: false } }]; const termDate = new Date(terminationDate); const now = new Date(); const sameMonth = termDate.getMonth() === now.getMonth(); const sameYear = termDate.getFullYear() === now.getFullYear(); return [{ json: { pass: sameMonth && sameYear } }];
5. Terminacion fue este mes?
- Tipo de Nodo:
n8n-nodes-base.if - Condición (Boolean):
- Value 1:
{{ $json.pass }} - Operator:
is True
- Value 1:
6. Send a message (Gmail)
- Tipo de Nodo:
n8n-nodes-base.gmail - Resource:
Message - Operation:
Send - Send To:
{{ $('Webhook').item.json.body.employees[0].fields['Correo electrónico personal'] }} - Subject:
GomezLee Marketing: Encuesta de salida – Queremos escuchar tu opinión - Body Type:
HTML - Message: (Insertar el código HTML provisto en la definición del flujo que renderiza la plantilla corporativa con el botón directo a la encuesta de Google Forms).
Bloque B: Procesamiento de Respuestas de Encuesta e IA
7. Webhook1 (Recepción del Formulario)
- Tipo de Nodo:
n8n-nodes-base.webhook - HTTP Method:
POST - Path:
encuesta
8. Code in JavaScript (Timestamping)
- Tipo de Nodo:
n8n-nodes-base.code - Código JS: Genera una estampa de tiempo formateada (
MM/DD/YYYY HH:MM:SS) para consistencia en la hoja de cálculo.
9. AI Agent + Google Gemini Chat Model (Clasificador Inicial)
- Tipo de Nodo:
@n8n/n8n-nodes-langchain.agentconectado almChatGoogleGemini. - Model Name:
models/gemini-3.1-pro-preview - Prompt Text:
={{ $('Webhook1').item.json.body['¿Por qué elegiste dejar la empresa?'] }} - System Message (Clave): Debe instruirse rigurosamente al modelo a actuar como un analista experto de RRHH para trade marketing y mapear el texto a etiquetas estructuradas de salida. Los labels válidos requeridos son:
"Motivos Personales""Remuneración""Liderazgo / Jefe Directo""Otro Trabajo / Traslado de Agencia""Ambiente Laboral / Compañeros""Work Life Balance / Horarios""Marca / Cliente / Condiciones del Punto""Onboarding / Procesos / Organización""Way of Work / Soporte Operativo""Reclutamiento / Expectativa vs Realidad""No quiso responder","Motivo No Declarado", o"Otros".
- Estructura del Output Requerido (JSON puro sin backticks):
{ "homologacion": "string", "homologado_2": "string | null", "sentimiento": "Positivo | Neutro | Negativo", "insight_rrhh": "frase breve con hallazgo clave" }
10. Code in JavaScript1 (Limpieza de Formato IA)
- Tipo de Nodo:
n8n-nodes-base.code - Objetivo: Elimina bloques de markdown (como ```json) en caso de que el LLM rompa las restricciones de formato, aislando la cadena JSON cruda.
11. Edit Fields & Eliminar espacios vacios
- Tipo de Nodos:
n8n-nodes-base.setyn8n-nodes-base.code. - Función: Mapean y remueven espacios en blanco colindantes en los nombres y cadenas para evitar inconsistencias de llaves primarias.
12. Añadir a Responses (Google Sheets)
- Tipo de Nodo:
n8n-nodes-base.googleSheets - Operation:
Append - Document ID:
1_vEMMGBclOZxaTeuHLXO_ucN0GmJ03Gm7jzOlzkVMFA - Sheet Name:
Respuestas - Mapeo de Columnas (Expresiones):
Homologacion_IA:{{ $('Edit Fields').item.json.cleaned.homologacion }}Subcategoria_IA:{{ $('Edit Fields').item.json.cleaned.homologado_2 }}Sentimiento_IA:{{ $('Edit Fields').item.json.cleaned.sentimiento }}Insight_RRHH:{{ $('Edit Fields').item.json.cleaned.insight_rrhh }}Timestamp:{{ $('Webhook1').item.json.body.timestamp }}Email Address:{{ $('Webhook1').item.json.body.email }}Nombre Completo:{{ $json.name }}¿Por qué elegiste dejar la empresa?:{{ $('Webhook1').item.json.body['¿Por qué elegiste dejar la empresa?'] }}
13. Es motivo personal? (El Enrutador de Excepciones)
- Tipo de Nodo:
n8n-nodes-base.if - Lógica de Evaluación Expresa (JavaScript Emulado):
{{ (() => { const allowed = ["motivos personales", "motivo no declarado"]; const homol = ($json.Homologacion_IA ?? "").toLowerCase().trim(); const sub = ($json.Subcategoria_IA ?? "").toLowerCase().trim(); const homolOk = homol === "" || allowed.includes(homol); const subOk = sub === "" || allowed.includes(sub); const anyFilled = homol !== "" || sub !== ""; return anyFilled && homolOk && subOk; })() }} - Operator:
is True - Comportamiento: Si da verdadero (True), significa que la respuesta de la persona no es accionable y requiere intervención de RRHH.
14. Paises (Ruteo Geográfico de RRHH)
- Tipo de Nodo:
n8n-nodes-base.code - Propósito: Mapea el país del empleado al correo del analista encargado en esa región.
- Diccionario de Mapeo:
- Dominicana:
nlaureano@gomezleemarketing.com - Guatemala:
rgalvez@gomezleemarketing.com - El Salvador:
cmalta@gomezleemarketing.com - Honduras:
mchang@gomezleemarketing.com - Nicaragua:
yestrada@gomezleemarketing.com - Costa Rica:
lchaves@gomezleemarketing.com - México:
ccastro@gomezleemarketing.com - Colombia:
rrhhcolombia@gomezleemarketing.com - Panamá:
dpenalba@gomezleemarketing.com
- Dominicana:
15. Enviar revision (Notificación a Analista)
- Tipo de Nodo:
n8n-nodes-base.gmail - Send To:
{{ $json.hhrr_email }} - Subject:
Seguimiento requerido – Encuesta de Salida - Contenido: Envía un correo con la ficha del exempleado pidiendo realizar la llamada y especificando que deben responder al sistema manteniendo el asunto: "Motivo de Salida Actualizado" e incluyendo en el cuerpo obligatoriamente las líneas:
Nombre completo: [Nombre Exacto] Motivo: [Nuevo Motivo Detallado]
Bloque C: Procesamiento del Correo de Actualización (RRHH Loop)
16. Gmail Trigger (Listener de Respuestas de RRHH)
- Tipo de Nodo:
n8n-nodes-base.gmailTrigger - Filters:
- Search Query (q):
Motivo de Salida Actualizado - Read Status:
Read
- Search Query (q):
17. Limpiar texto
- Tipo de Nodo:
n8n-nodes-base.code - Código JS: Remueve firmas automáticas y descargos legales buscando el marcador corporativo
'gomezlee marketing'para evitar ruidos en el análisis sintáctico de la IA.
18. AI Agent1 + Google Gemini Chat Model1 (Re-homologación)
- Tipo de Nodo:
@n8n/n8n-nodes-langchain.agent - Model Name:
models/gemini-3.1-pro-preview - Prompt Text:
={{ $json.body }} - Instrucciones del Sistema: Extrae el
nombre_completoy el nuevomotivo. Re-clasifica según las categorías estándar de la organización y genera un nuevo output estructurado:{ "nombre_completo": "string", "homologacion": "string", "homologado_2": "string | null", "sentimiento": "Positivo | Neutro | Negativo", "insight_rrhh": "string", "motivo": "string" }
19. Añadir a Responses1 (Google Sheets Update)
- Tipo de Nodo:
n8n-nodes-base.googleSheets - Operation:
Update - Document ID:
1_vEMMGBclOZxaTeuHLXO_ucN0GmJ03Gm7jzOlzkVMFA - Sheet Name:
Respuestas - Columnas a Actualizar:
Homologacion_IA:{{ $('Edit Fields1').item.json.output.homologacion }}Subcategoria_IA:{{ $('Edit Fields1').item.json.output.homologado_2 }}Sentimiento_IA:{{ $('Edit Fields1').item.json.output.sentimiento }}Insight_RRHH:{{ $('Edit Fields1').item.json.output.insight_rrhh }}¿Por qué elegiste dejar la empresa?:{{ $('Edit Fields1').item.json.output.motivo }}
- Key/Matching Columns:
Nombre Completo(Garantiza la sobreescritura exacta del registro que antes estaba bloqueado en motivos personales).
4. Instrucciones de Despliegue y Pruebas
- Credenciales: Asegurarse de enlazar la cuenta OAuth2 de Google Sheets (
Eidan - Google Sheets account), Gmail (Eidan - Gmail account), Google Gemini (Eidan - Google Gemini(PaLM) Api account) y la API de BambooHR. - Activación de Triggers: Pasar el estado del workflow en n8n de
InactiveaActive. - Monitoreo: En caso de errores en la estructura del JSON devuelto por Gemini, el nodo intermedio
Code in JavaScript1yLimpiar textoactuarán como capas de sanitización automáticas.