Node.js
El paquete honk-me es un cliente en TypeScript sin dependencias en tiempo de ejecución, para Node 18 o posterior, Bun y Deno. Úsalo en código de backend, funciones y scripts.
- Paquete
-
honk-mePublicado - Código fuente
- github.com/honk-me/honk-node · Licencia MIT
- Requisitos
- Node 18 o posterior (
fetchglobal), Bun o Deno.
Instalación
Después, crea un proyecto y una clave de ingesta en la app web de Honk.
npm install honk-me Quien tenga una clave de ingesta (honk_…) puede enviar mensajes a su proyecto. Guárdala en servidores, tareas y secretos de CI, nunca en un navegador ni en una app móvil o de escritorio.
Enviar un evento
Honk.fromEnv() lee HONK_URL, HONK_KEY y los valores por defecto opcionales HONK_SOURCE, HONK_ENVIRONMENT y HONK_CHANNEL. En CommonJS también funciona require('honk-me').
import { Honk } from 'honk-me';
const honk = new Honk({ url: process.env.HONK_URL, key: process.env.HONK_KEY });
await honk.beep('Backup finished', 'nightly pg_dump took 42 s'); Receta: una solicitud de cliente en tu teléfono
Un grupo por solicitud y una clave de idempotencia estable: dos clientes nunca se juntan en una misma notificación, y un webhook reintentado nunca suena dos veces. No se hace await de la promesa, así que una red lenta nunca retrasa la respuesta al cliente.
import { Honk } from 'honk-me';
const honk = Honk.fromEnv(); // create once, reuse (keep-alive)
export async function onCustomerRequest(req) {
// ...save the request first, then notify without blocking the response:
honk
.send(
{
title: `New request: ${req.subject}`.slice(0, 160),
message: `${req.name} (${req.company}) asked: ${req.body}`.slice(0, 2000),
priority: 'high', // push right away
category: 'customers',
channel: 'requests',
groupKey: `requests/${req.id}`, // one group per request
url: `https://shop.example.com/admin/requests/${req.id}`, // https only, shown as "Open link"
metadata: { request_id: String(req.id) },
},
{ idempotencyKey: `request-${req.id}` }, // same request, same key: never a duplicate
)
.catch((err) => console.warn('honk:', err.message)); // never fail the customer's request
} La escala Honk e incidentes
Un helper por nivel. problem y recovery requieren una clave de grupo; la recuperación cierra el episodio que abrió el problema.
await honk.loud('Disk 91%', '/var on app-01', { groupKey: 'disk/app-01/var' });
await honk.light('Deploy started', 'v4.2.0 to production', { channel: 'deploys' });
await honk.problem('db/backup', 'Backup failed', 'pg_dump exited with 1'); // a long honk by default
await honk.recovery('db/backup', 'Backup OK', 'pg_dump finished in 41 s'); // a beep by default Errores
Todos los errores son HonkError, con kind y retryable. Los de validación son fallos de programación; los reintentables pueden volver a tu cola con la misma clave.
import { HonkError, HonkValidationError } from 'honk-me';
try {
await honk.send(msg, { idempotencyKey: `order-${order.id}-failed` });
} catch (err) {
if (err instanceof HonkValidationError) logger.error(err.fields); // a bug: don't retry
else if (err instanceof HonkError && err.retryable) queue.retryLater(err.idempotencyKey, err.retryAfter);
else throw err;
} Bun y Deno
Bun: bun add honk-me y úsalo como en Node. Deno lo importa desde npm:
import { Honk } from 'npm:honk-me'; // Deno
const honk = new Honk({ url: Deno.env.get('HONK_URL')!, key: Deno.env.get('HONK_KEY')! }); Reintentos que nunca envían dos veces
- Cada envío lleva una
Idempotency-Key: la tuya o un UUIDv7 nuevo. La misma clave se reutiliza en cada reintento y, durante 24 horas, Honk responde a una repetición con el id original yduplicate: true, así que una respuesta perdida nunca crea un segundo mensaje. - Solo se reintentan los errores de red, los tiempos de espera agotados,
429y5xx, con backoff exponencial y jitter completo, y nunca antes delRetry-Afterdel servidor. Las demás respuestas4xxno se reintentan nunca: hay que corregir la solicitud. - Cada intento se corta a los 5 segundos y todo se detiene a los 30. Una espera que superaría ese plazo, como una cuota diaria que se reinicia a medianoche, falla al momento y te dice cuándo reintentar.
- Los campos se validan antes de enviar, y todos los errores de validación se devuelven juntos.