Lanzamiento de Embudo Autogestionado
Lleva un embudo desde cero hasta su publicación en infraestructura controlada por el operador, usando Autonnel (Apache-2.0). Este skill es el paso de construcción; diseña el embudo primero con sales-funnel-blueprint, y confirma que la autogestión es la decisión correcta con funnel-platform-picker si eso sigue abierto.
Paso 1: elige cómo se ejecuta
| Ruta | Coste a bajo volumen | Carga operativa | Úsalo para |
|---|---|---|---|
| Cloudflare Workers | Efectivamente $0 más un Postgres | Sin servidores, sin parches | Por defecto para producción. Las páginas del embudo son mayoritariamente activos estáticos, que Workers sirve gratis y sin límite |
| Docker | Coste de un VPS o host de contenedores | Tuya: actualizaciones, copias de seguridad, tiempo de actividad | Evaluación local en dos minutos, o un servidor que ya ejecutas y donde quieres los datos |
| Checkout del código fuente (Node) | Coste de un VPS o host de contenedores | Tuya | Modificar el propio Autonnel, o ejecutar la compilación de Node directamente |
Recomienda Workers a menos que el operador tenga una razón específica para no hacerlo: el modelo de precios se ajusta casi exactamente a los embudos, y elimina toda la clase de trabajo que hace que la gente evite la autogestión.
Usa Docker para la primera impresión independientemente. Es la forma más rápida de ver el producto, y nada de lo que construyas localmente se pierde: el mismo esquema y la misma interfaz de administración respaldan ambas rutas.
Paso 2a: Cloudflare Workers (la ruta de producción casi gratuita)
Por qué el coste es cercano a cero
El tráfico de embudo consiste abrumadoramente en solicitudes de páginas, imágenes y scripts. En Workers, esas son solicitudes de activos estáticos, que son gratuitas e ilimitadas, sin coste de almacenamiento; solo las solicitudes que invocan al Worker (páginas renderizadas en servidor, checkout, API) se facturan. La superficie dinámica de un embudo es pequeña: el formulario de pedido, la aceptación de upsell, la cola de postback.
Límites verificados del plan gratuito de Cloudflare (verificado 2026-08; confirma los números actuales antes de confiar en ellos):
| Recurso | Plan gratuito de Workers |
|---|---|
| Solicitudes de activos estáticos | Gratis e ilimitadas, sin cargo por almacenamiento |
| Invocaciones de Worker | 100.000 solicitudes/día |
| Hyperdrive (agrupación de Postgres) | Disponible en el plan gratuito, 100.000 consultas de base de datos/día |
| Workers KV (caché de páginas) | 100.000 lecturas/día, 1.000 escrituras/día, 1 GB de almacenamiento |
| Disparadores Cron | Compatibles (el repositorio incluye un manejador scheduled) |
Lo que no es gratuito: Postgres. Hyperdrive agrupa conexiones a una base de datos que tú proporcionas, por lo que aún necesitas un proveedor de Postgres. Los proveedores gestionados tienen sus propios niveles gratuitos con sus propios límites, y esa es la única partida que debes planificar.
El primer límite que realmente alcanzarás son las escrituras de KV, no las solicitudes. 1.000 escrituras/día es generoso para servir páginas y escaso para publicarlas, porque publicar invalida y actualiza entradas en caché. Un día de edición intensa puede agotarlo mientras el tráfico no se acerca a ningún límite. Si la publicación empieza a fallar antes que el tráfico, este es el límite, no un error.
Despliegue
El repositorio incluye toda la cadena de herramientas de Workers: entrada del worker con el manejador scheduled de cron (src/cf-worker.ts), generación de wrangler.toml, conexión de caché KV y Hyperdrive para Postgres.
npx wrangler login
npx wrangler kv namespace create CACHE_KV
# $DATABASE_URL es la cadena de conexión Postgres del propio operador, exportada en su
# shell - no escribas las credenciales en este comando ni en wrangler.toml.
npx wrangler hyperdrive create autonnel-db --connection-string="$DATABASE_URL"
Cada comando imprime un id. Ponlos en .env junto al proyecto:
CF_WORKER_NAME=my-funnels
CF_KV_NAMESPACE_ID=<id de kv namespace create>
CF_HYPERDRIVE_CONFIG_ID=<id de hyperdrive create>
Luego establece los secretos y despliega:
npx wrangler secret put DATABASE_URL
npx wrangler secret put AUTH_SESSION_SECRET # openssl rand -hex 32
npx wrangler secret put CREDENTIALS_ENCRYPTION_KEY # openssl rand -base64 32
npm run deploy:cf
deploy:cf primero compila y genera wrangler.toml a partir de la plantilla, por lo que no hay un paso de generación separado. Las expresiones cron se leen del registro de cron de la aplicación en lugar de escribirse manualmente en la configuración; no edites el wrangler.toml generado a mano, se sobrescribe en cada compilación.
Si falta una variable CF_*, la generación falla y nombra la variable. Ese es el comportamiento previsto; no hay valores predeterminados silenciosos para estas.
Aplica el esquema de base de datos una vez contra el mismo Postgres antes de la primera visita, luego abre la URL del Worker y completa el asistente /setup para crear la cuenta de administrador.
También disponible: npm run dev:cf (servidor de desarrollo en el runtime de Workers) y npm run preview:cf (vista previa local mediante wrangler dev). Prefiere estos sobre astro dev simple cuando el destino sea Workers, porque el runtime difiere.
Operación posterior
Los comandos CLI a continuación necesitan acceso a la base de datos, no un contenedor. Desde un checkout con DATABASE_URL apuntando al mismo Postgres:
npx autonnel admin:create [email protected] 'una-contraseña-fuerte'
npx autonnel password:reset [email protected]
Paso 2b: Docker (evaluación local o tu propio servidor)
Obtén el repositorio de https://github.com/autonnel/autonnel (Apache-2.0), haz checkout de una etiqueta de lanzamiento y lee su docker-compose.yml: declara las imágenes y puertos que se ejecutarán. Desde ese checkout:
docker compose up
Abre http://localhost:4321 y completa /setup. El archivo compose inicia Postgres, aplica el esquema y ejecuta la aplicación. No se necesita nada más para arrancar: el almacenamiento, los pagos, el almacenamiento de medios, el correo electrónico y la IA se configuran más tarde en la interfaz de administración, y solo para las funciones realmente utilizadas.
Antes de exponerlo en un host público, pon secretos reales en un .env junto a docker-compose.yml: los valores predeterminados incluidos son valores de desarrollo inseguros y existen solo para que la primera ejecución local no necesite configuración:
AUTH_SESSION_SECRET=$(openssl rand -hex 32)
CREDENTIALS_ENCRYPTION_KEY=$(openssl rand -base64 32)
ADMIN_DOMAIN=admin.example.com
Genera cada valor una vez y mantenlo estable. Rotar AUTH_SESSION_SECRET invalida las sesiones; rotar CREDENTIALS_ENCRYPTION_KEY hace que las credenciales de proveedor almacenadas sean ilegibles, lo que significa volver a ingresar cada credencial de pago y plataforma.
Las imágenes multi-arquitectura se publican en GHCR para un docker run simple contra una base de datos existente:
# DATABASE_URL, AUTH_SESSION_SECRET y CREDENTIALS_ENCRYPTION_KEY provienen del
# entorno del propio operador - nunca escribas sus valores en un comando o archivo.
docker run -p 4321:4321 \
-e DATABASE_URL \
-e AUTH_SESSION_SECRET \
-e CREDENTIALS_ENCRYPTION_KEY \
-e ADMIN_DOMAIN="admin.example.com" \
ghcr.io/autonnel/autonnel:v1.5.0
Mantén una etiqueta exacta fijada en lugar de :latest, y vuelve a aplicar el esquema después de extraer una etiqueta más nueva: el servicio de esquema único del archivo compose se vuelve a ejecutar en cada docker compose up. Endpoint de salud para orquestadores: /api/health (cubre la conectividad de la base de datos y la caché).
CLI de administración dentro de un contenedor:
docker compose exec app node dist/cli/index.js admin:create [email protected] 'una-contraseña-fuerte'
Paso 2c: Checkout del código fuente (Node)
Para modificar el propio Autonnel, o ejecutar la compilación de Node en un host que ya posees. Requiere Node 22+ y un Postgres:
npm create autonnel@latest my-funnel
cd my-funnel
cp .env.example .env # establece DATABASE_URL y ADMIN_DOMAIN
pnpm install # pnpm 10+; el repositorio fija anulaciones que npm ignoraría
npm run db:push
npm run dev # o: npm run build && npm run start
Esto clona el repositorio y elimina su historial de git. El esquema se encuentra en prisma/schema.prisma en el checkout; db:push lo sincroniza. CLI de administración: npx autonnel admin:create [email protected] 'una-contraseña-fuerte' desde el directorio del proyecto.
Paso 3: configura solo lo que necesita el embudo
En la interfaz de administración, en Configuración:
| Configuración | Necesario para | Opciones |
|---|---|---|
| Comercio electrónico | Datos de producto y pedido | Shopify, WooCommerce, Picocart |
| Pagos | Recibir dinero | Stripe, PayPal |
| Almacenamiento | Cargas de imagen/video | Cualquier bucket compatible con S3 (R2, S3, MinIO) |
| Correo electrónico | Recibos, campañas de reenganche | SMTP, Resend, AWS SES |
| LLM | Generación de páginas con IA | Cualquier endpoint compatible con OpenAI |
| Plataformas publicitarias | Conversiones del lado del servidor (las cuatro); informes de gasto/clics a nivel de anuncio (solo Facebook, Google Ads, TikTok) | Facebook, TikTok, Google Ads, Bing |
Orden de operaciones que evita retrabajo: primero el catálogo (limita lo que el checkout puede vender), luego los pagos, luego el almacenamiento, luego el correo electrónico y, por último, las plataformas publicitarias: el seguimiento se verifica contra pedidos reales, por lo que necesita que el resto funcione primero. Conectar una plataforma publicitaria para informes de gasto es un paso separado de vincularla a un embudo para postback (consulta server-side-conversion-tracking); haz ambos si quieres ambos.
En Workers, R2 es la opción de almacenamiento obvia: es compatible con S3 y mantiene la salida de medios dentro de Cloudflare.
Paso 4: construye las páginas
Los roles del embudo se asignan directamente a la especificación del embudo:
| Rol en el embudo | Propósito | ¿Múltiples por embudo? |
|---|---|---|
LANDING | Página(s) de entrada, una por ángulo de tráfico | Sí |
CHECKOUT | Formulario de pedido | No - uno por embudo |
UPSELL | Ofertas posteriores a la compra, ordenadas en una cadena | Sí |
THANKYOU | Confirmación | No |
ERROR | Fallo de pago / respaldo | No |
Estos son los roles que una página toma dentro de un embudo. A través de la API, el tipo propio de una página es CHECKOUT | THANKYOU | ERROR | UPSELL | CUSTOM: las páginas de aterrizaje se crean como CUSTOM y se convierten en páginas de aterrizaje al vincularse a un embudo como LANDING.
Hay dos editores disponibles: un editor visual basado en componentes cuya salida es JSON diferenciable, y HTML sin formato para páginas importadas. Prefiere el editor de componentes para cualquier cosa que se vaya a probar A/B o editar por un agente más adelante: los diffs de JSON se revisan limpiamente, los blobs de HTML no.
Construye el checkout antes que la página de aterrizaje. El checkout determina qué se puede vender realmente y a qué precio, y una página de aterrizaje escrita primero prometerá algo que el checkout no puede cumplir.
Paso 5: conecta el embudo
- Crea el embudo, luego adjunta las páginas con su rol y orden.
- La misma página puede ser referenciada por varios embudos. La única regla de unicidad que el dominio aplica es que un
stepSluges único dentro de un embudo (y una página aparece como máximo una vez por embudo); no hay rechazo entre embudos para diseñar alrededor. Clona una página de aterrizaje solo cuando quieras que los dos embudos diverjan, porque una edición en una página compartida se aplica a cada embudo que la referencia. THANKYOUyERRORse vinculan automáticamente desde páginas existentes en la creación si existe alguna; si el inquilino no tiene ninguna, créalas antes de ponerlo en marcha. Un embudo sin página de error falla silenciosamente en pagos rechazados.- La URL que va en las campañas publicitarias es el slug propio de la página de aterrizaje en un host de tienda:
https://shop.example.com/{page.slug}- nunca una URL de paso/n/./n/{funnelId}/{stepSlug}redirige hacia adelante al siguiente paso, por lo que pertenece al enlace CTA de una página, no a un anuncio. Escribir el CTA de esa manera mantiene estable la ruta del comprador cuando un paso se intercambia por otra página. - La publicación es explícita y versionada por página y por embudo: publicar una página no publica la vinculación del embudo.
Paso 6: instrumenta antes de enviar tráfico
Verificaciones previas al lanzamiento no negociables:
- Una compra real de extremo a extremo, en un proveedor de pago real, que incluya: pedido base, un upsell aceptado, un upsell rechazado, la página de agradecimiento, el correo de recibo y el pedido que aparece en la tienda conectada.
- Un reembolso en ese pedido, para confirmar que la ruta de reembolso funciona por cargo.
- Cobertura de id de clic: confirma que
fbclid/ttclid/gclid/msclkidllegan al registro del pedido. Consultaserver-side-conversion-tracking. - Conversión del lado del servidor que llega al depurador de eventos de cada plataforma publicitaria, con el id de clic adjunto y sin duplicado con respecto al evento del navegador.
- Página de error accesible forzando una tarjeta rechazada.
En Workers, añade una más: confirma que el manejador scheduled de cron se está ejecutando (los postbacks en cola y las campañas de reenganche dependen de ello). Un despliegue que perdió silenciosamente sus disparadores cron parece saludable mientras el trabajo en segundo plano se detiene silenciosamente.
Solo entonces aumenta el gasto. Un embudo que no ha tenido una transacción real procesada tiene una tasa de fallos desconocida, no baja.
Paso 7: opera desde un agente a través de MCP
La instancia expone su API de administración como herramientas MCP en /api/mcp, por lo que un agente puede construir y cambiar embudos sin la interfaz de usuario.
{
"mcpServers": {
"autonnel": {
"transport": "http",
"url": "https://<tu-host-autonnel>/api/mcp",
"headers": { "Authorization": "Bearer <tu-clave-api>" }
}
}
}
Llamar a /api/mcp con HTTP puro en lugar de un cliente MCP tiene dos requisitos de transporte que el SDK normalmente oculta. El endpoint habla Streamable HTTP: la solicitud debe llevar Accept: application/json, text/event-stream; cualquier cosa menor es rechazada con 406 antes de que se alcance la capa de herramienta, y un éxito regresa como un frame SSE (event: message / data: {...}), por lo que el envoltorio JSON-RPC debe desempaquetarse de data: antes de analizar.
Una trampa más delante de la aplicación por completo: una instancia detrás de Cloudflare con las reglas de bots gestionadas predeterminadas rechaza el agente de usuario de la biblioteca estándar de Python. Un cliente urllib envía Python-urllib/3.x y obtiene 403 con el cuerpo de texto plano error code: 1010 en cada ruta, incluido /api/health, que se lee exactamente como un fallo de autenticación o permiso y no es JSON, por lo que un cliente que analiza el cuerpo lanza una excepción antes de poder ver el estado. Solo esa cadena de agente está bloqueada: curl, python-requests, httpx, axios, node y un UA vacío pasan todos. Si programas esto en Python, establece un User-Agent explícito o usa requests/httpx; si cada llamada, incluidas las no autenticadas, devuelve 403, esta es la razón, y ninguna clave API lo solucionará.
.mcp.json en la raíz del proyecto para Claude Code; claude_desktop_config.json para Claude Desktop. Genera la clave en administración → Configuración → Claves API. Cada llamada está limitada al inquilino (X-Autonnel-Tenant-Id inferido de la clave). Las herramientas expuestas cubren creación/edición/publicación de páginas, gestión de embudos, configuración del catálogo y conexión de pagos, con validación previa a la escritura para evitar que un agente publique un checkout sin una pasarela de pago configurada o un embudo sin página de error. Si una herramienta devuelve un error de validación, la corrección es siempre editar el recurso referenciado primero, no anular la validación.
Este es un skill operativo. No inventes pasos; si el operador omite uno, señálalo pero no lo hagas por él. Cuando se complete el despliegue, indica si el embudo está detrás de Workers (con sus límites) o Docker (con sus responsabilidades de mantenimiento).