Polar, Stripe y GitHub hablan su propio JSON. AlertHub habla ah_title, ah_level y ah_key. Hookdeck Event Gateway se pone en medio: acusa recibo al proveedor al instante, verifica la firma, reescribe el payload si hace falta y hace POST de una alerta limpia a AlertHub. No montas servidor.
No son alternativas. Hookdeck es fontanería de webhooks (cola, HMAC, reintentos, inspeccionar/reenviar). AlertHub es la capa humana: dashboard con historial más Slack, Telegram, ntfy, Gotify, email, Discord, Teams. Cambias el chat en Connections; Polar sigue hablando con Hookdeck.
Polar → Hookdeck (verificar → filtrar → transformar) → ingest AlertHub → dashboard + canales
El plan Developer gratuito de Hookdeck incluye 10.000 eventos/mes. Sobran para AlertHub Pro (1.000 alertas/mes).
Por qué poner Hookdeck delante de AlertHub
Apuntar Polar directo a https://api.thealerthub.com/sendAlert funciona si metes placeholders en la query — el mismo truco que Stripe y GitHub. Se queda corto en cuanto el payload es rico:
| Hueco | URL nativa a AlertHub | Con Hookdeck |
|---|---|---|
| HMAC / Standard Webhooks | ingest no verifica la firma de Polar | El Source valida webhook-id / webhook-timestamp / webhook-signature |
| Archivar vs renombrar | Polar no tiene evento product.archived — archivar es product.updated + data.is_archived | La transformación pone critical o warning |
| Secreto en el panel de Polar | ah_key en la URL del endpoint | ah_key vive en una variable de la transformación de Hookdeck |
| Polar reintenta / tú depuras | Polar reintenta a ciegas | Cola, Issues, replay masivo |
Usa Hookdeck cuando la fuente es un webhook SaaS (Polar, Stripe, Shopify). Sáltatelo para cron, bash, n8n o la API de ingestión que ya controlas.
Cómo encajan las piezas
- Polar hace POST de su evento nativo a la URL de un Source de Hookdeck. Polar recibe 200 al momento.
- Un Filter (opcional) tira todo lo que no sea
product.updated. - Una Transformation mapea el producto Polar a campos AlertHub e inyecta
ah_keydesdeprocess.env. - El Destination es
POST https://api.thealerthub.com/sendAlert. - AlertHub autentica el proyecto, guarda la fila y
handle-new-alertreparte. Solo warning y critical salen del dashboard; info es historial. Ver niveles de alerta.
Orden de reglas: Filter y después Transform. Hookdeck aplica el filtro después de la transformación por defecto. Arrastra Filter encima de Transform, o el filtro buscará body.type en un body que ya solo tiene ah_*.
Configuración (una vez)
1. Proyecto AlertHub
En la app, abre el proyecto y copia la clave secreta (ah_key). Conecta Slack, Telegram, ntfy o Gotify en Connections para que el primer evento real tenga destino.
2. Source y Destination en Hookdeck
En el dashboard de Hookdeck:
- Crea un Source. Nombre
polar. Copia la URL (https://hkdk.events/…). - Crea un Destination. URL
https://api.thealerthub.com/sendAlert, método POST. No pongasah_keyen esa URL. - Crea una Connection de ese Source a ese Destination.
Autenticación del Source: Polar firma con Standard Webhooks. En Polar puedes poner tu propio secreto al crear el endpoint — genéralo, pégalo en Polar y en el campo de verificación del Source de Hookdeck. Si Polar genera el secreto al guardar, cópialo a Hookdeck antes de fiarte del tráfico de producción.
3. Webhook en Polar
En Polar: Settings → Webhooks → Add endpoint.
- URL: la del Source de Hookdeck (no AlertHub).
- Format: Raw.
- Events:
product.updated(añadeproduct.createdsi también quieres altas de catálogo). Polar no emiteproduct.archived.
4. Filtro (opcional)
En la connection, añade una regla Filter encima de Transform:
{
"type": "product.updated"
}
Solo archivos (sin cambios de nombre/precio):
{
"type": "product.updated",
"data": { "is_archived": true }
}
Reintentos hacia AlertHub: 5xx y timeouts sí. No reintentes 401 (ah_key mala) ni 400 (falta título). Un 429 es la cuota mensual de AlertHub — martillear ingest no ayuda hasta el ciclo siguiente.
Guardar ah_key como variable de Hookdeck
No pegues la clave del proyecto AlertHub en Polar, en la URL del Destination ni como literal en el código de la transformación. Las transformaciones de Hookdeck tienen variables de entorno para secretos.
- Abre la connection → Transform → Create new transformation (o Editor si ya existe).
- En el editor, abre el desplegable Variables (arriba a la derecha del panel de código).
- Añade una variable llamada
AH_KEY. Pega la clave secreta de AlertHub como valor. Guarda. - En el JavaScript, léela con
process.env.AH_KEY— nunca la interpoles enrequest.queryni en la URL del endpoint de Polar.
La variable pertenece a esa transformación. Quien pueda editarla la ve; la UI de webhooks de Polar no. Si rotas la clave en el proyecto AlertHub, actualiza solo AH_KEY en Hookdeck — la URL de Polar no cambia.
Los payloads de prueba del editor (Input) no meten las env vars en una captura que compartas. Tras Run, confirma en Output que sale ah_key y que no subes esa pestaña a git.
Copiar y pegar: Polar product.updated → AlertHub
Pega esto como handler de la transformación. Producto archivado → critical; cualquier otra actualización → warning.
addHandler("transform", (request) => {
const event =
typeof request.body === "string" ? JSON.parse(request.body) : request.body;
const product = event.data || {};
const archived = Boolean(product.is_archived);
const price = (product.prices && product.prices[0]) || {};
const priceLabel =
price.amount_type === "free"
? "gratis"
: price.price_amount != null
? `${(price.price_amount / 100).toFixed(2)} ${(price.price_currency || "").toUpperCase()}`
: "n/d";
request.body = {
ah_key: process.env.AH_KEY,
ah_source: "Polar",
ah_level: archived ? "critical" : "warning",
ah_title: archived
? `Polar: producto archivado — ${product.name || product.id}`
: `Polar: producto actualizado — ${product.name || product.id}`,
ah_description: archived
? `${product.name} (${product.id}) ya no está a la venta. Las suscripciones existentes conservan los beneficios.`
: `ID: ${product.id}\nVisible: ${product.visibility}\nRecurring: ${product.is_recurring} (${product.recurring_interval || "one-time"})\nPrecio: ${priceLabel}`,
};
request.headers["content-type"] = "application/json";
delete request.headers["webhook-signature"];
delete request.headers["webhook-id"];
delete request.headers["webhook-timestamp"];
return request;
});
Borra las cabeceras de firma de Polar al reescribir el body: ya no coinciden, y AlertHub no las verifica.
Input de ejemplo (pégalo en Input de Hookdeck → Run)
{
"type": "product.updated",
"timestamp": "2026-09-01T10:12:00.000Z",
"data": {
"id": "prod_01ABC",
"name": "Pro mensual",
"is_archived": false,
"is_recurring": true,
"recurring_interval": "month",
"visibility": "public",
"prices": [
{
"amount_type": "fixed",
"price_amount": 1000,
"price_currency": "eur"
}
]
}
}
Salida esperada: ah_source: Polar, ah_level: warning, título con Pro mensual, ah_key desde la variable. Pon is_archived a true y Run otra vez — el nivel debe pasar a critical.
Nombra la transformación (p. ej. polar-product-to-alerthub), Confirm, y Save en la connection.
Qué deberías ver
Archiva o renombra un producto en Polar (vale el sandbox). En Hookdeck, Requests muestra el JSON de Polar; Events, el POST transformado. El feed de AlertHub recibe la fila. Los canales conectados solo reciben warning / critical.
Un Source de Hookdeck puede repartir a varios Destinations. Deja una segunda connection sin esta transformación si otro sistema sigue necesitando el body original firmado por Polar.
Ideas para sacarle más partido
- Mismo patrón con Stripe / GitHub / Shopify. Un Source por proveedor, el mismo Destination AlertHub, una transform que mapee
type→ah_title/ah_level. Las URLs con placeholders siguen bien para eventos triviales — constructor de webhooks. subscription.canceleden warning,order.paiden info. Info no pagina; sigue en el dashboard.- ntfy o Gotify para guardia, Slack para el equipo. Añade ambos en Connections — guardia híbrida. Polar no necesita formato Discord/Slack; déjalo en Raw.
- Issues de Hookdeck → AlertHub. Si Hookdeck no puede entregar a ingest, ese Issue puede ser una segunda connection que te pagine. Meta-alerta de la fontanería.
Preguntas frecuentes
¿Polar hace POST a Slack?
No. Polar → Hookdeck → AlertHub → tus Connections.
¿Puedo saltarme la transformación?
Sí: URL del Destination con query (ah_key, ah_title={{type}}) como en la guía de Stripe. Pierdes niveles archivo-vs-cambio y dejas ah_key en una URL. Vale para una prueba, no para cambios de catálogo.
¿Hookdeck reintentará los 429 de AlertHub todo el mes?
Configura 4xx como no reintentables salvo quizá un retraso corto en 429 si esperas subir de plan. No uses el default de «reintentar una semana» en un 401.
¿Sustituye el log de reintentos de Polar?
Hookdeck responde 200 a Polar rápido, así que los reintentos de Polar deberían quedarse quietos. La depuración está en Hookdeck (replay) y en AlertHub (historial).
Siguientes pasos
Crea el Source, pega su URL en Polar para product.updated, añade AH_KEY, pega la transformación y dispara un test desde el sandbox de Polar.
Relacionado: API de ingestión · Webhooks Stripe · Webhooks GitHub · Destino ntfy