Módulo 2: Branching y Decisiones Avanzadas
Mini-Proyecto: Árbol de Decisión de 3 Niveles
Descripción de la cápsula
Cierre del módulo. Vas a construir un workflow real que integra todos los patrones de M02: pre-cómputo con Set, filtros en cadena, Switch grandes con agrupación, sub-workflows extraídos, y un fallback robusto. El caso: procesamiento automático de tickets de soporte con árbol de decisión de 3 niveles (categoría → severidad → idioma).
Es un proyecto realista — sistemas de soporte modernos hacen exactamente esto. Al terminar, vas a tener un workflow productivo que demuestra dominio del branching avanzado, y vas a tener experiencia diseñando lógica compleja sin caer en if hell.
Lo que vas a aprender
Al terminar este mini-proyecto serás capaz de:
- ✅ Diseñar un árbol de decisión de 3 niveles antes de implementarlo
- ✅ Aplicar pre-cómputo consistentemente
- ✅ Estructurar Switch jerárquicos sin if hell
- ✅ Extraer ramas a sub-workflows cuando se justifica
- ✅ Validar exhaustivamente con casos por rama
El escenario completo
Lo que recibe el workflow
Tickets de soporte vía Webhook:
{
"ticket_id": "TKT-12345",
"subject": "No puedo iniciar sesión",
"description": "Después de cambiar password no me deja entrar...",
"customer_email": "cliente@ejemplo.com",
"language": "es",
"account_type": "premium",
"received_at": "2026-05-11T14:30:00Z"
}
Lo que debe hacer
Nivel 1: Categorizar (tipo de problema)
auth(login, password, 2FA)billing(cobros, facturas, suscripciones)bug(algo no funciona)general_inquiry(otros)
Nivel 2: Severidad (qué tan urgente)
critical— afecta múltiples usuarios o función core (asignar inmediato)high— cliente premium o impacto serio (asignar prioritario)medium— cliente standard, problema único (cola normal)low— consulta general (auto-respuesta + cola)
Nivel 3: Idioma
es→ equipo españolen→ equipo inglésother→ equipo internacional (con traducción)
Acciones según camino:
- Asignar al equipo correcto
- Notificar canal Slack correspondiente
- Si es crítica: alerta especial
- Registrar en sistema de tickets (mock con Sheet)
Paso 1: Diseñar antes de construir
Antes de tocar n8n, dibuja el árbol en papel o con Excalidraw.
El árbol
Ticket llega
│
├─ Nivel 1: ¿Categoría?
│ ├─ "auth" → ...
│ ├─ "billing" → ...
│ ├─ "bug" → ...
│ └─ "general_inquiry" → ...
│
├─ Nivel 2 (dentro de cada rama): ¿Severidad?
│ ├─ critical/high/medium/low
│
└─ Nivel 3 (dentro): ¿Idioma?
├─ es/en/other
Combinaciones totales
4 categorías × 4 severidades × 3 idiomas = 48 caminos posibles. Si implementaras todos como ramas anidadas literales: caos.
Estrategia: pre-computar una "full_category" como string concatenado (ej. auth_critical_es) y usar Switch único o sub-workflows para manejar.
Paso 2: Implementación del workflow principal
2.1. Workflow nuevo
Nombre: [PROY-G2M02] Router tickets soporte
2.2. Webhook Trigger
Configurar webhook POST con datos de ejemplo pineados (cápsula 03 de M01 te enseña).
2.3. Set de pre-cómputo (cápsula 04)
Set node después del webhook. Calcula todos los campos derivados:
// Field: category
{{
$json.body.subject.toLowerCase().includes('login') ||
$json.body.subject.toLowerCase().includes('password') ||
$json.body.subject.toLowerCase().includes('2fa')
? 'auth' :
$json.body.subject.toLowerCase().includes('cobro') ||
$json.body.subject.toLowerCase().includes('factura') ||
$json.body.subject.toLowerCase().includes('suscripción')
? 'billing' :
$json.body.subject.toLowerCase().includes('error') ||
$json.body.subject.toLowerCase().includes('bug') ||
$json.body.subject.toLowerCase().includes('no funciona')
? 'bug' :
'general_inquiry'
}}
// Field: severity
{{
$json.body.description.toLowerCase().includes('todos los usuarios') ||
$json.body.description.toLowerCase().includes('caído')
? 'critical' :
$json.body.account_type === 'premium' ? 'high' :
$json.body.account_type === 'standard' ? 'medium' :
'low'
}}
// Field: language (puede venir o detectarse)
{{ $json.body.language || 'es' }}
// Field: full_category (la clave para routing)
{{ $json.category + '_' + $json.severity + '_' + $json.language }}
Nota: la detección de categoría aquí es simple (keyword matching). En producción real usarías AI/LLM (cubierto en G6/G7).
2.4. Switch principal
Como tenemos 48 caminos posibles, no listamos los 48 en el Switch. Estrategia:
Opción A: Switch sobre primer nivel + sub-Switches
[Switch sobre category]
├─→ "auth" → [Switch sobre severity] → [Switch sobre language] → ...
├─→ "billing" → ...
├─→ "bug" → ...
└─→ "general_inquiry" → [Send Email autorespuesta]
3 Switches anidados pero estructurados, no if hell.
Opción B: Switch único con menos categorías, lógica adicional en sub-workflows
[Switch sobre category]
├─→ "auth" → [Execute Workflow: [BRANCH] handle-auth]
├─→ "billing" → [Execute Workflow: [BRANCH] handle-billing]
├─→ "bug" → [Execute Workflow: [BRANCH] handle-bug]
└─→ "general_inquiry" → [Execute Workflow: [BRANCH] handle-general]
Cada sub-workflow recibe full_category y maneja la lógica de severidad + idioma internamente.
Para este proyecto: Opción B (más limpio, escalable).
Paso 3: Crear los sub-workflows
Sub-workflow: [BRANCH] handle-auth
Recibe el ticket. Maneja:
[Execute Workflow Trigger]
│
[Switch sobre severity]
├─→ "critical" → [Slack #soporte-urgente-{{language}}] + alert oncall
├─→ "high" → [Slack #soporte-premium-{{language}}]
├─→ "medium" → [Slack #soporte-{{language}}]
└─→ "low" → [Auto-respuesta + Slack #soporte-{{language}}]
(Donde {{language}} se interpola según el campo del ticket.)
Para canales Slack distintos por idioma, podrías:
- Tener canales
#soporte-es,#soporte-en,#soporte-other - Set previo:
slack_channel: "#soporte-" + language - Slack node usa
{{ $json.slack_channel }}
Sub-workflow: [BRANCH] handle-billing
Similar estructura, pero los canales son distintos (#billing-...).
Sub-workflow: [BRANCH] handle-bug
[Execute Workflow Trigger]
│
[Set: agregar contexto técnico]
│
[Switch sobre severity]
├─→ "critical" → [GitHub: create issue] + Slack [#dev-bugs] + escalar a oncall
├─→ "high" → GitHub issue + Slack #dev-bugs
├─→ "medium" → Slack #dev-bugs (sin issue automático)
└─→ "low" → Solo Slack #bugs-cola
Sub-workflow: [BRANCH] handle-general
Más simple — auto-respuesta + agregar a cola normal:
[Execute Workflow Trigger]
│
[Send Email: autorespuesta en {{ language }}]
│
[Sheet: append a "support_queue"]
Paso 4: Registrar todos los tickets
Al final del Workflow principal (después del Switch), siempre registrar el ticket en un Sheet processed_tickets:
[Switch] ...
...
▼
[Set: completar registro]
- full_category
- assigned_team
- processed_at
[Sheet: append "processed_tickets"]
Para que esto funcione, las ramas del Switch deben converger después del procesamiento específico:
[Switch]
├─→ rama A → [proceso A]
├─→ rama B → [proceso B]
└─→ ...
↓ (todas convergen)
[Sheet append: registrar]
O simplemente cada rama hace su Sheet append al final.
Paso 5: Validar con casos
Casos de prueba
Manda al webhook (vía Postman/curl) estos casos:
Caso 1: Auth crítica español
{
"ticket_id": "TKT-001",
"subject": "No puedo iniciar sesión - login caído",
"description": "Todos los usuarios reportan que no pueden entrar",
"customer_email": "admin@cliente.com",
"language": "es",
"account_type": "premium"
}
Esperado:
- category:
auth - severity:
critical - language:
es - Ruta:
handle-auth→ Slack #soporte-urgente-es + alert oncall - Sheet registra
Caso 2: Billing media inglés
{
"ticket_id": "TKT-002",
"subject": "Question about my invoice",
"description": "I see a charge I don't recognize",
"customer_email": "user@example.com",
"language": "en",
"account_type": "standard"
}
Esperado: handle-billing → Slack #billing-en (medium)
Caso 3: Bug premium inglés
{
"ticket_id": "TKT-003",
"subject": "Export feature is broken",
"description": "When I try to export to CSV, nothing happens",
"customer_email": "user@example.com",
"language": "en",
"account_type": "premium"
}
Esperado: handle-bug → Slack #dev-bugs + GitHub issue (high severidad)
Caso 4: Consulta general otro idioma
{
"ticket_id": "TKT-004",
"subject": "How do I add a new user?",
"description": "...",
"customer_email": "user@example.com",
"language": "fr",
"account_type": "standard"
}
Esperado: handle-general → autorespuesta en fr + cola
Caso 5: Severidad calculada vs explícita
Mismo ticket pero con account_type: "premium" vs standard. Verificar que severidad cambia entre high y medium correctamente.
Paso 6: Documentar con Sticky Notes
En el canvas del workflow principal, agrega Sticky Notes:
[Webhook]
│
[Set: pre-cómputo]
│ Sticky Note: "Computa: category, severity, language, full_category.
│ Categorización por keywords en subject. En producción real,
│ usaría LLM para categorización más robusta."
│
[Switch]
│ Sticky Note: "Switch sobre category.
│ Cada rama es un sub-workflow [BRANCH] que maneja severity+language."
│
...
3 meses después, tu yo futuro o un colega entiende el workflow en 30 segundos.
Reflexión: lo que aplicaste
Mira cuántos patrones del módulo usaste:
| Patrón | ¿Dónde lo aplicaste? |
|---|---|
| Pre-cómputo (cápsula 04) | Set inicial con category/severity/language |
| Switch consolidado (cápsula 03) | Switch principal sobre category (4 ramas) |
| Sub-workflows (cápsula 07) | 4 sub-workflows para cada categoría |
| Switch dentro de sub (cápsula 03) | Cada sub tiene Switch sobre severity |
| Categorías derivadas (cápsula 04) | full_category calculada |
| Lookup-style (cápsula 04) | Canales Slack construidos por concatenación |
Todos los patrones del módulo aplicados en un solo workflow real.
Lo que aprendiste en M02 (zoom out)
| Antes de M02 | Después de M02 |
|---|---|
| IF anidados confusos | Pre-cómputo + Switch consolidado |
| 12 IFs en un canvas | Sub-workflows extraídos |
| Condiciones inline complejas | Booleans descompuestos con Set |
| Workflows que rompen al cambiar | Estructura mantenible |
| Sin documentación | Sticky Notes en puntos clave |
Más importante: ahora piensas en estructuras, no solo en nodos.
Resumen y siguiente paso
Lo que construiste:
- Workflow real con árbol de decisión de 3 niveles
- 1 workflow principal + 4 sub-workflows
- 48 caminos lógicos posibles, todos manejados sin if hell
Lo que sabes:
- Pre-cómputo como hábito
- Switch jerárquico vs flat
- Sub-workflows para manejar complejidad
- Tests por rama exhaustivos
Antes de pasar a M03:
- Workflow
[PROY-G2M02]construido y testeado con los 5 casos - Sub-workflows con nombres convencionales
[BRANCH] - Sticky Notes documentando puntos clave
- Sheet
processed_ticketsregistrando todos los items
Lo que sigue (Módulo 3 — Loops y Iteraciones):
Hasta acá, los workflows procesaban N items con iteración implícita (n8n itera automáticamente). M03 te enseña control explícito sobre iteración:
- SplitInBatches para procesar de a N items
- Patrones de loop (procesar todos, hasta cumplir condición, etc.)
- Rate limiting para no saturar APIs externas
- Procesamiento secuencial vs paralelo dentro de loops
Esencial cuando procesas listas grandes (1000+ items) o llamas APIs con rate limits.
Recursos adicionales
- Decision Tree Patterns - Conceptos generales.
- n8n Workflow Templates: Support Ticket Router - Templates similares.
Creado: Mayo 11, 2026 Versión: 1.0