Files
encuesta-terminacion-volunt…/documentacion_workflow_n8n.md
T
2026-06-16 15:20:01 +00:00

13 KiB
Raw Blame History

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 (visibles en la estructura del flujo de image_ec77fb.jpg):

  1. Fase de Envío Automatizado: Identifica bajas voluntarias del sistema central (BambooHR) y envía la encuesta formal de manera automatizada.
  2. 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).
  3. 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

De acuerdo al archivo técnico y a la imagen de referencia image_ec77fb.jpg, 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)

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 credenciales GLM 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

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.agent conectado a lmChatGoogleGemini.
  • 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.set y n8n-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

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

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_completo y el nuevo motivo. 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

  1. 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.
  2. Activación de Triggers: Pasar el estado del workflow en n8n de Inactive a Active.
  3. Monitoreo: En caso de errores en la estructura del JSON devuelto por Gemini, el nodo intermedio Code in JavaScript1 y Limpiar texto actuarán como capas de sanitización automáticas.