Node.js
Pachetul honk-me este un client TypeScript fără dependențe la rulare, pentru Node 18 sau mai nou, Bun și Deno. Folosește-l în codul de backend, în funcții și în scripturi.
- Pachet
-
honk-mePublicat - Cod sursă
- github.com/honk-me/honk-node · Licență MIT
- Cerințe
- Node 18 sau mai nou (cu
fetchglobal), Bun sau Deno.
Instalare
Apoi creează un proiect și o cheie API în aplicația web Honk.
npm install honk-me Oricine are o cheie API (honk_…) poate trimite mesaje în proiectul ei. Ține-o pe servere, în joburi și în secretele din CI, niciodată într-o aplicație de browser, de mobil sau de desktop.
Trimite un eveniment
Honk.fromEnv() citește HONK_URL, HONK_KEY și valorile implicite opționale HONK_SOURCE, HONK_ENVIRONMENT și HONK_CHANNEL. În CommonJS merge și 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'); Rețetă: cererea unui client, direct pe telefon
Un grup pentru fiecare cerere și o cheie de idempotență stabilă: doi clienți nu ajung niciodată în aceeași notificare, iar un webhook retrimis nu te anunță de două ori. Nu aștepți rezultatul trimiterii, așa că o rețea lentă nu întârzie niciodată răspunsul pentru client.
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
} Scala Honk și incidentele
Câte un helper pentru fiecare nivel. problem și recovery au nevoie de o cheie de grup; revenirea închide episodul deschis de problemă.
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 Erori
Fiecare eroare este un HonkError cu kind și retryable. Erorile de validare sunt buguri; cele care se pot reîncerca pot reveni în coada ta cu aceeași cheie.
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 și Deno
Bun: bun add honk-me și folosește-l ca în Node. Deno îl importă din npm:
import { Honk } from 'npm:honk-me'; // Deno
const honk = new Honk({ url: Deno.env.get('HONK_URL')!, key: Deno.env.get('HONK_KEY')! }); Reîncercări care nu trimit nimic de două ori
- Fiecare trimitere are un
Idempotency-Key: al tău sau un UUIDv7 nou. Aceeași cheie e refolosită la fiecare reîncercare, iar timp de 24 de ore Honk răspunde la o repetare cu id-ul original șiduplicate: true, așa că un răspuns pierdut nu creează niciodată un al doilea mesaj. - Se reîncearcă doar erorile de rețea, cererile care expiră,
429și5xx, cu backoff exponențial și jitter complet, niciodată mai devreme decâtRetry-Afterde la server. Celelalte răspunsuri4xxnu se reîncearcă niciodată: corectează cererea. - Fiecare încercare expiră după 5 secunde, iar totul se oprește după 30. Dacă ar trebui să aștepte mai mult, de exemplu până se resetează cota zilnică la miezul nopții, eșuează imediat și îți spune când să reîncerci.
- Câmpurile sunt verificate înainte de trimitere, iar toate câmpurile invalide sunt raportate deodată.