Typed operational alerts for TacticLaunch services: a small client + transports + templates layer so apps stop copy-pasting Telegram fetch snippets and string formatting.
- Ship lifecycle and billing signals to ops chat (new user, payment succeeded) with consistent copy and parse modes.
- Format digest-style messages from your own scheduler or worker (
digest.daily/digest.weekly/digest.monthlytemplates). - Route different severities to different chats using named transports (
default,security, …).
- Backend / full-stack engineers on Node 18+ who already use (or plan to use) Telegram Bot API for ops visibility.
- Teams that want shared vocabulary (
user.registered, …) and typed payloads without building a second notification platform.
You still can — this package is a thin convenience layer: one place for timeouts, forum threads, error handling policy, and event templates. It is not a hosted relay, queue, or outbox.
npm install @tacticlaunch/alertsFor coding assistants: a copy-paste prompt that describes the package surface and how to wire it into a host app lives in docs/INTEGRATION_PROMPT.md (also shipped on npm under node_modules/@tacticlaunch/alerts/docs/).
Scheduled digests: this package does not run timers or cron. Wire client.send('digest.daily', …) (or other events) from your job runner, queue, or platform scheduler.
- Put
botTokenand chat IDs in environment variables or a secrets manager — never commit tokens. - MarkdownV2 / HTML: the package does not escape message text. Safe formatting is the caller’s responsibility (see tests for the passthrough contract).
import{createAlertClient,createTelegramTransport,builtInTemplates,typeBuiltInEventMap,}from'@tacticlaunch/alerts';interfaceAppEventMapextendsBuiltInEventMap{'order.shipped': {orderId: string};}constclient=createAlertClient<AppEventMap>({transports: {default: createTelegramTransport({botToken: process.env.TELEGRAM_BOT_TOKEN!,chatId: process.env.TELEGRAM_CHAT_ID!,messageThreadId: process.env.TELEGRAM_THREAD_ID
? Number(process.env.TELEGRAM_THREAD_ID)
: undefined,}),},templates: {
...builtInTemplates,'order.shipped': (data)=>({text: `Order shipped: ${data.orderId}`,parseMode: 'HTML',}),},});awaitclient.send('user.registered',{userId: 'usr_123',email: 'user@example.com',});Use one Telegram transport instance per destination and pick the channel per send:
constclient=createAlertClient({transports: {default: createTelegramTransport({botToken: process.env.TELEGRAM_BOT_TOKEN!,chatId: process.env.TELEGRAM_CHAT_DEFAULT!,}),security: createTelegramTransport({botToken: process.env.TELEGRAM_BOT_TOKEN!,chatId: process.env.TELEGRAM_CHAT_SECURITY!,}),},templates: builtInTemplates,});awaitclient.send('billing.payment_succeeded',payload,{channel: 'security',});transports.default is required. Unknown channel keys invoke onError with kind: 'unknown_channel' and do not throw unless throw: true.
awaitclient.sendRaw({text: '<b>Ad-hoc</b> alert',parseMode: 'HTML'},{channel: 'default'},);By default failures are logged via console.error and do not reject unless you pass throw: true. Override with onError for metrics or PagerDuty-style escalation.
| Export | Role |
|---|---|
createAlertClient | Template registry + send / sendRaw |
createTelegramTransport | sendMessage via native fetch (Node 18+) |
builtInTemplates / BuiltInEventMap | Presets: user.registered, billing.payment_succeeded, digest.* |
This package follows Semantic Versioning. Releases are tagged vMAJOR.MINOR.PATCH on GitHub; see CHANGELOG.md for details. Breaking changes bump the major version.
npm ci
npm run typecheck
npm run lint
npm test
npm run buildMIT — see LICENSE.