Communityn8ngithub.com

ashtonfeliciano/n8n-workflow-engineer

Construye, depura y robustece flujos de trabajo en n8n. Úsalo cuando edites JSON de flujos, resuelvas fallos silenciosos, trabajes con nodos Code, Telegram, Gmail, HTTP Request, disparadores programados, seguimiento de elementos emparejados, deduplicación con datos estáticos o realices operaciones masivas mediante la API REST de n8n. Cubre la interfaz específica de v2.x. No apto para automatizaciones que no usen n8n.

¿Qué es n8n-workflow-engineer?

Este skill está diseñado para desarrolladores e ingenieros que trabajan con n8n, la plataforma de automatización de flujos de trabajo. Proporciona un conjunto completo de pautas, soluciones a problemas comunes y patrones de implementación probados que cubren desde la edición segura de JSON hasta la depuración de fallos silenciosos. Soporta nodos críticos como Code, Telegram, Gmail, HTTP Request, Switch y Merge, así como las peculiaridades de la interfaz v2.x. Explica en detalle cómo manejar la deduplicación con datos estáticos (staticData), el seguimiento de elementos emparejados (paired items), las reglas de modo/retorno de los nodos Code, y ofrece recetas para operaciones masivas mediante la API REST de n8n. También incluye advertencias sobre anti-patrones comunes y estrategias de observabilidad mediante contadores de pipeline. Es útil tanto para depuración reactiva como para diseño proactivo de flujos robustos.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ashtonfeliciano/claude-skills-pack/tree/HEAD/skills/n8n-workflow-engineer

Installed? Explore more n8n skills: ashtonfeliciano/n8n-evaluations-runner, hubgunter4-ops/configurador-de-nodos-n8n, hubgunter4-ops/experto-en-n8n-mcp · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

n8n Workflow Engineer

Cuándo activarlo

  • Editar o construir JSON de flujo de trabajo en n8n
  • Depurar n8n: "el nodo no se ejecuta", "elemento emparejado no disponible", "los datos estáticos no persisten"
  • Operaciones masivas (renombrar, reintentar, eliminar) mediante la API REST de n8n
  • Patrones de nodos Telegram, Gmail, HTTP Request, Code, Switch, Merge
  • Comportamiento de disparadores programados / zona horaria / cron en n8n
  • Comportamiento de la interfaz de n8n v2.x (Publicar/Despublicar, Archivar)

Reglas estrictas

  1. Auditar antes de editar. Leer el JSON completo del flujo → presentar hallazgos → confirmar → aplicar en una sola pasada. Nunca parchear a ciegas.
  2. Probar mediante disparador programado. La ejecución manual reinicia $workflow.staticData. La prueba de deduplicación requiere una ejecución real de cron.
  3. Verificar el resultado real. Revisar el registro de ejecución y el estado final (el mensaje llegó, la fila existe). Que un nodo devuelva ok: true es una buena señal, no una prueba. El desfase de sincronización de la interfaz engaña a los observadores.
  4. Hacer coincidir el modo del nodo Code con la firma de retorno. Un modo incorrecto + un retorno incorrecto = procesamiento parcial silencioso.

Referencia rápida: los errores más comunes

SíntomaCausa raízSolución
HTTP Request a localhost:4000 devuelve rechazo/tiempo de esperan8n en modo puente DockerUsar el gateway del host: a menudo 172.17.0.1 en el puente predeterminado (verificar con docker network inspect bridge), o mapear host.docker.internal:host-gateway en extra_hosts
El mensaje de Telegram nunca llega, sin errorTiempo de espera por resolución de IPv6 DNSNODE_OPTIONS=--dns-result-order=ipv4first en docker-compose
new Date() devuelve UTC a pesar de tener cron en ESTEl contenedor carece de la variable de entorno TZEstablecer tanto TZ como GENERIC_TIMEZONE a tu zona horaria
parse_mode: Markdown falla silenciosamente o distorsiona* o _ no emparejados en la salida de IAUsar parse_mode: HTML + sanitizar antes de enviar
401 en el nodo HTTP Request a LiteLLMFalta el encabezado de autenticaciónAñadir Authorization: Bearer {{ $env.LITELLM_API_KEY }}
ECONNABORTED: timeout of 15000ms en llamada a ClaudeTiempo de espera predeterminado de 15sEstablecer options.timeout: 90000
PUT a /api/v1/workflows/:id devuelve 400Campos adicionales en el cuerpoLimpiar a solo: name, nodes, connections, settings, staticData
Renombrar un nodo rompe el flujo silenciosamenteLas referencias de conexiones usan el nombre antiguoReemplazar_todo el nombre antiguo tanto en nodes[].name como en las claves de connections{}
Elemento emparejado no disponible después de agregación con CodeLa transformación N→1→M perdió la línea de elementosEstablecer executeOnce: true, iterar $('UpstreamNode').all() explícitamente
La deduplicación con datos estáticos "no funciona" en ejecución manualLa ejecución manual reinicia los datos estáticosProbar solo con cron programado

Nodo Code: reglas de modo/retorno

Cada nodo Code tiene un parámetro mode. La discrepancia provoca errores silenciosos.

ModoPatrón de accesoRetorno
runOnceForAllItems (predeterminado)const items = $input.all();return items.map(...) — debe ser un array
runOnceForEachItem$json es el elemento actualreturn { json: ... } — objeto único, NO un array

Síntomas de discrepancia:

  • runOnceForAllItems + acceder a $json → solo se procesa el primer elemento silenciosamente
  • runOnceForEachItem + devolver un array → error de validación "A 'json' property isn't an object"

Patrón de deduplicación (estado entre ejecuciones)

const store = $getWorkflowStaticData('global');
store.jobIds = store.jobIds || [];

const newItems = items.filter(item => !store.jobIds.includes(item.json.id));

// Persistir nuevos IDs, limitar a los últimos 500 para evitar crecimiento sin control
store.jobIds = [...store.jobIds, ...newItems.map(i => i.json.id)].slice(-500);

return newItems;

Importante: staticData persiste únicamente en ejecuciones programadas. La ejecución manual lo reinicia. Verifica la deduplicación observando dos ejecuciones programadas consecutivas, no haciendo clic en "Ejecutar" dos veces.

Limpieza de caché por ejecución

// Al inicio del primer nodo Code — limpiar cachés transitorias pero preservar el estado entre ejecuciones
const store = $getWorkflowStaticData('global');
for (const k of Object.keys(store)) {
  if (k.startsWith('cjob_') || k.startsWith('cprep_') || k === 'pendingJobs') {
    delete store[k];
  }
}
// NUNCA eliminar jobIds — la deduplicación entre ejecuciones depende de ello

Patrón de observabilidad del pipeline

Establecer contadores en cada nodo Code importante. Leer en el paso de formateo. Añadir al mensaje.

// Etapa 1 — Construir Tickers
const store = $getWorkflowStaticData('global');
store.pipeline = { ticker_count: tickers.length, fixed_count: fixed.length };

// Etapa 2 — Calcular Señales
store.pipeline = store.pipeline || {};
store.pipeline.signal_count = results.length;

// Final — Formatear mensaje
const pl = store.pipeline || {};
const pf = (n) => (n === undefined || n === null) ? '?' : String(n);
const pipelineBlock =
  '\n\n📊 Pipeline\n' +
  'Build Tickers:   ' + pf(pl.ticker_count) + '\n' +
  'Señales:         ' + pf(pl.signal_count);

Problema de elementos emparejados y solución

Síntoma: Después de un nodo de agregación (N elementos → 1 prompt → 1 respuesta de LLM → dividir en M elementos), el acceso $('UpstreamNode').item.json aguas abajo lanza "Paired item data for item from node 'X' is unavailable".

Soluciones (en orden de preferencia):

  1. Establecer executeOnce: true en el nodo Code aguas abajo, iterar explícitamente:

    const upstream = $('UpstreamNode').all();
    const outputs = [];
    for (let i = 0; i < parsed.length; i++) {
      outputs.push({ json: { ...parsed[i], original: upstream[i].json } });
    }
    return outputs;
    
  2. Pasar IDs a través de datos estáticos; buscarlos explícitamente aguas abajo.

  3. pairedItem.sourceOverwrite — frágil, último recurso.

Patrones de Telegram

Modo HTML: solo se permiten 7 etiquetas

<b>, <i>, <u>, <s>, <a>, <code>, <pre> — cualquier otra produce 400 Bad Request: Unsupported start tag.

Defensa de tres capas para contenido generado por IA

  1. Prompt: indicar explícitamente a la IA qué etiquetas están permitidas
  2. Sanitizar: eliminar etiquetas no soportadas en el código antes de enviar
  3. Escapar: escapar HTML del contenido de usuario/IA (& → &amp;, < → &lt;, > → &gt;) antes de incrustar

Suprimir pie de atribución de n8n

"additionalFields": {
  "parse_mode": "HTML",
  "appendAttribution": false,
  "disable_web_page_preview": true
}

Token en .env vs credential

Preferir el patrón de variable de entorno + HTTP Request sobre el nodo integrado de Telegram + credencial:

  • Portátil entre migraciones
  • Más fácil de rotar (nano .env + reinicio del contenedor)
  • Sin riesgo de bloqueo por clave de cifrado de BD
  • Patrón: POST https://api.telegram.org/bot{{ $env.BOT_TOKEN }}/sendMessage
  • Compensación: el token reside en la URL de la solicitud, por lo que puede aparecer en datos de ejecución, registros de proxy y mensajes de error. Desactivar el guardado de datos de ejecución para este flujo, o usar la credencial integrada de Telegram si otras personas pueden leer tus registros.

Patrones de OAuth de Gmail

ProblemaResolución
invalid_grant ... refresh token revokedOAuth en modo "Pruebas" expira ~7 días. Re-autenticar mediante la interfaz, o publicar la app en Producción.
payload.headers vacío (De/Asunto en blanco)El valor predeterminado simple: true elimina encabezados. Establecer options.simple: false.
Faltan alertas de seguridad / recibosNo excluir -category:promotions -category:social -category:updates — Gmail dirige el 90% del correo relevante allí. Usar solo is:unread newer_than:Nd.
Necesidad de marcar como leído en varias cuentasSe necesitan credenciales por cuenta. Una sola credencial de Gmail no puede operar sobre IDs de mensajes de otra cuenta.

Patrones de API REST (operaciones masivas)

Autenticación: Encabezado X-N8N-API-KEY: <key>.

EndpointNotas
GET /api/v1/workflowsDevuelve todos (paginados). Filtrar del lado del cliente.
GET /api/v1/workflows/:idJSON completo del flujo.
PUT /api/v1/workflows/:idEstricto: solo name, nodes, connections, settings, staticData. settings tiene una lista blanca (ver abajo). Eliminar todo lo demás en un ciclo GET→PUT.
DELETE /api/v1/workflows/:idRealmente elimina (la interfaz solo ofrece Archivar). Útil para limpieza masiva.
POST /api/v1/workflows/:id/activateSimilar a Publicar en la interfaz v2.x.

Lista blanca del campo settings (cuerpo PUT)

executionOrder, timezone, saveExecutionProgress, saveDataErrorExecution, saveDataSuccessExecution, saveManualExecutions, callerPolicy, callerIds, errorWorkflow, executionTimeout

El type del nodo es inmutable después de la creación

Un PUT que cambie node.type devuelve 200 pero el tipo permanece igual. Para convertir (ej. telegram → httpRequest): reemplazar el objeto completo del nodo (nuevo UUID para id, mismo name). Las conexiones se enrutan por nombre, por lo que el reemplazo que preserva el nombre es seguro.

Particularidades de la interfaz n8n v2.x

Antiguo (v1.x)Nuevo (v2.x)
Interruptor ActivarPublicar (botón verde, arriba a la derecha) / Despublicar
Eliminar flujoSolo Archivar (usar API REST para eliminación real)

Nodo HTTP Request: imprescindibles para llamadas a LLM

{
  "method": "POST",
  "url": "http://172.17.0.1:4000/v1/chat/completions",
  "sendHeaders": true,
  "headerParameters": {
    "parameters": [
      {"name": "Content-Type", "value": "application/json"},
      {"name": "Authorization", "value": "=Bearer {{ $env.LITELLM_API_KEY }}"}
    ]
  },
  "sendBody": true,
  "contentType": "raw",
  "rawContentType": "application/json",
  "body": "={{ JSON.stringify({model:'<tu-alias-modelo>',messages:[{role:'user',content:$json.prompt}],temperature:0.3}) }}",
  "options": {
    "timeout": 90000,
    "retry": { "tries": 2, "waitBetweenTries": 5000 }
  }
}

El contenedor de n8n no tiene curl

Para pruebas HTTP dentro del contenedor, usar el módulo https integrado de Node mediante docker exec:

docker exec n8n node -e "const https=require('https'); /* solicitud */"

Pre-vuelo SSH (antes de cualquier heredoc en VPS)

ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=10 <usuario>@<host>
# Verificar prompt: [<usuario>@<host> ...]$
# SOLO ENTONCES pegar el heredoc

Pegar un heredoc de bash en PowerShell después de una caída SSH = cientos de errores de análisis sintáctico.

Patrón de suite de evaluación (solo lógica)

Las pruebas con entradas simuladas mediante la función de Evaluaciones de n8n detectan regresiones lógicas sin gastar créditos de API. Volver a ejecutar ANTES Y DESPUÉS de cualquier cambio en la lógica de filtrado, listas de palabras clave o reglas de validación.

Anti-patrones

Anti-patrónQué hacer en su lugar
"Ejecútalo otra vez, a ver si funciona"Leer el registro de ejecución de principio a fin primero
Parchear un nodo a la vez en múltiples rondasAuditar archivo completo → script de parches agrupados → verificar en una sola pasada
Usar parse_mode: Markdown para salida de IAparse_mode: HTML + sanitizador
Codificar claves de API / IDs de chat en el JSON del flujoReferenciar {{ $env.KEY }}, almacenar en <archivo-secreto> (chmod 600)
Renombrar nodos sin actualizar conexionesreplace_all en el nombre del nodo tanto en nodes[].name como en las claves de connections{}
Ejecución manual para probar deduplicaciónEsperar al disparador programado
Tiempo de espera predeterminado de httpRequest para llamadas a LLMEstablecer mínimo de 90000ms
Mezclar runOnceForAllItems y $jsonHacer coincidir modo con patrón de acceso

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Skills relacionados

ashtonfeliciano/n8n-evaluations-runner

Build and run zero-API-cost logic test suites for n8n workflows. Use when adding test coverage to filter logic, scoring functions, validators, keyword lists, resume maps, or any pure-JS code-node logic. Outputs grouped pass/fail/pending report via Telegram. Run before AND after any logic change to catch regressions without burning API credits.

community

hubgunter4-ops/configurador-de-nodos-n8n

Ayuda a configurar nodos de n8n con reglas de dependencia complejas y conexiones de IA. Agiliza la creación de flujos de trabajo automatizados gestionando dependencias de nodos intrincadas e integraciones de IA.

community

hubgunter4-ops/experto-en-n8n-mcp

Guía a los desarrolladores a seleccionar y configurar herramientas y formatos de nodo del Protocolo de Contexto de Modelo MCP dentro de los flujos de trabajo de n8n. Proporciona orientación estructurada para integrar herramientas MCP.

community

caiqueDeOliveira-dev/homelab

HomeLab Agent — Gerencia Home Assistant, ESP32 satellites, dispositivos Zigbee/Matter/Thread, automações físicas, cameras, sensores. Camada de decisão e execução no hardware (não orquestração de software = Automação/n8n).

community

hubgunter4-ops/experto-en-n8n-mcp

Guía a los desarrolladores a seleccionar y configurar herramientas y formatos de nodo del Protocolo de Contexto de Modelo MCP dentro de los flujos de trabajo de n8n. Proporciona orientación estructurada para integrar herramientas MCP.

community

hubgunter4-ops/experto-en-validacion-de-n8n

Corrige errores de validación de n8n consultando un catálogo de errores integrado. Optimiza el proceso de depuración, permitiendo identificar rápidamente problemas y resolver problemas de configuración del flujo de trabajo.

community