@vp-k/notihub
v1.0.0
Published
Universal notification library for Telegram, Discord, and webhooks
Readme
notihub
Universal notification library for Telegram, Discord, and custom webhooks.
- Zero dependencies — uses native
fetch(Node >= 18) - Never throws — always returns a structured
SendResult - Function-based API — simple, tree-shakeable
- TypeScript-first with full type definitions
- ESM + CJS dual build
Install
npm install notihubQuick Start
import { createTelegram, createDiscord, createWebhook, sendAll } from "notihub";
const telegram = createTelegram({
token: "YOUR_BOT_TOKEN",
chatId: "YOUR_CHAT_ID",
});
const discord = createDiscord({
webhookUrl: "https://discord.com/api/webhooks/...",
});
const webhook = createWebhook({
url: "https://example.com/hook",
body: (msg) => ({ text: msg }),
});
// Send to a single channel
const result = await telegram.send("Server deployed!");
// { ok: true, channel: "telegram" }
// { ok: false, channel: "telegram", error: "Unauthorized", status: 401 }
// Send to all channels at once
const results = await sendAll([telegram, discord, webhook], "Deploy complete");API
createTelegram(config)
| Config | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| token | string | Yes | — | Telegram Bot API token |
| chatId | string | No | — | Default chat ID |
| parseMode | "HTML" \| "Markdown" | No | "HTML" | Message parse mode |
const tg = createTelegram({ token: "bot123:ABC", chatId: "456" });
await tg.send("Hello");
await tg.send("Hello", { chatId: "789" }); // override chatId
await tg.send("Hello", { parseMode: "Markdown" }); // override parseMode
await tg.send("Hello", { timeout: 5000 }); // custom timeout (default: 10s)createDiscord(config)
| Config | Type | Required | Description |
|--------|------|----------|-------------|
| webhookUrl | string | Yes | Discord webhook URL |
const dc = createDiscord({ webhookUrl: "https://discord.com/api/webhooks/..." });
// Plain text
await dc.send("Hello");
// Rich embed
await dc.send("New order", {
embeds: [{
title: "Order #123",
color: 0x00ff00,
fields: [
{ name: "Customer", value: "John", inline: true },
{ name: "Total", value: "$99", inline: true },
],
}],
});
// Custom bot name & avatar
await dc.send("Hello", { username: "MyBot", avatarUrl: "https://..." });createWebhook(config)
| Config | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| url | string | Yes | — | Webhook endpoint URL |
| method | HttpMethod | No | "POST" | HTTP method |
| headers | Record<string, string> | No | {} | Default headers |
| body | (msg: string) => unknown | No | { message } | Custom body builder |
const wh = createWebhook({
url: "https://example.com/hook",
headers: { Authorization: "Bearer token" },
body: (msg) => ({ text: msg, source: "notihub" }),
});
await wh.send("Alert!");
await wh.send("Alert!", { headers: { "X-Priority": "high" } }); // merge headerssendAll(channels, message)
Sends a message to multiple channels concurrently using Promise.allSettled. One channel's failure does not affect others.
const results = await sendAll([telegram, discord, webhook], "Deploy complete");
// [
// { ok: true, channel: "telegram" },
// { ok: false, channel: "discord", error: "...", status: 404 },
// { ok: true, channel: "webhook" },
// ]Utilities
import { escapeHtml, truncate } from "notihub";
escapeHtml("<b>bold & safe</b>"); // "<b>bold & safe</b>"
truncate("Long message...", 10); // "Long me..."SendResult
All send() calls return a SendResult:
type SendResult =
| { ok: true; channel: string }
| { ok: false; channel: string; error: string; status?: number };ok: true— message sent successfullyok: false— failed, with human-readableerrorand optional HTTPstatus- Never rejects — safe to use fire-and-forget:
telegram.send("alert").then(r => !r.ok && console.error(r.error));License
MIT
