CULTIVA IA · Productividad · Automatización de conocimiento
ls-webhook-custom-data| Criterio | Estado |
|---|---|
| Recurrente (2+ proyectos) | ✓ 3 proyectos |
| No obvio (requirió debugging) | ✓ 2 h debug |
| Ampliamente aplicable | ✓ Stack genérico |
| Solución multi-paso | ✓ 4 pasos |
| Flaggeado por usuario | ✓ Explicit |
--- name: "ls-webhook-custom-data" description: "Fix para Lemon Squeezy webhook que envía custom_data como string JSON-encoded y falla silenciosamente en n8n si falta client_id. Use when: integrando checkout LS con n8n y el flujo de onboarding no dispara sin errores visibles." --- # ls-webhook-custom-data ## Quick Reference | Problema | Solución | |----------|----------| | custom_data llega como string, no objeto | Nodo Set: JSON.parse({{ $json.custom_data }}) | | Flujo no dispara, sin error en logs n8n | Validar client_id en primer nodo con throw explícito | | Error solo visible en callback LS | Habilitar webhook debug log en LS settings | | Silent no-op en nodo If downstream | Añadir nodo Error Trigger como fallback | ## The Problem Lemon Squeezy serializa el campo custom_data como string JSON-encoded antes de enviarlo al webhook — no como objeto nativo. n8n recibe este campo como texto plano y no lo parsea automáticamente, por lo que cualquier acceso a $json.custom_data.client_id devuelve undefined sin lanzar ningún error. El nodo If downstream lo interpreta como condición false y el flujo se detiene silenciosamente. ## Solutions ### Option 1: Nodo Set + JSON.parse (Recomendado) Añadir un nodo Set inmediatamente después del webhook trigger: ```javascript // Expresión n8n en el nodo Set → campo "parsedData" {{ JSON.parse($json.custom_data) }} ``` Luego validar en un nodo Function: ```javascript const data = $input.first().json.parsedData; if (!data?.client_id) { throw new Error('[ls-webhook] client_id ausente en custom_data'); } return [{ json: { ...data } }]; ``` ### Option 2: Code Node con try/catch Para entornos donde no se puede añadir nodos intermedios: ```javascript let customData; try { customData = JSON.parse($json.custom_data ?? '{}'); } catch (e) { throw new Error(`[ls-webhook] custom_data no es JSON válido: ${e.message}`); } if (!customData.client_id) throw new Error('client_id requerido'); return [{ json: customData }]; ``` ## Trade-offs | Enfoque | Pros | Contras | |---------|------|---------| | Nodo Set + Function | Visual, editable sin código | +2 nodos en el flujo | | Code Node único | Compacto, portable | Menos visible para no-devs | | Error Trigger fallback | Captura todos los silent fails | Requiere canal de alertas | ## Edge Cases - custom_data puede ser null: usar $json.custom_data ?? '{}' antes de parsear - Webhooks de test LS: omiten custom_data — añadir guard if ($json.meta?.test_mode) - Reintentos automáticos LS: el webhook reintenta 3× — el throw explícito evita duplicados
ls-webhook-custom-data/ ├── SKILL.md ├── README.md └── reference/ └── examples.md
# Instalar en proyecto actual /plugin install ls-webhook-custom-data # Publicar al hub clawhub publish ./ls-webhook-custom-data
extraer-patron-como-skill · Ejecutado 2026-06-12 · ID 2f90f135