Un webhook de deploy de Netlify dispara cuando muere el build. Una Function que lanza en runtime es otro fallo: el sitio sigue verde, /api/checkout devuelve 500 y nadie mira Functions → Logs hasta que un cliente se queja.
No necesitas un SDK de Slack dentro de cada función. Captura la excepción, POST a AlertHub, y Slack, Telegram, WhatsApp, Discord o Teams reciben el mismo evento critical.
Esto es distinto de las notificaciones de deploy de Netlify (webhooks salientes del estado del build). Aquí la propia función avisa de que ha petado.
Qué deberías alertar
| Evento | Dónde | Nivel recomendado | Por qué importa |
|---|---|---|---|
| Excepción no controlada en una función HTTP | try/catch alrededor del handler | Critical | Checkout, auth o un webhook tuyo acaba de morir |
| Función programada fallida | el mismo try/catch en el cron | Critical | El job nocturno no corrió |
| 4xx de un API aguas abajo que ya manejas | sendAlert explícito | Warning | Recuperable; aún merece una fila en el panel |
| Invocación correcta | omitir, o info | Info | Solo historial — no pings a Slack |
Solo warning y critical se empujan a canales externos. Las llamadas correctas deben quedarse en info (o omitirse).
Configuración (una sola vez)
- Crea un proyecto en app.thealerthub.com y copia la clave secreta.
- En Netlify: Project configuration → Environment variables → añade
ALERTHUB_KEY. Ámbitola a Production (y Preview si quieres ruido de PRs). Nunca pongas la clave en el código de la función. - Conecta destinos en AlertHub. Telegram basta para un maintainer; Slack para el canal del equipo.
Docs: API de ingestión. Webhooks de deploy fallido (no crashes de funciones): fuente Netlify.
Alerta 1: Función HTTP petada (el valor por defecto)
Functions 2.0 exportan un handler por defecto. Envuelve el trabajo en try/catch, avisa a AlertHub y luego devuelve 500. Traga los errores del notify para que un AlertHub caído no oculte el stack original.
// netlify/functions/checkout.mjs
const ALERTHUB_URL = 'https://api.thealerthub.com/sendAlert';
async function notifyAlertHub({ title, description, level = 'critical' }) {
try {
await fetch(ALERTHUB_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
ah_key: process.env.ALERTHUB_KEY,
ah_title: title,
ah_description: description,
ah_level: level,
ah_source: 'Netlify Function',
}),
});
} catch (notifyError) {
console.error('AlertHub notify failed', notifyError);
}
}
export default async (req, context) => {
try {
const body = await req.json();
const result = await chargeCustomer(body);
return Response.json({ ok: true, result });
} catch (error) {
const stack = error instanceof Error ? error.stack : String(error);
await notifyAlertHub({
title: 'Netlify Function failed: checkout',
description: `${stack}\nurl: ${req.url}\nrequestId: ${context.requestId}`,
});
return new Response('Internal error', { status: 500 });
}
};
export const config = { path: '/api/checkout' };
Despliega, fuerza un throw (un payload malo basta) y confirma la alerta en el panel y en tus canales.
Alerta 2: exports.handler clásico
Las funciones antiguas siguen usando la API compatible con Lambda. Misma variable de entorno, mismo cuerpo JSON:
// netlify/functions/legacy-webhook.js
const ALERTHUB_URL = 'https://api.thealerthub.com/sendAlert';
exports.handler = async (event) => {
try {
await processWebhook(JSON.parse(event.body || '{}'));
return { statusCode: 200, body: '{"ok":true}' };
} catch (error) {
try {
await fetch(ALERTHUB_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
ah_key: process.env.ALERTHUB_KEY,
ah_title: 'Netlify Function failed: legacy-webhook',
ah_description: error instanceof Error ? error.stack : String(error),
ah_level: 'critical',
ah_source: 'Netlify Function',
}),
});
} catch (notifyError) {
console.error('AlertHub notify failed', notifyError);
}
return { statusCode: 500, body: 'Internal error' };
}
};
Alerta 3: Función programada
Las funciones cron fallan en silencio si solo miras el sitio. El mismo catch, ah_source distinto para filtrar el feed:
// netlify/functions/nightly-sync.mjs
export default async () => {
try {
await syncOrders();
return new Response('ok');
} catch (error) {
await fetch('https://api.thealerthub.com/sendAlert', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
ah_key: process.env.ALERTHUB_KEY,
ah_title: 'Netlify scheduled function failed: nightly-sync',
ah_description: error instanceof Error ? error.stack : String(error),
ah_level: 'critical',
ah_source: 'Netlify Cron',
}),
}).catch((notifyError) => console.error('AlertHub notify failed', notifyError));
return new Response('Internal error', { status: 500 });
}
};
export const config = { schedule: '0 3 * * *' };
Ideas para sacarle más partido
- Reutiliza un helper. Copia
notifyAlertHubanetlify/functions/_lib/alerthub.mjse impórtalo en cada handler. - Incluye
requestId. La descripción de arriba abre la fila en los logs de Netlify Functions con una búsqueda. - Preview vs production. Usa un segundo proyecto AlertHub (o
warningen Deploy Previews) para que un PR roto no pagine el canal de guardia. - Edge Functions. El mismo
try/catch+fetch. Lee la clave conNetlify.env.get('ALERTHUB_KEY')(oDeno.env.get) — sigue siendo una variable de entorno, nunca unah_keyhardcodeado. - Combínalo con webhooks de deploy. Fallos de build vía deploys de Netlify; crashes de runtime con los snippets de arriba.
Preguntas frecuentes
¿Por qué no solo los logs / el email de Netlify?
Los logs necesitan que alguien los abra. El email de Netlify se ahoga junto a los newsletters. AlertHub es el último salto para que Slack, Telegram y WhatsApp sigan sincronizados.
¿Funciona process.env.ALERTHUB_KEY en Functions 2.0?
Sí. Configúrala en la UI de Netlify (o netlify env:set ALERTHUB_KEY). Vuelve a desplegar después de añadir la variable para que producción la recoja.
¿Puedo enviar info al éxito?
Sí, con "ah_level": "info". No se repartirá a canales.
¿Es lo mismo que un deploy fallido de Netlify?
No. Los webhooks de deploy cubren build/publish. Esto cubre excepciones dentro de una función cuando el sitio ya está en vivo. Usa ambos.
Siguientes pasos
Añade ALERTHUB_KEY, pega el try/catch en una función de producción, fuerza un throw y conecta Slack o Telegram.
Relacionado: deploys de Netlify · fallos de Cloudflare Workers · API de ingestión