@xbibzlibrary/telebibz 0.4.5 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -138
- package/LICENSE +1 -1
- package/NOTICE.md +9 -4
- package/README.id.md +542 -206
- package/README.md +539 -213
- package/examples/01-quickstart.js +13 -0
- package/examples/02-menu-tombol.js +22 -0
- package/examples/03-wizard.js +58 -0
- package/examples/04-broadcast.js +25 -0
- package/examples/05-kirim-file.js +19 -0
- package/examples/06-menu.js +35 -0
- package/examples/07-inline-query.js +18 -0
- package/index.d.ts +106 -0
- package/index.js +44 -0
- package/lib/api.js +154 -0
- package/lib/broadcast.js +35 -0
- package/lib/composer.js +174 -0
- package/lib/context.js +190 -0
- package/lib/errors.js +35 -0
- package/lib/file.js +41 -0
- package/lib/inline-query.js +28 -0
- package/lib/keyboard.js +83 -0
- package/lib/logger.js +38 -0
- package/lib/menus.js +90 -0
- package/lib/net.js +115 -0
- package/lib/ratelimit.js +61 -0
- package/lib/runner.js +45 -0
- package/lib/session.js +36 -0
- package/lib/telebibz.js +193 -0
- package/lib/wizard.js +247 -0
- package/package.json +35 -97
- package/test/all.test.js +439 -0
- package/CODE_OF_CONDUCT.md +0 -37
- package/CONTRIBUTING.md +0 -59
- package/CONTRIBUTION_RULES.md +0 -41
- package/GOVERNANCE.md +0 -47
- package/README.zh-CN.md +0 -306
- package/RELEASE_AUTOMATION.md +0 -78
- package/RELEASE_POLICY.md +0 -32
- package/SECURITY.md +0 -47
- package/SHOWCASE.md +0 -29
- package/SUPPORT.md +0 -30
- package/assets/readme-preview.html +0 -75
- package/assets/telebibz-logo.png +0 -0
- package/assets/telebibz-readme-preview.png +0 -0
- package/bin/telebibz.mjs +0 -3
- package/dist/generated/api.d.ts +0 -13
- package/dist/generated/api.d.ts.map +0 -1
- package/dist/generated/api.js +0 -192
- package/dist/generated/api.js.map +0 -1
- package/dist/src/api/client.d.ts +0 -62
- package/dist/src/api/client.d.ts.map +0 -1
- package/dist/src/api/client.js +0 -104
- package/dist/src/api/client.js.map +0 -1
- package/dist/src/api/errors.d.ts +0 -45
- package/dist/src/api/errors.d.ts.map +0 -1
- package/dist/src/api/errors.js +0 -65
- package/dist/src/api/errors.js.map +0 -1
- package/dist/src/api/index.d.ts +0 -6
- package/dist/src/api/index.d.ts.map +0 -1
- package/dist/src/api/index.js +0 -6
- package/dist/src/api/index.js.map +0 -1
- package/dist/src/api/telegram-types/LICENSE +0 -21
- package/dist/src/api/telegram-types/api.d.ts +0 -22
- package/dist/src/api/telegram-types/checklist.d.ts +0 -72
- package/dist/src/api/telegram-types/inline.d.ts +0 -692
- package/dist/src/api/telegram-types/langs.d.ts +0 -193
- package/dist/src/api/telegram-types/manage.d.ts +0 -1144
- package/dist/src/api/telegram-types/markup.d.ts +0 -268
- package/dist/src/api/telegram-types/message.d.ts +0 -1537
- package/dist/src/api/telegram-types/methods.d.ts +0 -2870
- package/dist/src/api/telegram-types/mod.d.ts +0 -14
- package/dist/src/api/telegram-types/passport.d.ts +0 -163
- package/dist/src/api/telegram-types/payment.d.ts +0 -570
- package/dist/src/api/telegram-types/rich.d.ts +0 -1010
- package/dist/src/api/telegram-types/settings.d.ts +0 -120
- package/dist/src/api/telegram-types/story.d.ts +0 -89
- package/dist/src/api/telegram-types/update.d.ts +0 -84
- package/dist/src/api/telegram.d.ts +0 -7
- package/dist/src/api/telegram.d.ts.map +0 -1
- package/dist/src/api/telegram.js +0 -2
- package/dist/src/api/telegram.js.map +0 -1
- package/dist/src/api/transport.d.ts +0 -68
- package/dist/src/api/transport.d.ts.map +0 -1
- package/dist/src/api/transport.js +0 -264
- package/dist/src/api/transport.js.map +0 -1
- package/dist/src/api/types.d.ts +0 -466
- package/dist/src/api/types.d.ts.map +0 -1
- package/dist/src/api/types.js +0 -2
- package/dist/src/api/types.js.map +0 -1
- package/dist/src/branding/terminal.d.ts +0 -77
- package/dist/src/branding/terminal.d.ts.map +0 -1
- package/dist/src/branding/terminal.js +0 -328
- package/dist/src/branding/terminal.js.map +0 -1
- package/dist/src/broadcast/broadcast.d.ts +0 -50
- package/dist/src/broadcast/broadcast.d.ts.map +0 -1
- package/dist/src/broadcast/broadcast.js +0 -56
- package/dist/src/broadcast/broadcast.js.map +0 -1
- package/dist/src/cache/cache.d.ts +0 -34
- package/dist/src/cache/cache.d.ts.map +0 -1
- package/dist/src/cache/cache.js +0 -41
- package/dist/src/cache/cache.js.map +0 -1
- package/dist/src/cli.d.ts +0 -2
- package/dist/src/cli.d.ts.map +0 -1
- package/dist/src/cli.js +0 -84
- package/dist/src/cli.js.map +0 -1
- package/dist/src/context/context.d.ts +0 -124
- package/dist/src/context/context.d.ts.map +0 -1
- package/dist/src/context/context.js +0 -302
- package/dist/src/context/context.js.map +0 -1
- package/dist/src/core/bot.d.ts +0 -204
- package/dist/src/core/bot.d.ts.map +0 -1
- package/dist/src/core/bot.js +0 -506
- package/dist/src/core/bot.js.map +0 -1
- package/dist/src/core/events.d.ts +0 -75
- package/dist/src/core/events.d.ts.map +0 -1
- package/dist/src/core/events.js +0 -35
- package/dist/src/core/events.js.map +0 -1
- package/dist/src/core/webhook-reply.d.ts +0 -34
- package/dist/src/core/webhook-reply.d.ts.map +0 -1
- package/dist/src/core/webhook-reply.js +0 -37
- package/dist/src/core/webhook-reply.js.map +0 -1
- package/dist/src/index.d.ts +0 -24
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js +0 -24
- package/dist/src/index.js.map +0 -1
- package/dist/src/keyboard/index.d.ts +0 -46
- package/dist/src/keyboard/index.d.ts.map +0 -1
- package/dist/src/keyboard/index.js +0 -55
- package/dist/src/keyboard/index.js.map +0 -1
- package/dist/src/middleware/compose.d.ts +0 -5
- package/dist/src/middleware/compose.d.ts.map +0 -1
- package/dist/src/middleware/compose.js +0 -17
- package/dist/src/middleware/compose.js.map +0 -1
- package/dist/src/observability/logger.d.ts +0 -78
- package/dist/src/observability/logger.d.ts.map +0 -1
- package/dist/src/observability/logger.js +0 -285
- package/dist/src/observability/logger.js.map +0 -1
- package/dist/src/plugins/plugin.d.ts +0 -38
- package/dist/src/plugins/plugin.d.ts.map +0 -1
- package/dist/src/plugins/plugin.js +0 -59
- package/dist/src/plugins/plugin.js.map +0 -1
- package/dist/src/queue/queue.d.ts +0 -77
- package/dist/src/queue/queue.d.ts.map +0 -1
- package/dist/src/queue/queue.js +0 -213
- package/dist/src/queue/queue.js.map +0 -1
- package/dist/src/router/router.d.ts +0 -61
- package/dist/src/router/router.d.ts.map +0 -1
- package/dist/src/router/router.js +0 -183
- package/dist/src/router/router.js.map +0 -1
- package/dist/src/state/conversation.d.ts +0 -56
- package/dist/src/state/conversation.d.ts.map +0 -1
- package/dist/src/state/conversation.js +0 -133
- package/dist/src/state/conversation.js.map +0 -1
- package/dist/src/state/forms.d.ts +0 -34
- package/dist/src/state/forms.d.ts.map +0 -1
- package/dist/src/state/forms.js +0 -44
- package/dist/src/state/forms.js.map +0 -1
- package/dist/src/state/menu.d.ts +0 -78
- package/dist/src/state/menu.d.ts.map +0 -1
- package/dist/src/state/menu.js +0 -127
- package/dist/src/state/menu.js.map +0 -1
- package/dist/src/storage/storage.d.ts +0 -146
- package/dist/src/storage/storage.d.ts.map +0 -1
- package/dist/src/storage/storage.js +0 -195
- package/dist/src/storage/storage.js.map +0 -1
- package/dist/src/telegram-features.d.ts +0 -33
- package/dist/src/telegram-features.d.ts.map +0 -1
- package/dist/src/telegram-features.js +0 -71
- package/dist/src/telegram-features.js.map +0 -1
- package/dist/src/testing.d.ts +0 -24
- package/dist/src/testing.d.ts.map +0 -1
- package/dist/src/testing.js +0 -38
- package/dist/src/testing.js.map +0 -1
- package/dist/src/utils/concurrency.d.ts +0 -25
- package/dist/src/utils/concurrency.d.ts.map +0 -1
- package/dist/src/utils/concurrency.js +0 -52
- package/dist/src/utils/concurrency.js.map +0 -1
- package/dist/src/utils/files.d.ts +0 -45
- package/dist/src/utils/files.d.ts.map +0 -1
- package/dist/src/utils/files.js +0 -53
- package/dist/src/utils/files.js.map +0 -1
- package/dist/src/utils/text.d.ts +0 -39
- package/dist/src/utils/text.d.ts.map +0 -1
- package/dist/src/utils/text.js +0 -56
- package/dist/src/utils/text.js.map +0 -1
- package/dist/src/webhook/handler.d.ts +0 -19
- package/dist/src/webhook/handler.d.ts.map +0 -1
- package/dist/src/webhook/handler.js +0 -141
- package/dist/src/webhook/handler.js.map +0 -1
- package/dist-cjs/generated/api.js +0 -194
- package/dist-cjs/package.json +0 -3
- package/dist-cjs/src/api/client.js +0 -107
- package/dist-cjs/src/api/errors.js +0 -74
- package/dist-cjs/src/api/index.js +0 -21
- package/dist-cjs/src/api/telegram-types/LICENSE +0 -21
- package/dist-cjs/src/api/telegram-types/api.d.ts +0 -22
- package/dist-cjs/src/api/telegram-types/checklist.d.ts +0 -72
- package/dist-cjs/src/api/telegram-types/inline.d.ts +0 -692
- package/dist-cjs/src/api/telegram-types/langs.d.ts +0 -193
- package/dist-cjs/src/api/telegram-types/manage.d.ts +0 -1144
- package/dist-cjs/src/api/telegram-types/markup.d.ts +0 -268
- package/dist-cjs/src/api/telegram-types/message.d.ts +0 -1537
- package/dist-cjs/src/api/telegram-types/methods.d.ts +0 -2870
- package/dist-cjs/src/api/telegram-types/mod.d.ts +0 -14
- package/dist-cjs/src/api/telegram-types/passport.d.ts +0 -163
- package/dist-cjs/src/api/telegram-types/payment.d.ts +0 -570
- package/dist-cjs/src/api/telegram-types/rich.d.ts +0 -1010
- package/dist-cjs/src/api/telegram-types/settings.d.ts +0 -120
- package/dist-cjs/src/api/telegram-types/story.d.ts +0 -89
- package/dist-cjs/src/api/telegram-types/update.d.ts +0 -84
- package/dist-cjs/src/api/telegram.js +0 -2
- package/dist-cjs/src/api/transport.js +0 -267
- package/dist-cjs/src/api/types.js +0 -2
- package/dist-cjs/src/branding/terminal.js +0 -338
- package/dist-cjs/src/broadcast/broadcast.js +0 -58
- package/dist-cjs/src/cache/cache.js +0 -45
- package/dist-cjs/src/cli.js +0 -86
- package/dist-cjs/src/context/context.js +0 -305
- package/dist-cjs/src/core/bot.js +0 -510
- package/dist-cjs/src/core/events.js +0 -38
- package/dist-cjs/src/core/webhook-reply.js +0 -42
- package/dist-cjs/src/index.js +0 -47
- package/dist-cjs/src/keyboard/index.js +0 -61
- package/dist-cjs/src/middleware/compose.js +0 -20
- package/dist-cjs/src/observability/logger.js +0 -293
- package/dist-cjs/src/plugins/plugin.js +0 -63
- package/dist-cjs/src/queue/queue.js +0 -219
- package/dist-cjs/src/router/router.js +0 -186
- package/dist-cjs/src/state/conversation.js +0 -139
- package/dist-cjs/src/state/forms.js +0 -47
- package/dist-cjs/src/state/menu.js +0 -133
- package/dist-cjs/src/storage/storage.js +0 -202
- package/dist-cjs/src/telegram-features.js +0 -76
- package/dist-cjs/src/testing.js +0 -45
- package/dist-cjs/src/utils/concurrency.js +0 -57
- package/dist-cjs/src/utils/files.js +0 -58
- package/dist-cjs/src/utils/text.js +0 -63
- package/dist-cjs/src/webhook/handler.js +0 -144
- package/docs/API.id.md +0 -1935
- package/docs/API.md +0 -1969
- package/docs/API.zh-CN.md +0 -1929
- package/docs/COOKBOOK.id.md +0 -321
- package/docs/COOKBOOK.md +0 -321
- package/docs/COOKBOOK.zh-CN.md +0 -321
- package/docs/ERRORS.id.md +0 -194
- package/docs/ERRORS.md +0 -194
- package/docs/ERRORS.zh-CN.md +0 -194
- package/docs/FILES.id.md +0 -243
- package/docs/FILES.md +0 -243
- package/docs/FILES.zh-CN.md +0 -243
- package/docs/GETTING_STARTED.id.md +0 -89
- package/docs/GETTING_STARTED.md +0 -89
- package/docs/GETTING_STARTED.zh-CN.md +0 -89
- package/docs/GITHUB_PACKAGES.id.md +0 -82
- package/docs/GITHUB_PACKAGES.md +0 -82
- package/docs/GITHUB_PACKAGES.zh-CN.md +0 -82
- package/docs/MIGRATION_TELEGRAF.id.md +0 -147
- package/docs/MIGRATION_TELEGRAF.md +0 -154
- package/docs/MIGRATION_TELEGRAF.zh-CN.md +0 -147
- package/docs/README.md +0 -67
- package/docs/STORAGE.id.md +0 -105
- package/docs/STORAGE.md +0 -105
- package/docs/STORAGE.zh-CN.md +0 -105
- package/docs/TESTING.id.md +0 -203
- package/docs/TESTING.md +0 -203
- package/docs/TESTING.zh-CN.md +0 -203
- package/docs/WEBHOOK.id.md +0 -212
- package/docs/WEBHOOK.md +0 -215
- package/docs/WEBHOOK.zh-CN.md +0 -212
- package/examples/README.md +0 -37
- package/examples/files.ts +0 -35
- package/examples/minimal.ts +0 -12
- package/examples/tsconfig.json +0 -9
- package/examples/webhook.ts +0 -42
- package/examples/wizard-registration.ts +0 -42
package/README.md
CHANGED
|
@@ -1,315 +1,641 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
[🇬🇧 **English**](README.md) · [🇮 **Indonesia**](README.id.md)
|
|
4
|
+
|
|
5
|
+
<br>
|
|
6
|
+
|
|
7
|
+
<a href="https://www.npmjs.com/package/@xbibzlibrary/telebibz" title="Open telebibz on npm">
|
|
8
|
+
<img src="https://imgbs.com/uploads/telebibz-d7b30671.png" alt="telebibz — Telegram Bot Library" width="560">
|
|
9
|
+
</a>
|
|
10
|
+
|
|
11
|
+
<br><br>
|
|
12
|
+
|
|
13
|
+
**The easiest Telegram bot library for Node.js — full feature set on par with grammY.**<br>
|
|
14
|
+
A standalone recode of [grammY](https://grammy.dev)'s elegant architecture, with production
|
|
15
|
+
dependencies that are *actually used*, and an Indonesia-first community.
|
|
16
|
+
|
|
17
|
+
<br>
|
|
18
|
+
|
|
19
|
+
[](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
|
|
20
|
+
[](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
|
|
21
|
+
[](https://nodejs.org)
|
|
22
|
+
[](#-testing--live-proof)
|
|
23
|
+
[](#-analytics--statistics)
|
|
24
|
+
[](LICENSE)
|
|
25
|
+
[](https://github.com/XbibzOfficial777/telebibz)
|
|
26
|
+
|
|
27
|
+
<br>
|
|
28
|
+
|
|
29
|
+
`//—Xbibz Official—//`
|
|
30
|
+
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 📑 Table of Contents
|
|
36
|
+
|
|
37
|
+
| | | |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| ⚡ [Why telebibz?](#why) | 📊 [Feature matrix vs grammY](#matrix) | 📥 [Installation & requirements](#install) |
|
|
40
|
+
| 🚀 [Quick start](#quickstart) | 🧠 [How it works (architecture)](#architecture) | 📖 [Full documentation](#docs) |
|
|
41
|
+
| 🎛️ [Handlers & filters](#handlers) | 💬 [Context shortcuts](#context) | 🔘 [Keyboards & buttons](#keyboards) |
|
|
42
|
+
| ️ [Interactive menus](#menus) | 🧙 [Wizard (forms + buttons + edit/delete)](#wizard) | ❓ [Inline mode](#inline) |
|
|
43
|
+
| 📣 [Broadcast](#broadcast) | 📎 [Files & media](#files) | 🛡️ [Reliability & rate limiting](#ratelimit) |
|
|
44
|
+
| 🗃️ [Sessions](#sessions) | 🇮🇩 [Human-readable errors](#errors) | 🕸️ [Webhooks & serverless](#webhook) |
|
|
45
|
+
| 🔌 [Proxy transport](#proxy) | 🧪 [Transformers](#transformers) | 📈 [Analytics & statistics](#analytics) |
|
|
46
|
+
| 🧩 [Examples](#examples) | 🔬 [Testing](#testing) | 📂 [Repo structure](#structure) |
|
|
47
|
+
| 🕐 [Changelog](#changelog) | 📄 [License](#license) | |
|
|
48
|
+
|
|
49
|
+
<a id="why"></a>
|
|
50
|
+
## ⚡ Why telebibz?
|
|
51
|
+
|
|
52
|
+
> [!TIP]
|
|
53
|
+
> **One principle:** every feature that needs a plugin in grammY is **built in** here —
|
|
54
|
+
> wizard, menus, rate limiting, broadcast, file download — and polling that *never dies* on 409.
|
|
55
|
+
|
|
56
|
+
- 🧠 **The grammY API you already know** — `bot.cmd()`, `bot.hears()`, `ctx.reply()`, middleware, transformers
|
|
57
|
+
- 🧙 **Built-in Wizard v3.1** — question-and-answer forms with **choice buttons** (reply/inline) and **edit/delete** message modes
|
|
58
|
+
- 🛡️ **Bulletproof** — 429 auto-retry, throttler, per-user limiter, polling auto-retry on 409 conflict
|
|
59
|
+
- 🇮🇩 **Human-readable errors** — every Telegram error is translated into a plain-language suggestion
|
|
60
|
+
- 🔌 **Proxy API for any method** — `api.anyMethod({...})` works automatically, even for methods not released yet
|
|
61
|
+
- 🪶 **Light & honest** — 4 dependencies, all genuinely used and tested
|
|
62
|
+
|
|
63
|
+
<a id="matrix"></a>
|
|
64
|
+
## 📊 Feature Matrix — grammY parity
|
|
65
|
+
|
|
66
|
+
| Feature | grammY | telebibz |
|
|
67
|
+
|---|:---:|:---:|
|
|
68
|
+
| Proxy API for **any method** (auto-generated) | ✅ | ✅ |
|
|
69
|
+
| ~60 typed shortcuts (sendMessage, banChatMember…) | ✅ | ✅ |
|
|
70
|
+
| Full Context (~70 shortcuts reply/edit/admin/react) | ✅ | ✅ |
|
|
71
|
+
| Business flavor (`business_connection_id` automatic) | plugin | ✅ built-in |
|
|
72
|
+
| Filters `on('message:photo' / ':text' / 'chat_type:private' …)` | ✅ | ✅ |
|
|
73
|
+
| `cmd / hears / action / inlineQuery` | ✅ | ✅ (+ inlineQuery matcher) |
|
|
74
|
+
| `branch / filter / drop / route / lazy / fork` | ✅ | ✅ |
|
|
75
|
+
| Error boundary + catch | ✅ | ✅ (all shortcuts auto-protected) |
|
|
76
|
+
| Session + swappable storage | ✅ | ✅ |
|
|
77
|
+
| Transformer API (`api.config.use`) | ✅ | ✅ |
|
|
78
|
+
| `auto-retry` on 429 honoring `retry_after` | plugin | ✅ built-in `autoRetry()` |
|
|
79
|
+
| Throttler queue | plugin | ✅ built-in `throttler()` |
|
|
80
|
+
| Per-user rate limit | plugin | ✅ built-in `limiter()` |
|
|
81
|
+
| `InputFile` Buffer/path/stream + multipart `attach://` | ✅ | ✅ |
|
|
82
|
+
| `InputMedia` builder + media groups | ✅ | ✅ `InputMediaBuilder` |
|
|
83
|
+
| File download (`getFile`/`downloadFile`) | plugin | ✅ built-in |
|
|
84
|
+
| Keyboard & InlineKeyboard fluent classes | ✅ | ✅ |
|
|
85
|
+
| Interactive menus | plugin | ✅ built-in `Menu/MenuContainer` |
|
|
86
|
+
| Wizard/conversations | plugin | ✅ built-in — **+ choice buttons & `edit`/`delete` modes** |
|
|
87
|
+
| 409-resilient long polling | ❌ (fatal crash) | ✅ built-in (auto-retry 5 s) |
|
|
88
|
+
| Broadcast ready to use | ❌ | ✅ `bot.broadcast()` |
|
|
89
|
+
| Humanized errors + suggestions | ❌ | ✅ `humanize()` |
|
|
90
|
+
| Boot banner + debug logging | ❌ | ✅ (`DEBUG=telebibz*`) |
|
|
91
|
+
| HTTP(S) proxy for VPS | ⚠️ manual | ✅ `proxy` transport option |
|
|
92
|
+
| TypeScript | ✅ full | loose d.ts (JS-first) |
|
|
93
|
+
| Documentation language | en | **🇬🇧 + 🇮🇩** |
|
|
94
|
+
|
|
95
|
+
<a id="install"></a>
|
|
96
|
+
## 📥 Installation & Requirements
|
|
97
|
+
|
|
98
|
+
**Requirements:** Node.js ≥ 18 (uses global `FormData`/`Blob` for uploads).
|
|
2
99
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
**`@xbibzlibrary/telebibz`** is a Telegram Bot SDK and framework for Node.js and TypeScript. It provides a typed API client, polling, routing, middleware, context helpers, keyboard builders, state/session primitives, webhooks, queues, scheduling, caching, plugin lifecycle, colorful terminal logging, CLI tooling, and testing utilities.
|
|
100
|
+
```bash
|
|
101
|
+
npm install @xbibzlibrary/telebibz
|
|
102
|
+
# or
|
|
103
|
+
yarn add @xbibzlibrary/telebibz
|
|
104
|
+
# or
|
|
105
|
+
pnpm add @xbibzlibrary/telebibz
|
|
106
|
+
```
|
|
11
107
|
|
|
12
|
-
|
|
108
|
+
**Runtime dependencies (all used, all tested):**
|
|
13
109
|
|
|
14
|
-
|
|
110
|
+
| Package | Purpose |
|
|
111
|
+
|---|---|
|
|
112
|
+
| `axios ^1.20` | keep-alive transport + streaming `downloadFile` |
|
|
113
|
+
| `mime-types ^3.0` | content-type detection for uploads |
|
|
114
|
+
| `https-proxy-agent ^9.1` | VPS proxy transport option |
|
|
115
|
+
| `debug ^4.4` | logging via `DEBUG=telebibz:net,telebibz:ratelimit` |
|
|
15
116
|
|
|
16
|
-
|
|
117
|
+
Get your bot token from **@BotFather** → `/newbot`. The constructor validates the token
|
|
118
|
+
format (`123456:ABC…`) and throws a helpful error if it's wrong.
|
|
17
119
|
|
|
18
|
-
|
|
120
|
+
<a id="quickstart"></a>
|
|
121
|
+
## 🚀 Quick Start
|
|
19
122
|
|
|
20
|
-
|
|
123
|
+
```js
|
|
124
|
+
const { TeleBibz } = require('@xbibzlibrary/telebibz');
|
|
21
125
|
|
|
22
|
-
|
|
126
|
+
const bot = new TeleBibz('TOKEN_FROM_BOTFATHER');
|
|
23
127
|
|
|
24
|
-
|
|
128
|
+
bot.cmd('start', (ctx) => ctx.reply('Hello!'));
|
|
129
|
+
bot.hears(/hello|hi/i, (ctx) => ctx.reply('hello there 👋'));
|
|
130
|
+
bot.hears('ping', (ctx) => ctx.reply('pong 🏓'));
|
|
25
131
|
|
|
26
|
-
|
|
132
|
+
bot.launch();
|
|
133
|
+
```
|
|
27
134
|
|
|
28
|
-
|
|
135
|
+
```bash
|
|
136
|
+
BOT_TOKEN=123:abc node index.js
|
|
137
|
+
```
|
|
29
138
|
|
|
30
|
-
|
|
139
|
+
```
|
|
140
|
+
┌──────────────────────────────────┐
|
|
141
|
+
│ 🤖 TeleBibz ON │
|
|
142
|
+
│ bot : @yourbot (id 123456) │
|
|
143
|
+
│ mode : long-polling │
|
|
144
|
+
│ library : telebibz 3.1.0 │
|
|
145
|
+
│ brand : //—Xbibz Official—// │
|
|
146
|
+
└──────────────────────────────────┘
|
|
147
|
+
✔ waiting for updates… (Ctrl+C to stop)
|
|
148
|
+
```
|
|
31
149
|
|
|
32
|
-
|
|
150
|
+
> [!NOTE]
|
|
151
|
+
> **On a VPS:** if another bot instance is still polling (409 Conflict — e.g. double
|
|
152
|
+
> deploy or a hosting restart), telebibz **auto-retries every 5 seconds without
|
|
153
|
+
> crashing** and boots the moment the lane is free. No PM2 babysitting needed.
|
|
33
154
|
|
|
34
|
-
|
|
155
|
+
<a id="architecture"></a>
|
|
156
|
+
## 🧠 How It Works (Architecture)
|
|
35
157
|
|
|
36
|
-
|
|
158
|
+
```
|
|
159
|
+
┌─────────────────────────────────────────────┐
|
|
160
|
+
Telegram Bot API ────►│ long polling (lib/runner.js) │
|
|
161
|
+
│ or webhook / handleUpdate (lib/telebibz.js)│
|
|
162
|
+
└──────────────────┬──────────────────────────┘
|
|
163
|
+
│ raw update (JSON)
|
|
164
|
+
▼
|
|
165
|
+
Context(update, api, me) lib/context.js
|
|
166
|
+
│
|
|
167
|
+
┌────────────────────────────▼───────────────────────────┐
|
|
168
|
+
│ Middleware tree `_root` (fixed order): │
|
|
169
|
+
│ 1. session() lib/session.js │
|
|
170
|
+
│ 2. wizard.middleware() lib/wizard.js │
|
|
171
|
+
│ 3. errorBoundary(reporter) │
|
|
172
|
+
│ └─► your handlers: use/cmd/hears/action/on/ │
|
|
173
|
+
│ inlineQuery/Menu/wizard lib/composer.js │
|
|
174
|
+
└────────────────────────────┬───────────────────────────┘
|
|
175
|
+
│ ctx.reply / ctx.api.*
|
|
176
|
+
▼
|
|
177
|
+
ApiBase + Proxy + transformer pipeline lib/api.js
|
|
178
|
+
(api.config.use → autoRetry / throttler)
|
|
179
|
+
│
|
|
180
|
+
▼
|
|
181
|
+
axios transport: JSON or multipart attach:// lib/net.js
|
|
182
|
+
│
|
|
183
|
+
▼
|
|
184
|
+
https://api.telegram.org
|
|
185
|
+
```
|
|
37
186
|
|
|
38
|
-
|
|
187
|
+
**Lifecycle of one update** (e.g. `/start`): `getUpdates` → `pollLoop` →
|
|
188
|
+
`handleUpdate` → new `Context` → session loads → wizard middleware (no active
|
|
189
|
+
wizard → pass) → error boundary → your matched handler runs → `ctx.reply()` →
|
|
190
|
+
transformer pipeline → axios → Telegram. Any thrown error becomes a `BotError`
|
|
191
|
+
and flows to `opts.onError` or the humanized reporter.
|
|
192
|
+
|
|
193
|
+
<a id="docs"></a>
|
|
194
|
+
## 📖 Full Documentation
|
|
195
|
+
|
|
196
|
+
### 🏗️ Constructor & options
|
|
197
|
+
|
|
198
|
+
```js
|
|
199
|
+
const bot = new TeleBibz('TOKEN', {
|
|
200
|
+
allowedUpdates: [...], // limit update types (default: common + Business types)
|
|
201
|
+
onError: (err, ctx) {}, // custom error handler (default: humanized reporter)
|
|
202
|
+
silent: false, // hide boot banner
|
|
203
|
+
dropPending: false, // discard old updates on start
|
|
204
|
+
session: { ... }, // { initial, getKey, storage } — see Sessions
|
|
205
|
+
transport: fn, // inject custom transport (testing / proxy)
|
|
206
|
+
});
|
|
207
|
+
```
|
|
39
208
|
|
|
40
|
-
|
|
209
|
+
<a id="handlers"></a>
|
|
210
|
+
### 🎛️ Handlers & filters
|
|
211
|
+
|
|
212
|
+
```js
|
|
213
|
+
bot.cmd('ping', (ctx) => ctx.reply('pong')); // /ping
|
|
214
|
+
bot.cmd(['a', 'b'], handler); // /a OR /b
|
|
215
|
+
bot.start('Welcome!'); // shortcut: registers /start
|
|
216
|
+
bot.hears('daftar', handler); // exact text "daftar" (case-insensitive)
|
|
217
|
+
bot.hears(/kitt?y/i, handler); // any regex
|
|
218
|
+
bot.on('message:photo', handler); // grammY-style filters
|
|
219
|
+
bot.on([':text', 'chat_type:private'], handler);
|
|
220
|
+
bot.action('menu:premium', handler); // callback_query data (string or RegExp)
|
|
221
|
+
bot.inlineQuery(/kucing/i, handler); // inline mode (regex / string / '*')
|
|
222
|
+
bot.use(middleware); // manual middleware
|
|
223
|
+
```
|
|
41
224
|
|
|
42
|
-
|
|
225
|
+
Composer combinators (grammY semantics):
|
|
43
226
|
|
|
44
|
-
```
|
|
45
|
-
|
|
227
|
+
```js
|
|
228
|
+
bot.branch(pred, ifTrue, ifFalse); // pick a subtree by predicate
|
|
229
|
+
bot.filter(pred, ...mw); // run only when pred(ctx) is true
|
|
230
|
+
bot.drop(pred, ...mw); // skip when pred(ctx) is true
|
|
231
|
+
bot.route('chat.type', { private: mwA, group: mwB }); // map ctx→handler
|
|
232
|
+
bot.lazy((ctx) => ctx.from.is_bot ? botMw : userMw); // build mw per update
|
|
233
|
+
bot.fork(slowMw); // run in background, doesn't block next()
|
|
46
234
|
```
|
|
47
235
|
|
|
48
|
-
|
|
236
|
+
Filters supported by `on()`: update fields (`message`, `edited_message`,
|
|
237
|
+
`callback_query`, `inline_query`, `my_chat_member`, …), message props
|
|
238
|
+
(`message:photo`, `message:text`, `:caption`, `:document`, `:sticker`, `:media`, …),
|
|
239
|
+
chat types (`chat_type:private/group/supergroup/channel`), plus
|
|
240
|
+
`callback_query:data`, payments, reactions, join requests.
|
|
49
241
|
|
|
50
|
-
|
|
242
|
+
Command handlers receive arguments in `ctx.match`:
|
|
51
243
|
|
|
52
|
-
```
|
|
53
|
-
|
|
244
|
+
```js
|
|
245
|
+
bot.cmd('echo', (ctx) => ctx.reply(`args: ${ctx.match}`)); // /echo hello → "hello"
|
|
246
|
+
```
|
|
54
247
|
|
|
55
|
-
|
|
248
|
+
<a id="context"></a>
|
|
249
|
+
### 💬 Context shortcuts
|
|
56
250
|
|
|
57
|
-
|
|
58
|
-
|
|
251
|
+
`ctx` wraps every update kind (message, edited, channel, business, callback,
|
|
252
|
+
inline…) with unified accessors: `chat`, `from`, `chatId`, `msgId`, `msg`,
|
|
253
|
+
`senderChat`, `inlineMessageId`, `businessConnectionId`.
|
|
59
254
|
|
|
60
|
-
|
|
255
|
+
| Category | Shortcuts |
|
|
256
|
+
|---|---|
|
|
257
|
+
| **Reply** | `reply`, `replyWithHTML`, `replyWithMarkdown`, `replyWithPhoto/Video/Audio/Document/Animation/Voice/VideoNote/Sticker/MediaGroup/Location/Venue/Contact/Poll/Dice/Invoice/ChatAction` |
|
|
258
|
+
| **Edit & delete** | `editMessageText/Caption/Media/ReplyMarkup`, `deleteMessage`, `deleteMessages` — callback-aware & inline-message aware |
|
|
259
|
+
| **React** | `react('👍')` |
|
|
260
|
+
| **Forward/copy** | `forwardMessage(to)`, `copyMessage(to)` (defaults to current msg) |
|
|
261
|
+
| **Callbacks & inline** | `answerCallbackQuery` (string or object), `answerInlineQuery` |
|
|
262
|
+
| **Admin** | `banChatMember`, `restrictChatMember`, `promoteChatMember`, `banAuthor`, `restrictAuthor`, `getChat*`, `getAuthor`, `leaveChat`, `setChatTitle/Description`, `pin/unpinChatMessage` |
|
|
263
|
+
| **Files** | `getFile()` (smart: largest photo), `downloadFile(dest)` |
|
|
264
|
+
|
|
265
|
+
Business accounts: replies inside a business context automatically carry
|
|
266
|
+
`business_connection_id`.
|
|
267
|
+
|
|
268
|
+
<a id="keyboards"></a>
|
|
269
|
+
### 🔘 Keyboards & buttons
|
|
270
|
+
|
|
271
|
+
```js
|
|
272
|
+
const { btn, url, webApp, copy, kb, InlineKeyboard, Keyboard } = require('@xbibzlibrary/telebibz');
|
|
273
|
+
|
|
274
|
+
bot.cmd('menu', (ctx) =>
|
|
275
|
+
ctx.reply('Pick:', kb([
|
|
276
|
+
[btn('💎 Premium', 'prem', 'primary'), // blue/purple
|
|
277
|
+
btn('✅ Register', 'reg', 'success')], // green
|
|
278
|
+
[url('🌐 Web', 'https://yoursite.com')],
|
|
279
|
+
[btn('❌ Close', 'close', 'danger', '5408846744727334338')], // red + ANIMATED ICON
|
|
280
|
+
])));
|
|
61
281
|
```
|
|
62
282
|
|
|
63
|
-
`
|
|
283
|
+
- 🎨 `style` colors (`primary`/`success`/`danger`) need Telegram apps from Feb 2026+ — older apps render plain buttons, never an error.
|
|
284
|
+
- ✨ `icon_custom_emoji_id` needs a Premium bot owner or a Fragment username.
|
|
285
|
+
- Helpers: `copy(text, value)` (copy-to-clipboard), `webApp(text, link)`, `kb.confirm(yesData, noData)`, `kb.markup(rows)`.
|
|
286
|
+
- Fluent classes: `new InlineKeyboard().text(...).url(...).row().text(...).build()` and `new Keyboard().text(...).requestContact(...).resized().build()` (real reply keyboards).
|
|
64
287
|
|
|
65
|
-
|
|
288
|
+
<a id="menus"></a>
|
|
289
|
+
### 🍽️ Interactive menus
|
|
66
290
|
|
|
67
|
-
|
|
291
|
+
```js
|
|
292
|
+
const { Menu, MenuContainer } = require('@xbibzlibrary/telebibz');
|
|
68
293
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
294
|
+
const mc = new MenuContainer();
|
|
295
|
+
const main = mc.create('main'), more = mc.create('more');
|
|
296
|
+
|
|
297
|
+
main.text('🔔 Toggle', async (ctx) => ctx.answerCallbackQuery('toggled!'))
|
|
298
|
+
.row()
|
|
299
|
+
.url('🌐 Web', 'https://x.com')
|
|
300
|
+
.submenu('More ▶', 'more');
|
|
301
|
+
more.back('◀️ Back', 'main');
|
|
302
|
+
|
|
303
|
+
bot.use(mc); // button handlers registered automatically
|
|
304
|
+
bot.cmd('cfg', (ctx) => ctx.reply('Menu:', { reply_markup: main.render(ctx) }));
|
|
72
305
|
```
|
|
73
306
|
|
|
74
|
-
|
|
307
|
+
Submenus swap the keyboard in place via `editMessageReplyMarkup`; stale button
|
|
308
|
+
presses are answered with a friendly alert instead of crashing.
|
|
75
309
|
|
|
76
|
-
|
|
310
|
+
<a id="wizard"></a>
|
|
311
|
+
### 🧙 Wizard — conversation forms, zero boilerplate
|
|
77
312
|
|
|
78
|
-
```
|
|
79
|
-
bot.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
313
|
+
```js
|
|
314
|
+
bot.wizard('register', {
|
|
315
|
+
steps: [
|
|
316
|
+
{ key: 'name', ask: 'What is your name?' },
|
|
317
|
+
{ key: 'age', ask: 'Age?', parse: Number,
|
|
318
|
+
validate: (n) => (n > 0 && n < 120 ? null : 'Numbers only, please:') },
|
|
319
|
+
],
|
|
320
|
+
done: async (ans, ctx) => ctx.reply(`Done ${ans.name} (${ans.age})!`),
|
|
83
321
|
});
|
|
322
|
+
// user runs /register → the bot asks until finished.
|
|
323
|
+
// typing "cancel" / "batal" stops any time. Session is active automatically.
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
`bot.wizard(id, def, bindCommand = true)` also binds `/id` as the trigger; use
|
|
327
|
+
`bot.wizardStart(ctx, id)` from any handler (button, menu, …).
|
|
328
|
+
|
|
329
|
+
#### 🆕 v3.1 — choice buttons + `edit`/`delete` modes
|
|
330
|
+
|
|
331
|
+
```js
|
|
332
|
+
bot.wizard('survey', {
|
|
333
|
+
mode: 'edit', // 'send' (default) | 'edit' | 'delete'
|
|
334
|
+
steps: [
|
|
335
|
+
// reply keyboard — user taps, no typing
|
|
336
|
+
{ key: 'gender', ask: 'Gender?', buttons: ['👨 Male', '👩 Female'], onlyButtons: true },
|
|
337
|
+
|
|
338
|
+
// inline keyboard (callback) — value may differ from label
|
|
339
|
+
{ key: 'island', ask: 'Which island?', inline: true, onlyButtons: true,
|
|
340
|
+
buttons: [[{ text: '🌋 Java', value: 'java' }, { text: '🌴 Sumatra', value: 'sumatra' }]] },
|
|
84
341
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
bot.hears("ping", async (ctx) => { await ctx.reply("pong"); });
|
|
92
|
-
bot.catch(async (error, ctx) => { await ctx.reply("Something went wrong."); });
|
|
342
|
+
// free typing with validation (mode can be overridden per step)
|
|
343
|
+
{ key: 'age', ask: 'Age?', parse: Number, mode: 'send',
|
|
344
|
+
validate: (n) => (n > 0 && n < 120 ? null : 'Numbers only:') },
|
|
345
|
+
],
|
|
346
|
+
done: async (ans, ctx) => ctx.reply(`Saved: ${JSON.stringify(ans)}`),
|
|
347
|
+
});
|
|
93
348
|
```
|
|
94
349
|
|
|
95
|
-
|
|
350
|
+
| Option | Level | Purpose |
|
|
351
|
+
|---|:---:|---|
|
|
352
|
+
| `buttons` | step | `['A','B']`, `[{text,value}]`, or explicit rows `[['A'],['B','C']]` |
|
|
353
|
+
| `inline` | step | `true` → callback buttons (click = value, no typing) |
|
|
354
|
+
| `onlyButtons` | step | `true`/string → reject free typing, must pick a button |
|
|
355
|
+
| `mode` | def/step | `'send'` new message · `'edit'` one message edited in place · `'delete'` old question deleted first |
|
|
356
|
+
| `cleanup` | def | delete the last question when done (default on with mode `'delete'`) |
|
|
357
|
+
| `removeKeyboard` | def | dismiss the reply keyboard when done (default `true` if one was shown) |
|
|
358
|
+
|
|
359
|
+
Programmatic helpers: `bot.wizardCancel(ctx)`, `bot.wizardEdit(ctx, text)`,
|
|
360
|
+
`bot.wizardDelete(ctx)`, plus module `wizard` (`cancel/editAsk/deleteAsk`).
|
|
361
|
+
Stale buttons (clicked after the wizard advanced/ended) get a safe alert —
|
|
362
|
+
the bot never crashes. `parse`/`validate` also apply to button values.
|
|
363
|
+
|
|
364
|
+
<a id="inline"></a>
|
|
365
|
+
### ❓ Inline mode
|
|
366
|
+
|
|
367
|
+
```js
|
|
368
|
+
const { iq } = require('@xbibzlibrary/telebibz');
|
|
369
|
+
|
|
370
|
+
bot.inlineQuery(/cat/i, async (ctx) => {
|
|
371
|
+
await ctx.answerInlineQuery([
|
|
372
|
+
iq.article('1', 'A cat fact', { message_text: 'meong!' }),
|
|
373
|
+
iq.photo('2', 'https://x/1.jpg'),
|
|
374
|
+
], { cache_time: 0 });
|
|
375
|
+
});
|
|
376
|
+
```
|
|
96
377
|
|
|
97
|
-
|
|
378
|
+
Builders: `iq.article/photo/gif/video/audio/location/sticker`.
|
|
98
379
|
|
|
99
|
-
|
|
380
|
+
<a id="broadcast"></a>
|
|
381
|
+
### 📣 Broadcast (rate-limit safe)
|
|
100
382
|
|
|
101
|
-
```
|
|
102
|
-
await bot.
|
|
103
|
-
|
|
104
|
-
await bot.api.call("sendMessage", { chat_id: 123456789, text: "Hello." });
|
|
105
|
-
await bot.api.raw("futureTelegramMethod", { value: true });
|
|
383
|
+
```js
|
|
384
|
+
const result = await bot.broadcast([111, 222, 333], 'Announcement!', { delay: 35 });
|
|
385
|
+
// → { terkirim: 3, gagal: 0, errors: [] } (blocked users are listed in errors)
|
|
106
386
|
```
|
|
107
387
|
|
|
108
|
-
|
|
388
|
+
`pesan` may be a string, a `sendMessage` payload object, or a function
|
|
389
|
+
`(chatId) => payload` for per-recipient personalization. Default pacing is
|
|
390
|
+
35 ms (≈28 msg/s, safely under Telegram limits).
|
|
391
|
+
|
|
392
|
+
<a id="files"></a>
|
|
393
|
+
### 📎 Files & media
|
|
394
|
+
|
|
395
|
+
```js
|
|
396
|
+
const { InputFile, InputMediaBuilder } = require('@xbibzlibrary/telebibz');
|
|
397
|
+
|
|
398
|
+
bot.cmd('foto', (ctx) => ctx.replyWithPhoto(new InputFile(buffer, 'x.jpg')));
|
|
399
|
+
bot.cmd('dok', (ctx) => ctx.replyWithDocument(new InputFile('/path/file.pdf')));
|
|
400
|
+
bot.cmd('album', (ctx) => ctx.replyWithMediaGroup([
|
|
401
|
+
InputMediaBuilder.photo('https://a/1.jpg'),
|
|
402
|
+
InputMediaBuilder.photo('https://a/2.jpg', { caption: 'two' }),
|
|
403
|
+
]));
|
|
404
|
+
bot.on('message:photo', async (ctx) => {
|
|
405
|
+
const f = await ctx.getFile(); // largest photo size, automatic
|
|
406
|
+
await ctx.downloadFile('./foto.jpg'); // streams to disk
|
|
407
|
+
});
|
|
408
|
+
```
|
|
109
409
|
|
|
110
|
-
|
|
410
|
+
`InputFile` accepts Buffer / Uint8Array / file path / fs stream / async
|
|
411
|
+
iterable; uploads are sent as `multipart` with `attach://` anywhere in the
|
|
412
|
+
payload (media groups, thumbnails, …). `api.downloadFile(file_id, dest)` works
|
|
413
|
+
standalone too.
|
|
111
414
|
|
|
112
|
-
|
|
113
|
-
|
|
415
|
+
<a id="ratelimit"></a>
|
|
416
|
+
### 🛡️ Reliability & rate limiting
|
|
114
417
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
.url("Documentation", "https://core.telegram.org/bots/api")
|
|
118
|
-
.build();
|
|
418
|
+
```js
|
|
419
|
+
const { autoRetry, throttler, limiter } = require('@xbibzlibrary/telebibz');
|
|
119
420
|
|
|
120
|
-
|
|
421
|
+
bot.api.config.use(autoRetry()); // retry 429, honor retry_after (max 5)
|
|
422
|
+
bot.api.config.use(throttler()); // global queue ≤ 28 calls/second
|
|
423
|
+
bot.use(limiter({ windowMs: 2000, limit: 3, onExceeded })); // per-user anti-spam
|
|
121
424
|
```
|
|
122
425
|
|
|
123
|
-
|
|
426
|
+
Long polling is resilient by default: 409 conflicts retry every 5 s
|
|
427
|
+
(`launch({ conflictDelay: 5000 })` to tune), network hiccups back off 1 s,
|
|
428
|
+
`stop()` exits cleanly (`await bot.runPromise`).
|
|
124
429
|
|
|
125
|
-
|
|
430
|
+
<a id="sessions"></a>
|
|
431
|
+
### 🗃️ Sessions
|
|
126
432
|
|
|
127
|
-
|
|
433
|
+
```js
|
|
434
|
+
const { session } = require('@xbibzlibrary/telebibz');
|
|
128
435
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
436
|
+
const bot = new TeleBibz(token, {
|
|
437
|
+
session: {
|
|
438
|
+
initial: () => ({ count: 0 }),
|
|
439
|
+
getKey: (ctx) => `${ctx.from?.id}:${ctx.chat?.id}`, // default
|
|
440
|
+
storage: myRedisAdapter, // { read(k), write(k,v), delete(k) } — default: in-memory Map
|
|
441
|
+
},
|
|
133
442
|
});
|
|
443
|
+
|
|
444
|
+
bot.on(':text', (ctx) => { ctx.session.count++; });
|
|
134
445
|
```
|
|
135
446
|
|
|
447
|
+
`ctx.session` is always present, even without configuration.
|
|
448
|
+
|
|
449
|
+
<a id="errors"></a>
|
|
450
|
+
### 🇮🇩 Human-readable errors
|
|
136
451
|
|
|
137
|
-
|
|
452
|
+
Every error is reported with an actionable suggestion:
|
|
138
453
|
|
|
139
|
-
|
|
454
|
+
```
|
|
455
|
+
✖ Telegram error (403): Forbidden: bot was blocked by the user
|
|
456
|
+
💡 saran: Bot diblokir pengguna — jangan kirim ulang, hapus dari daftar broadcast.
|
|
457
|
+
```
|
|
140
458
|
|
|
141
|
-
|
|
142
|
-
|
|
459
|
+
`humanize(err)` returns `{ pesan, saran, method, code }` covering 15+ common
|
|
460
|
+
Telegram errors (bad token, chat not found, rights, parse errors, rate limits,
|
|
461
|
+
stale callbacks, oversize files, …). Override with
|
|
462
|
+
`new TeleBibz(token, { onError: (err, ctx) => {} })`.
|
|
143
463
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
.step({ id: "name", run: async (flow) => { flow.set("name", flow.ctx.message?.text?.trim()); flow.next(); await flow.ctx.reply("How old are you?"); } })
|
|
147
|
-
.step({ id: "age", run: (flow) => { const age = Number(flow.ctx.message?.text?.trim()); if (!Number.isInteger(age)) return; flow.set("age", age); flow.next(); } });
|
|
464
|
+
<a id="webhook"></a>
|
|
465
|
+
### 🕸️ Webhooks & serverless
|
|
148
466
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
467
|
+
```js
|
|
468
|
+
const http = require('http');
|
|
469
|
+
http.createServer((req, res) =>
|
|
470
|
+
req.url === '/tg' ? bot.webhook()(req, res) : res.end('ok')
|
|
471
|
+
).listen(8443);
|
|
472
|
+
|
|
473
|
+
// any framework (Express/Fastify/Hono): mount the (req, res) handler from bot.webhook()
|
|
474
|
+
// or serverless, directly:
|
|
475
|
+
await bot.handleUpdate(req.body); // one raw update in → full pipeline
|
|
153
476
|
```
|
|
154
477
|
|
|
155
|
-
`
|
|
478
|
+
Remember `await bot.init()` first when you don't call `launch()` (it fetches
|
|
479
|
+
bot info), and `setWebhook(url)` via `bot.api.setWebhook({ url })`.
|
|
480
|
+
|
|
481
|
+
<a id="proxy"></a>
|
|
482
|
+
### 🔌 Proxy transport (VPS behind a proxy)
|
|
483
|
+
|
|
484
|
+
```js
|
|
485
|
+
const { TeleBibz, createTransport } = require('@xbibzlibrary/telebibz');
|
|
486
|
+
const bot = new TeleBibz(token, {
|
|
487
|
+
transport: createTransport(token, { proxy: 'http://user:pass@proxy:8080' }),
|
|
488
|
+
});
|
|
489
|
+
```
|
|
156
490
|
|
|
157
|
-
|
|
491
|
+
`createTransport(token, { apiRoot, proxy, timeoutMs, headers })` also lets you
|
|
492
|
+
point at a local Bot API server.
|
|
158
493
|
|
|
159
|
-
|
|
160
|
-
|
|
494
|
+
<a id="transformers"></a>
|
|
495
|
+
### 🧪 Transformers (escape hatch)
|
|
161
496
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
497
|
+
```js
|
|
498
|
+
bot.api.config.use(async (prev, method, payload) => {
|
|
499
|
+
console.log('→', method); // observe/modify every Bot API call
|
|
500
|
+
return prev(method, payload);
|
|
165
501
|
});
|
|
502
|
+
|
|
503
|
+
// any method, even unreleased ones (Proxy magic):
|
|
504
|
+
await bot.api.sendDiceCustom({ chat_id: 1, emoji: '🎲' });
|
|
166
505
|
```
|
|
167
506
|
|
|
168
|
-
|
|
507
|
+
<a id="analytics"></a>
|
|
508
|
+
## 📈 Analytics & Statistics
|
|
169
509
|
|
|
170
|
-
|
|
510
|
+
### 📊 This repo in numbers
|
|
171
511
|
|
|
172
|
-
|
|
512
|
+
| Metric | Value |
|
|
513
|
+
|---|---|
|
|
514
|
+
| 📦 Source modules | **16 files** in `lib/` |
|
|
515
|
+
| 📝 Total lines of code | **~1,700** (no build step) |
|
|
516
|
+
| 🔌 Bot API methods | **90+** — 75 typed shortcuts + unbounded Proxy |
|
|
517
|
+
| ⌨️ Context shortcuts | **50+** (reply/edit/delete/admin/react…) |
|
|
518
|
+
| 🧪 Offline tests | **30/30 passing**, zero network |
|
|
519
|
+
| 🧩 Ready examples | **7** in `examples/` |
|
|
520
|
+
| 📦 Runtime dependencies | **4** — all used, all tested |
|
|
173
521
|
|
|
174
|
-
|
|
175
|
-
- **No proactive throttling.** Outgoing requests are never delayed by the library. When Telegram answers 429, the transport waits exactly the `retry_after` window Telegram ordered (a global "flood gate" protects all in-flight traffic) and retries automatically — so bursts deliver completely instead of failing. For your own downstream limits, `Limiter` and `mapWithConcurrency()` rate-shape any workload.
|
|
176
|
-
- **Broadcast to 1000+ users at once.** `bot.broadcast()` attempts every chat immediately, retries 429s per Telegram's own `retry_after`, and returns a full report.
|
|
177
|
-
- **Graceful shutdown.** `bot.stop()` first waits for in-flight handlers to finish (bounded by `handlerTimeout`) and only then stops the plugin manager — active conversations are never truncated mid-write.
|
|
522
|
+
### ⬇️ Downloads & popularity (live from npm)
|
|
178
523
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
{ onProgress: (p) => console.log(`${p.delivered}/${p.total} delivered`) },
|
|
184
|
-
);
|
|
185
|
-
console.log(`Delivered ${report.delivered}/${report.total} in ${report.durationMs}ms`);
|
|
186
|
-
```
|
|
524
|
+
[](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
|
|
525
|
+
[](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
|
|
526
|
+
[](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
|
|
527
|
+
[](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
|
|
187
528
|
|
|
188
|
-
|
|
529
|
+
### 📏 Module size map (lines of code)
|
|
189
530
|
|
|
190
|
-
|
|
531
|
+
```
|
|
532
|
+
wizard.js █████████████████████████ 247 ← forms + buttons + edit/delete
|
|
533
|
+
telebibz.js ███████████████████▎ 193 ← main class & lifecycle
|
|
534
|
+
context.js ███████████████████ 190 ← ctx + 50-ish shortcuts
|
|
535
|
+
composer.js █████████████████▍ 174 ← middleware engine & filters
|
|
536
|
+
api.js ███████████████▍ 154 ← 75 shortcuts + Proxy + transformers
|
|
537
|
+
net.js ███████████▌ 115 ← axios transport + multipart
|
|
538
|
+
menus.js █████████ 90 ← Menu/MenuContainer
|
|
539
|
+
keyboard.js ████████▎ 83 ← btn/url/kb + fluent classes
|
|
540
|
+
ratelimit.js ██████ 61 ← autoRetry · throttler · limiter
|
|
541
|
+
runner.js ████▌ 45 ← 409-resilient polling
|
|
542
|
+
file.js ████ 41 ← InputFile + InputMediaBuilder
|
|
543
|
+
logger.js ███▊ 38 ← logs + banner
|
|
544
|
+
session.js ███▌ 36 ← swappable sessions
|
|
545
|
+
errors.js ███▌ 35 ← humanized errors 🇮
|
|
546
|
+
broadcast.js ███ 35 ← rate-limit-safe blast
|
|
547
|
+
inline-query.js██▊ 28 ← matcher + result builders
|
|
548
|
+
```
|
|
191
549
|
|
|
192
|
-
|
|
550
|
+
### 🗺️ Repo health
|
|
193
551
|
|
|
194
|
-
|
|
195
|
-
- **Chat management** — `ctx.setChatTitle/Description/Photo`, `ctx.setChatPermissions`, `ctx.leaveChat`, `ctx.unpinAllChatMessages`, `ctx.setChatStickerSet`, `ctx.deleteChatStickerSet`
|
|
196
|
-
- **Info** — `ctx.getChatAdministrators`, `ctx.getChatMemberCount`, `ctx.getChatMember`
|
|
197
|
-
- **Invite links & join requests** — `ctx.exportChatInviteLink`, `ctx.createChatInviteLink`, `ctx.editChatInviteLink`, `ctx.revokeChatInviteLink`, `ctx.approveChatJoinRequest`, `ctx.declineChatJoinRequest`
|
|
198
|
-
- **Polls, games, payments** — `ctx.replyWithQuiz`, `ctx.stopPoll`, `ctx.editMessageLiveLocation`, `ctx.stopMessageLiveLocation`, `ctx.replyWithGame`, `ctx.setGameScore`, `ctx.getGameHighScores`, `ctx.replyWithInvoice`
|
|
199
|
-
- **Forum topics** — `ctx.createForumTopic`, `ctx.closeForumTopic`, `ctx.editGeneralForumTopic`, and nine more
|
|
200
|
-
- **Launch options** — `handlerTimeout` (default 90s, like Telegraf) rejects hung updates with `UpdateTimeoutError` while the handler keeps running; `0` disables the timeout; `contextType` plugs in your own `Context` subclass; `dropPendingUpdates` on `start()/launch()`
|
|
201
|
-
- **Webhook replies** — opt-in `webhookReply: true` answers the first API call through the webhook HTTP response itself (Telegraf-style), with the lazy `getMe` never claiming the slot
|
|
202
|
-
- **Drop-in handler aliases** — `bot.action(...)` registers a callback-query handler just like `bot.callback(...)`, so handlers written for Telegraf migrate unchanged
|
|
552
|
+
<div align="center">
|
|
203
553
|
|
|
204
|
-
|
|
554
|
+
[](https://github.com/XbibzOfficial777/telebibz)
|
|
205
555
|
|
|
206
|
-
|
|
556
|
+
</div>
|
|
207
557
|
|
|
208
|
-
|
|
558
|
+
<details>
|
|
559
|
+
<summary>📅 Star history (click to open)</summary>
|
|
209
560
|
|
|
210
|
-
|
|
561
|
+

|
|
211
562
|
|
|
212
|
-
|
|
563
|
+
</details>
|
|
213
564
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
↳ Text: /start
|
|
217
|
-
[ => ] Callback From 123456789 John Doe 29/08/2026 15:04:07
|
|
218
|
-
↳ Data: menu:open
|
|
219
|
-
```
|
|
565
|
+
<a id="examples"></a>
|
|
566
|
+
## 🧩 Ready Examples (`examples/`)
|
|
220
567
|
|
|
221
|
-
|
|
568
|
+
| File | Content |
|
|
569
|
+
|---|---|
|
|
570
|
+
| `01-quickstart.js` | bot up in 6 lines |
|
|
571
|
+
| `02-menu-tombol.js` | colored keyboard + animated icons |
|
|
572
|
+
| `03-wizard.js` | registration form + **buttons + edit mode** |
|
|
573
|
+
| `04-broadcast.js` | admin blast |
|
|
574
|
+
| `05-kirim-file.js` | photos & documents from buffers |
|
|
575
|
+
| `06-menu.js` | interactive menus + submenus |
|
|
576
|
+
| `07-inline-query.js` | inline mode with result builders |
|
|
222
577
|
|
|
223
|
-
|
|
578
|
+
Run any of them with `BOT_TOKEN=123:abc node examples/01-quickstart.js`.
|
|
224
579
|
|
|
225
|
-
|
|
580
|
+
<a id="testing"></a>
|
|
581
|
+
## 🔬 Testing & Live Proof
|
|
226
582
|
|
|
227
583
|
```bash
|
|
228
|
-
npm
|
|
229
|
-
npx telebibz init my-bot
|
|
230
|
-
npx telebibz doctor
|
|
231
|
-
npx telebibz build
|
|
232
|
-
npx telebibz test
|
|
584
|
+
npm test # 30 cases, NO network (transport injected)
|
|
233
585
|
```
|
|
234
586
|
|
|
235
|
-
|
|
587
|
+
Validated **30/30 offline + 10 live** on the production bot `@xbibzrat_bot`:
|
|
588
|
+
getMe · colored keyboards & real animated icons · multipart uploads
|
|
589
|
+
(photo+document) · keyboard editing · broadcast · deleteMessage · polling 409
|
|
590
|
+
retry · wizard buttons & edit/delete.
|
|
236
591
|
|
|
237
|
-
|
|
238
|
-
import { printTeleBibzBanner, printTerminalBranding } from "@xbibzlibrary/telebibz";
|
|
592
|
+
Debug logging: `DEBUG=telebibz:net,telebibz:ratelimit node yourbot.js`.
|
|
239
593
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
```
|
|
594
|
+
<a id="structure"></a>
|
|
595
|
+
## 📂 Repo Structure (16 core files)
|
|
243
596
|
|
|
244
|
-
|
|
597
|
+
| File | Role |
|
|
598
|
+
|---|---|
|
|
599
|
+
| `lib/net.js` | axios keep-alive transport + multipart `attach://` |
|
|
600
|
+
| `lib/api.js` | Bot API methods + any-method Proxy + transformers |
|
|
601
|
+
| `lib/composer.js` | middleware, `on('message:photo')` filters, `errorBoundary` |
|
|
602
|
+
| `lib/context.js` | ctx object + 50-ish reply/edit/delete/callback shortcuts |
|
|
603
|
+
| `lib/session.js` | per user:chat sessions (swappable storage) |
|
|
604
|
+
| `lib/runner.js` | long polling: 409 retry, network backoff, drop pending |
|
|
605
|
+
| `lib/wizard.js` | conversation forms + choice buttons + edit/delete modes |
|
|
606
|
+
| `lib/menus.js` | `Menu`/`MenuContainer` interactive menus |
|
|
607
|
+
| `lib/keyboard.js` | button builders + fluent `InlineKeyboard`/`Keyboard` |
|
|
608
|
+
| `lib/ratelimit.js` | `autoRetry` 429 · `throttler` queue · per-user `limiter` |
|
|
609
|
+
| `lib/broadcast.js` | rate-limit-safe blast |
|
|
610
|
+
| `lib/file.js` | `File`/`InputFile` (Buffer/path/stream) + `InputMediaBuilder` |
|
|
611
|
+
| `lib/inline-query.js` | query matcher + inline result builders |
|
|
612
|
+
| `lib/errors.js` | humanized errors + suggestions |
|
|
613
|
+
| `lib/logger.js` | framed logs + boot banner |
|
|
614
|
+
| `index.js` / `index.d.ts` | export door + TypeScript types |
|
|
245
615
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
npm run test:types
|
|
249
|
-
npm run lint
|
|
250
|
-
npm test
|
|
251
|
-
npm run build
|
|
252
|
-
npm run security
|
|
253
|
-
npm run release:check
|
|
254
|
-
```
|
|
616
|
+
<a id="changelog"></a>
|
|
617
|
+
## 🕐 Changelog
|
|
255
618
|
|
|
256
|
-
|
|
619
|
+
- **3.1.0** — wizard: choice buttons (reply/inline), `edit`/`delete` modes, auto cleanup, programmatic helpers · tests 24 → 30
|
|
620
|
+
- **3.0.0** — production-grade grammY parity: axios keep-alive, transformers, menus, inline query, limiter
|
|
621
|
+
- **2.0.0** — engine rewritten from scratch, multipart transport, native Node webhook
|
|
622
|
+
- **1.0.0** — grammY architecture recode
|
|
257
623
|
|
|
258
|
-
|
|
624
|
+
> Full details in [`CHANGELOG.md`](CHANGELOG.md). Deep architecture study (🇮): [`ANALISIS-telebibz.md`](ANALISIS-telebibz.md).
|
|
259
625
|
|
|
260
|
-
|
|
626
|
+
<a id="license"></a>
|
|
627
|
+
## 📄 License
|
|
261
628
|
|
|
262
|
-
|
|
629
|
+
**MIT** © Xbibz Official — architecture inspired by [grammY](https://grammy.dev) (MIT, see [`NOTICE.md`](NOTICE.md)).
|
|
263
630
|
|
|
264
|
-
|
|
631
|
+
---
|
|
265
632
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
| Context | `Context`, `ContextOptions`, `contextType` launch option; ~80 shortcuts on `ctx` for replies, admin actions, chat management, invite links, polls, games, payments, and forum topics |
|
|
270
|
-
| Telegram API | `ApiClient` with `call()`, `request()`, `raw()`, `downloadFile()`, and `methods` (all generated Bot API methods); `FetchTransport` with automatic 429/5xx retries, a global flood gate, multipart uploads (Blob/bytes/path/streams), and file downloads |
|
|
271
|
-
| Errors | `TelegramError` with a `kind` taxonomy (`retryable`, `rate-limit`, `authentication`, `validation`, `network`, `server`, `unknown`) and `retryAfter`, plus `TelegramRateLimitError`, `TelegramAuthError`, `TelegramValidationError`, `TelegramNetworkError` |
|
|
272
|
-
| Router & middleware | `Router`, `compose`, 24 update filters (`message:photo`, `callback_query:data`, …), `matchMode` (`first`/`all`) |
|
|
273
|
-
| Keyboards | `InlineKeyboard`, `ReplyKeyboard`, `removeKeyboard()`, `forceReply()` |
|
|
274
|
-
| Storage | `MemoryStorage` (TTL, per-key serialization), `JsonFileStorage`, `RedisStorage`, `SqlStorage`, `MongoStorage`, plus the small driver interfaces they build on |
|
|
275
|
-
| Cache & limiting | `MemoryCache`, `TokenBucketLimiter`, `Limiter`, `mapWithConcurrency()` |
|
|
276
|
-
| Queue & scheduler | `TaskQueue` (priority, retry, backoff, delay, cancel), `Scheduler` (intervals, one-shot, cron), `parseCronExpression()`, `nextCronOccurrence()` |
|
|
277
|
-
| State & dialogs | `Wizard`, `ConversationManager`, `ConversationFlow`, `Form` with `validators`, permission-aware `Menu`, `MenuController`, `paginate()` |
|
|
278
|
-
| Webhook | `createWebhookHandler()` (Web `Request`/`Response`), `webhookCallback()` for Express/Koa/Fastify/Node `http`, `runWithWebhookReply()`, `claimWebhookReply()` |
|
|
279
|
-
| Web Apps & payments | `parseWebAppInitData()`, `validateWebAppInitData()`, `PaymentsClient`, `TelegramTypes` (vendored Telegram declarations) |
|
|
280
|
-
| Observability | `Logger` (levels, redaction, JSON format), `EventBus` with the `update:*`, `bot:*`, and `broadcast:*` event maps, `redact()` |
|
|
281
|
-
| Terminal | `printTeleBibzBanner()`, `printTerminalBranding()`, `buildTerminalBranding()`, `runStartupSequence()`, `startTeleBibzBanner()`, `paintRainbow()`, `printStatusLine()` |
|
|
282
|
-
| Text utilities | `splitMessage()`, `splitCaption()`, `escapeMarkdownV2()`, `escapeHtml()`, `md`, `html`, `template()` |
|
|
283
|
-
| File utilities | `validateUpload()`, `assertValidUpload()`, `UploadValidationError` (size, MIME, extension rules) |
|
|
284
|
-
| Testing (`@xbibzlibrary/telebibz/testing`) | `MockTransport` (with mock downloads), `createTestBot()`, `createMockUpdate()`, `createMockCallbackUpdate()`, `createMockContext()` |
|
|
285
|
-
| CLI (`telebibz …`) | `init`, `doctor`, `build`, `test`, `start`, `webhook`, `generate` |
|
|
286
|
-
|
|
287
|
-
## API targets and limitations
|
|
288
|
-
|
|
289
|
-
The generated method list is derived from the Telegram Bot API schema when it is updated. Runtime access is available for detected official methods, while specialized request/result inference remains concentrated on the core method map. The complete vendored Telegram object, union, enum, and method declarations are available through `TelegramTypes`. See [FEATURE_MATRIX.md](FEATURE_MATRIX.md) for implementation status and [docs/API.md](docs/API.md) for the complete API reference.
|
|
290
|
-
|
|
291
|
-
For every exported class, function, method, type, error, lifecycle hook, CLI command, and generated Telegram method, see the [complete English API reference](docs/API.md).
|
|
292
|
-
|
|
293
|
-
## Release automation
|
|
294
|
-
|
|
295
|
-
The GitHub repository includes CI and an auto-publish workflow. A push to `main` runs the quality gates and derives the next version from the pushed Conventional Commits: `feat:` commits and breaking changes bump the minor version while the package is pre-1.0 (`BREAKING-CHANGE` footers or `type!:` subjects bump the major from 1.0.0 onward), everything else bumps the patch version. A version already declared in `package.json` ahead of npm publishes exactly as declared, and the workflow never publishes a version at or below the latest npm release. The workflow commits the version, creates the tag, publishes to npm (with provenance disabled via `--provenance=false`), and creates a GitHub Release. Commits containing `[skip release]` do not trigger a publication. Configure the `NPM_TOKEN` GitHub Actions secret before relying on automatic publication. See [RELEASE_AUTOMATION.md](RELEASE_AUTOMATION.md).
|
|
296
|
-
|
|
297
|
-
## Project policies and contribution
|
|
298
|
-
|
|
299
|
-
| Document | Purpose |
|
|
300
|
-
|---|---|
|
|
301
|
-
| [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) | Community behavior, enforcement, reporting, and appeals. |
|
|
302
|
-
| [CONTRIBUTING.md](CONTRIBUTING.md) | Local setup, branch/commit rules, tests, review, and release workflow. |
|
|
303
|
-
| [CONTRIBUTION_RULES.md](CONTRIBUTION_RULES.md) | API, compatibility, testing, dependency, security, and release requirements. |
|
|
304
|
-
| [GOVERNANCE.md](GOVERNANCE.md) | Roles, decision-making, triage, repository protection, and amendments. |
|
|
305
|
-
| [SECURITY.md](SECURITY.md) | Private vulnerability reporting, threat boundaries, and credential rotation. |
|
|
306
|
-
| [SUPPORT.md](SUPPORT.md) | Support channels, safe-reporting rules, and request expectations. |
|
|
307
|
-
| [RELEASE_AUTOMATION.md](RELEASE_AUTOMATION.md) | GitHub-to-npm automation and required `NPM_TOKEN` setup. |
|
|
308
|
-
| [RELEASE_POLICY.md](RELEASE_POLICY.md) | Immutable release and hardening controls. |
|
|
309
|
-
| [NOTICE.md](NOTICE.md) | Third-party declaration attribution. |
|
|
633
|
+
<div align="center">
|
|
634
|
+
|
|
635
|
+
**Made with ❤️ by //—Xbibz Official—//**
|
|
310
636
|
|
|
311
|
-
|
|
637
|
+
If telebibz helps you, a ⭐ on this repo means a lot.
|
|
312
638
|
|
|
313
|
-
|
|
639
|
+
[](https://github.com/XbibzOfficial777/telebibz)
|
|
314
640
|
|
|
315
|
-
|
|
641
|
+
</div>
|