Subir archivos a "/"

This commit is contained in:
2026-06-16 15:20:01 +00:00
parent ad2c54217f
commit c71b3598ae
+237
View File
@@ -0,0 +1,237 @@
# 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:**
```javascript
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):**
```json
{
"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):**
```javascript
{{
(() => {
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:
```text
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:
```json
{
"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.