| name | n8n |
| description | Design and debug n8n workflows using nodes, expressions, credentials, and the Code node (JavaScript/Python) for self-hosted or cloud automation pipelines. Use when "create n8n workflow", "n8n webhook", "n8n expression", "n8n node", "automate with n8n", "n8n http request", "n8n schedule", "n8n code node", "n8n credential", "n8n self-hosted", "trigger n8n flow", "n8n error handling". |
| metadata | {"openclaw":{"emoji":"🦾","requires":{"env":[]}}} |
n8n Skill
Rick puede asistir en el diseño, depuración y mantenimiento de workflows n8n — tanto en instancia self-hosted como en n8n Cloud.
Documentación oficial: https://docs.n8n.io/
Tasks del Worker cubiertas por esta skill
n8n.list_workflows
n8n.get_workflow
n8n.create_workflow
n8n.update_workflow
n8n.post_webhook
Conceptos fundamentales
| Concepto | Descripción |
|---|
| Workflow | Conjunto de nodos conectados que procesan datos |
| Node | Bloque de acción o disparador. Produce ítems de salida |
| Item | Unidad de dato que fluye entre nodos (objeto JSON) |
| Trigger node | Nodo que inicia el workflow (webhook, cron, evento) |
| Regular node | Nodo de procesamiento/acción invocado después del trigger |
| Expression | Valor dinámico calculado con {{ }} en parámetros |
| Credential | Autenticación almacenada de forma segura para servicios externos |
| Execution | Una corrida del workflow (manual, trigger, programada) |
Expresiones n8n
Nodos core más usados
Triggers
| Nodo | Cuándo usar |
|---|
| Webhook | Recibir llamadas HTTP POST/GET desde sistemas externos |
| Schedule Trigger | Ejecutar según cron (ej: 0 8 * * 1-5 = lun-vie 8:00) |
| Manual Trigger | Ejecución manual durante desarrollo/testing |
| Email Trigger (IMAP) | Trigger cuando llega un email |
| RSS Read | Monitorear feeds RSS |
Procesamiento y lógica
| Nodo | Uso |
|---|
| HTTP Request | Llamar cualquier API REST/HTTP |
| Code | Ejecutar JavaScript o Python personalizado |
| Set | Crear/modificar campos en los ítems |
| If | Bifurcación condicional (true/false) |
| Switch | Múltiples ramas según valor |
| Merge | Combinar datos de múltiples ramas |
| Split In Batches | Procesar ítems en grupos (evitar rate limits) |
| Filter | Filtrar ítems que cumplan condición |
| Aggregate | Agrupar múltiples ítems en uno |
| Loop Over Items | Iterar sobre un array dentro de un ítem |
| Wait | Pausar ejecución por tiempo o hasta evento |
| Edit Fields (Set) | Mapear y transformar campos |
Integraciones comunes
| Nodo | Servicio |
|---|
| OpenAI | GPT-4, embeddings, Assistants |
| Slack | Mensajes, canales, usuarios |
| Gmail | Leer, enviar, etiquetar emails |
| Google Sheets | Leer, escribir, actualizar hojas |
| Notion | Crear páginas, actualizar propiedades |
| Airtable | CRUD en bases Airtable |
| GitHub | Issues, PRs, repositorios |
| Telegram | Enviar mensajes, bots |
| MySQL / PostgreSQL | Queries SQL |
| Redis | Get, Set, Push en Redis |
| HTTP Request | Cualquier API personalizada |
Expresiones (Expressions)
Las expresiones se escriben entre {{ }} en cualquier campo de parámetro:
Acceder a datos de nodos anteriores
Acceder a datos del nodo anterior
{{ $json.nombre }}
{{ $json.email }}
{{ $json["campo con espacio"] }}
{{ $node["HTTP Request"].json.data.id }}
{{ $node["Webhook"].json.body.payload }}
{{ $node["Google Sheets"].json[0].Title }}
{{ $input.first().json.event_type }}
{{ $input.all() }}
Variables de entorno y workflow
{{ $env.MI_API_KEY }}
{{ $workflow.id }}
{{ $workflow.name }}
{{ $execution.id }}
{{ $now }}
{{ $today }}
Luxon — Fechas y tiempo
{{ $now.toISO() }}
{{ $now.toFormat('dd/MM/yyyy') }}
{{ $now.plus({days: 7}).toISO() }}
{{ $now.minus({hours: 2}).toISO() }}
{{ $now.startOf('month').toISO() }}
{{ $now.toUTC().toISO() }}
{{ DateTime.fromISO($json.fecha).toFormat('yyyy') }}
Transformaciones de texto
{{ $json.nombre.toUpperCase() }}
{{ $json.email.toLowerCase() }}
{{ $json.texto.replace(/\n/g, ' ') }}
{{ $json.nombre.split(' ')[0] }}
{{ `Hola, ${$json.nombre}!` }}
JMESPath — Consultas en JSON
{{ $jmespath($json, "items[?status=='active'].name") }}
{{ $jmespath($json, "orders | length(@)") }}
Nodo Code (JavaScript/Python)
JavaScript — Run Once for All Items
const results = [];
for (const item of items) {
const data = item.json;
results.push({
json: {
id: data.id,
nombre: data.nombre.trim().toUpperCase(),
total: data.precio * data.cantidad,
timestamp: new Date().toISOString()
}
});
}
return results;
JavaScript — Run Once for Each Item
const data = $input.item.json;
return {
json: {
procesado: true,
valor_doble: data.valor * 2,
categoria: data.valor > 1000 ? 'alto' : 'bajo'
}
};
Python (Code node)
results = []
for item in _input.all():
data = item.json
results.append({
"json": {
"nombre": data.get("nombre", "").upper(),
"total": data.get("precio", 0) * data.get("cantidad", 0)
}
})
return results
Nodos principales
Webhook — Configuración
Responder al webhook desde n8n:
{
"status": "ok",
"message": "Procesado exitosamente",
"execution_id": "{{ $execution.id }}"
}
Transformación de datos
Credenciales — Configuración
Tipos más comunes:
- Header Auth:
Name: Authorization, Value: Bearer <token>
- Basic Auth: usuario + contraseña
- OAuth2: flujo OAuth estándar con callback a n8n
- API Key: clave en header o query param
Crear credencial: Configuración → Credenciales → + Nueva credencial
Usar en expresiones: {{ $credentials.MiCredencial.apiKey }} (solo en Code node)
docker-compose.yml mínimo
version: '3.8'
services:
n8n:
image: docker.n8n.io/n8nio/n8n:latest
restart: always
ports:
- "5678:5678"
environment:
- N8N_HOST=tu-dominio.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://tu-dominio.com/
- N8N_ENCRYPTION_KEY=clave-secreta-32-chars
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=admin
- N8N_BASIC_AUTH_PASSWORD=password-seguro
- N8N_SECURE_COOKIE=false
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=n8n_password
volumes:
- n8n_data:/home/node/.n8n
postgres:
image: postgres:15
environment:
POSTGRES_DB: n8n
POSTGRES_USER: n8n
POSTGRES_PASSWORD: n8n_password
volumes:
- postgres_data:/var/lib/postgresql/data
Workflow Principal
└── En caso de error → Ejecuta Error Workflow
├── Obtiene detalles del error
├── Envía notificación (email, Slack, Telegram)
└── Registra en Notion/Airtable
Activar: `Configuración del workflow → Error Workflow → Seleccionar workflow`
### Try/Catch con nodo If
[Acción riesgosa]
├── Success → Continuar flujo normal
└── Error → [If: $execution.error != null]
├── Sí → Manejar error, notificar
└── No → No aplica
### En nodo Code:
```javascript
try {
const response = await fetch($env.API_URL);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
return [{ json: data }];
} catch (error) {
return [{ json: { error: true, message: error.message } }];
}
Self-Hosted n8n
Instalación con Docker
docker run -d \
--name n8n \
-p 5678:5678 \
-e N8N_BASIC_AUTH_ACTIVE=true \
-e N8N_BASIC_AUTH_USER=admin \
-e N8N_BASIC_AUTH_PASSWORD=changeme \
-e N8N_HOST=tu-dominio.com \
-e N8N_PROTOCOL=https \
-e WEBHOOK_URL=https://tu-dominio.com/ \
-v ~/.n8n:/home/node/.n8n \
n8nio/n8n
Variables de entorno clave
N8N_PORT=5678
N8N_PROTOCOL=https
N8N_HOST=tu-dominio.com
WEBHOOK_URL=https://tu-dominio.com/
N8N_ENCRYPTION_KEY=clave-aleatoria-larga
DB_TYPE=postgresdb
EXECUTIONS_DATA_PRUNE=true
EXECUTIONS_DATA_MAX_AGE=336
CLI commands
n8n execute --id <workflow-id>
n8n export:workflow --all --output=./workflows-backup/
n8n import:workflow --input=./workflows-backup/
n8n export:credentials --all --output=./credentials-backup.json
Integración con Umbral Agent Stack
n8n puede actuar como orquestador externo que dispara tareas al Worker de Umbral:
{
"task_type": "research.web",
"input": {
"query": "{{ $json.search_query }}",
"max_results": 5
},
"callback_url": "{{ $env.N8N_WEBHOOK_URL }}/webhook/resultado"
}
Schedule → Fetch → Transform → Store
[Schedule 0 8 * * *] → [HTTP Request: GET /api/datos] →
[Code: transformar] → [Google Sheets: append rows]
Fan-out con Merge
[Trigger] → [Split In Batches] → [Loop: HTTP Request por item] →
[Aggregate: consolidar resultados] → [Notion: crear página con resumen]
Error handling con Try/Catch
[Nodo con riesgo] → (en caso de error) → [Error Trigger] →
[Telegram: notificar error] → [Set: registrar en log]
Errores frecuentes
| Error | Causa | Solución |
|---|
Cannot read property of undefined | Campo inexistente en $json | Usar $json.campo ?? 'default' o verificar con if ($json.campo) |
Workflow could not be started | Trigger no activo | Activar el workflow (toggle ON en la lista) |
Webhook not registered | n8n reiniciado sin reload | Desactivar y reactivar el workflow |
Credential not found | Credencial eliminada o mal referenciada | Verificar nombre en Credenciales y reasignar en el nodo |
ECONNREFUSED | Servicio externo no disponible | Agregar nodo Wait + retry loop, o verificar URL |
Too many requests (429) | Rate limit alcanzado | Usar Split in Batches + Wait entre lotes |
Execution timeout | Workflow tarda demasiado | Aumentar EXECUTIONS_TIMEOUT o dividir en subworkflows |
Expression Error | Sintaxis incorrecta en expresión | Revisar {{ }}, comillas y nombres de nodo exactos |
Buenas prácticas
- Nombrar nodos descriptivamente:
Get User Data en lugar de HTTP Request 3.
- Usar Sticky Notes para documentar lógica compleja dentro del workflow.
- Variables de entorno para URLs, tokens y configuraciones cambiables.
- Error Workflow configurado para todos los workflows productivos.
- Sub-workflows: encapsular lógica reutilizable en workflows separados y llamarlos con el nodo Execute Workflow.
- Logging: agregar nodo Code con
console.log durante desarrollo, o nodo Notion/Airtable para audit trail en producción.
- Split in Batches antes de acciones con rate limit (APIs, email masivo).
- Pinning de datos: en desarrollo, "pinear" datos de salida de nodos para iterar sin re-ejecutar triggers.
API de n8n (para integración)
GET /api/v1/workflows
Authorization: Bearer <N8N_API_KEY>
POST /api/v1/workflows/{id}/execute
Content-Type: application/json
{"runData": {}}
GET /api/v1/executions?workflowId={id}&status=success
GET /api/v1/workflows/{id}/webhook-urls
Documentación oficial