@xbibzlibrary/telebibz 3.0.1 โ†’ 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/README.md CHANGED
@@ -1,232 +1,641 @@
1
- # ๐Ÿค– telebibz
1
+ <div align="center">
2
2
 
3
- **Library Telegram paling gampang untuk Node.js, set fitur penuh setara grammY** โ€” recode mandiri atas arsitektur elegan [grammY](https://grammy.dev) (MIT โ€” lihat [NOTICE.md](NOTICE.md)) dengan dependency produksi yang **benar-benar dipakai** (axios keep-alive, mime-types, https-proxy-agent, debug).
3
+ [๐Ÿ‡ฌ๐Ÿ‡ง **English**](README.md) ยท [๐Ÿ‡ฎ **Indonesia**](README.id.md)
4
4
 
5
- ```
6
- npm install @xbibzlibrary/telebibz
7
- ```
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
+ [![npm version](https://img.shields.io/npm/v/@xbibzlibrary/telebibz?style=for-the-badge&logo=npm&logoColor=white&color=CB3837&label=telebibz)](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
20
+ [![downloads](https://img.shields.io/npm/dm/@xbibzlibrary/telebibz?style=for-the-badge&logo=npm&logoColor=white&color=green&label=downloads%2Fmonth)](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
21
+ [![node](https://img.shields.io/node/v/@xbibzlibrary/telebibz?style=for-the-badge&logo=node.js&logoColor=white&color=339933&label=node)](https://nodejs.org)
22
+ [![tests](https://img.shields.io/badge/tests-30%2F30%20passing-brightgreen?style=for-the-badge&logo=checkmarx&logoColor=white)](#-testing--live-proof)
23
+ [![size](https://img.shields.io/badge/code-1.7k%20lines-orange?style=for-the-badge&logo=codeigniter&logoColor=white)](#-analytics--statistics)
24
+ [![license](https://img.shields.io/npm/l/@xbibzlibrary/telebibz?style=for-the-badge&color=blue)](LICENSE)
25
+ [![views](https://komarev.com/ghpvc/?username=XbibzOfficial777&repo=telebibz&style=for-the-badge&color=blueviolet&label=repo+views)](https://github.com/XbibzOfficial777/telebibz)
8
26
 
9
- ## ๐Ÿ“Š FEATURE MATRIX (parity grammY)
27
+ <br>
10
28
 
11
- | Fitur | grammY | telebibz |
29
+ `//โ€”Xbibz Officialโ€”//`
30
+
31
+ </div>
32
+
33
+ ---
34
+
35
+ ## ๐Ÿ“‘ Table of Contents
36
+
37
+ | | | |
12
38
  |---|---|---|
13
- | Proxy API **segala metode** (auto-generated) | โœ… `api.xyz()` | โœ… `api.xyz({...})` |
14
- | ~60 shortcut bertipe (sendMessage, banChatMemberโ€ฆ) | โœ… | โœ… |
15
- | Context lengkap (~70 pintasan reply/edit/admin/react) | โœ… | โœ… |
16
- | Context flavor business (`business_connection_id` otomatis) | plugin | โœ… bawaan |
17
- | Filter `on('message:photo' / ':text' / 'chat_type:private' โ€ฆ)` | โœ… | โœ… |
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' โ€ฆ)` | โœ… | โœ… |
18
73
  | `cmd / hears / action / inlineQuery` | โœ… | โœ… (+ inlineQuery matcher) |
19
74
  | `branch / filter / drop / route / lazy / fork` | โœ… | โœ… |
20
- | Error boundary + catch | โœ… | โœ… (semua shortcut otomatis terlindungi) |
21
- | Session + storage swappable | โœ… | โœ… |
75
+ | Error boundary + catch | โœ… | โœ… (all shortcuts auto-protected) |
76
+ | Session + swappable storage | โœ… | โœ… |
22
77
  | Transformer API (`api.config.use`) | โœ… | โœ… |
23
- | `auto-retry` 429 hormati `retry_after` | plugin (@grammyjs/auto-retry) | โœ… bawaan `autoRetry()` |
24
- | Throttler antre-rate-limit | plugin | โœ… bawaan `throttler()` |
25
- | Rate limit per-user | plugin | โœ… bawaan `limiter()` |
26
- | `InputFile` Buffer/path/stream + multipart attach:// | โœ… | โœ… |
27
- | `InputMedia` builder + media group | โœ… | โœ… `InputMediaBuilder` |
28
- | Download file (`getFile`/`downloadFile`) | plugin grammy/files | โœ… bawaan |
29
- | Keyboard & InlineKeyboard fluent class | โœ… | โœ… |
30
- | Menu interaktif | plugin @grammyjs/menu | โœ… bawaan `Menu/MenuContainer` |
31
- | Wizard/percakapan | plugin conversations | โœ… bawaan `wizard()` (lebih simpel) |
32
- | Long polling tahan-409 | โŒ (fatal crash) | โœ… bawaan (auto-retry 5 dtk) |
33
- | Broadcast siap pakai | โŒ | โœ… `bot.broadcast()` |
34
- | Humanisasi error + saran (๐Ÿ‡ฎ๐Ÿ‡ฉ) | โŒ | โœ… `humanize()` |
35
- | Banner boot cantik + log debug | โŒ | โœ… (`DEBUG=telebibz*`) |
36
- | Proxy HTTP(S) untuk VPS | โš ๏ธ via config manual | โœ… opsi `proxy` transport |
37
- | TypeScript | โœ… full | d.ts longgar (JS-first) |
38
- | Docs bahasa | en | **๐Ÿ‡ฎ๐Ÿ‡ฉ Indonesia-first** |
39
-
40
- ## Dependensi (semuanya dipakai nyata โ€” tertest)
41
- | Paket | Untuk |
42
- |---|---|
43
- | `axios ^1.20` | transport keep-alive + streaming downloadFile |
44
- | `mime-types ^3.0` | deteksi content-type upload |
45
- | `https-proxy-agent ^9.1` | opsi proxy transport VPS |
46
- | `debug ^4.4` | logging `DEBUG=telebibz:net,telebibz:ratelimit` |
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).
99
+
100
+ ```bash
101
+ npm install @xbibzlibrary/telebibz
102
+ # or
103
+ yarn add @xbibzlibrary/telebibz
104
+ # or
105
+ pnpm add @xbibzlibrary/telebibz
106
+ ```
47
107
 
48
- > โ“ *"Kenapa bukan protobuf?"* โ€” Bot API memakai **JSON/HTTP murni**, protobuf hanya relevan di dunia MTProto (user-client). Menambahkannya = dependency mati, melanggar prinsip *"semua library harus berfungsi"*.
108
+ **Runtime dependencies (all used, all tested):**
49
109
 
50
- ---
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` |
51
116
 
52
- ## ๐Ÿš€ Mulai dalam 6 baris
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.
119
+
120
+ <a id="quickstart"></a>
121
+ ## ๐Ÿš€ Quick Start
53
122
 
54
123
  ```js
55
124
  const { TeleBibz } = require('@xbibzlibrary/telebibz');
56
125
 
57
- const bot = new TeleBibz('TOKEN_DARI_BOTFATHER');
126
+ const bot = new TeleBibz('TOKEN_FROM_BOTFATHER');
58
127
 
59
- bot.cmd('start', (ctx) => ctx.reply('Halo!'));
60
- bot.hears(/halo/i, (ctx) => ctx.reply('halo juga ๐Ÿ‘‹'));
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 ๐Ÿ“'));
61
131
 
62
132
  bot.launch();
63
133
  ```
64
134
 
65
- ```
135
+ ```bash
66
136
  BOT_TOKEN=123:abc node index.js
67
137
  ```
68
138
 
69
- Output terminal:
70
139
  ```
71
- โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
72
- โ”‚ ๐Ÿค– TeleBibz ON โ”‚
73
- โ”‚ bot : @botkamu โ”‚
74
- โ”‚ engine : grammY 1.46โ”‚
75
- โ”‚ brand : //โ€”Xbibz Officialโ€”//
76
- โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
77
- โœ” menunggu updateโ€ฆ (Ctrl+C untuk berhenti)
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)
78
148
  ```
79
149
 
80
- > **Hidup di VPS:** kalau ada instance bot lain yang masih polling (409 Conflict โ€” misal deploy
81
- > ganda atau hosting restart), telebibz **otomatis retry tiap 5 detik tanpa crash** dan menyalakan
82
- > diri begitu jalur bebas. Tidak perlu PM2 babysitter.
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.
83
154
 
84
- ---
155
+ <a id="architecture"></a>
156
+ ## ๐Ÿง  How It Works (Architecture)
157
+
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
+ ```
85
186
 
86
- ## ๐Ÿ“š API lengkap (semuanya!)
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.
87
192
 
88
- ### Perintah & teks
193
+ <a id="docs"></a>
194
+ ## ๐Ÿ“– Full Documentation
195
+
196
+ ### ๐Ÿ—๏ธ Constructor & options
89
197
 
90
198
  ```js
91
- bot.cmd('ping', (ctx) => ctx.reply('pong')); // /ping
92
- bot.cmd(['a', 'b'], handler); // /a ATAU /b
93
- bot.hears('daftar', handler); // teks persis "daftar"
94
- bot.hears(/kampret/i, handler); // regex bebas
95
- bot.on('message:photo', handler); // filter grammY apa pun
96
- bot.use(middleware); // middleware manual
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
+ });
97
207
  ```
98
208
 
99
- ### Tombol (keyboard) โ€” berwarna & ikon animated
209
+ <a id="handlers"></a>
210
+ ### ๐ŸŽ›๏ธ Handlers & filters
100
211
 
101
212
  ```js
102
- const { btn, url, webApp, copy, kb } = require('@xbibzlibrary/telebibz');
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
+ ```
224
+
225
+ Composer combinators (grammY semantics):
226
+
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()
234
+ ```
235
+
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.
241
+
242
+ Command handlers receive arguments in `ctx.match`:
243
+
244
+ ```js
245
+ bot.cmd('echo', (ctx) => ctx.reply(`args: ${ctx.match}`)); // /echo hello โ†’ "hello"
246
+ ```
247
+
248
+ <a id="context"></a>
249
+ ### ๐Ÿ’ฌ Context shortcuts
250
+
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`.
254
+
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');
103
273
 
104
274
  bot.cmd('menu', (ctx) =>
105
- ctx.reply('Pilih:', kb([
106
- [btn('๐Ÿ’Ž Premium', 'prem', 'primary'), // biru/ungu
107
- btn('โœ… Daftar', 'reg', 'success')], // hijau
108
- [url('๐ŸŒ Web', 'https://situsmu.com')],
109
- [btn('โŒ Tutup', 'close', 'danger', '5408846744727334338')], // merah + IKON ANIMASI
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
110
280
  ])));
281
+ ```
282
+
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).
111
287
 
112
- bot.action('prem', async (ctx) => {
113
- await ctx.answerCallbackQuery('Menuju premiumโ€ฆ');
114
- await ctx.reply('halaman premium');
288
+ <a id="menus"></a>
289
+ ### ๐Ÿฝ๏ธ Interactive menus
290
+
291
+ ```js
292
+ const { Menu, MenuContainer } = require('@xbibzlibrary/telebibz');
293
+
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) }));
305
+ ```
306
+
307
+ Submenus swap the keyboard in place via `editMessageReplyMarkup`; stale button
308
+ presses are answered with a friendly alert instead of crashing.
309
+
310
+ <a id="wizard"></a>
311
+ ### ๐Ÿง™ Wizard โ€” conversation forms, zero boilerplate
312
+
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})!`),
115
321
  });
322
+ // user runs /register โ†’ the bot asks until finished.
323
+ // typing "cancel" / "batal" stops any time. Session is active automatically.
116
324
  ```
117
325
 
118
- - Warna (`primary`/`success`/`danger`) butuh aplikasi Telegram rilis โ‰ฅ Feb 2026 โ€” versi lama tampil biasa, tidak error.
119
- - Ikon animated (`icon_custom_emoji_id`) butuh **owner bot ber-Premium** atau username Fragment. Cari ID-nya: kirim custom emoji ke bot + lihat entity `custom_emoji` di update (atau sediakan `/emojiid` sendiri, 5 baris lewat `bot.on('message')`).
326
+ `bot.wizard(id, def, bindCommand = true)` also binds `/id` as the trigger; use
327
+ `bot.wizardStart(ctx, id)` from any handler (button, menu, โ€ฆ).
120
328
 
121
- ### Wizard โ€” form tanya-jawab tanpa boilerplate
329
+ #### ๐Ÿ†• v3.1 โ€” choice buttons + `edit`/`delete` modes
122
330
 
123
331
  ```js
124
- bot.wizard('daftar', {
332
+ bot.wizard('survey', {
333
+ mode: 'edit', // 'send' (default) | 'edit' | 'delete'
125
334
  steps: [
126
- { key: 'nama', ask: 'Siapa namamu?' },
127
- { key: 'umur', ask: 'Umur?', parse: Number,
128
- validate: (n) => (n > 0 && n < 120 ? null : 'Angka saja ya:') },
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' }]] },
341
+
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:') },
129
345
  ],
130
- done: async (ans, ctx) => ctx.reply(`Oke ${ans.nama} (${ans.umur})!`),
346
+ done: async (ans, ctx) => ctx.reply(`Saved: ${JSON.stringify(ans)}`),
131
347
  });
132
- // user tinggal /daftar โ†’ bot bertanya-bertanya sampai selesai.
133
- // ketik "batal" kapan pun untuk berhenti. Sesi otomatis aktif, tak perlu setup.
134
348
  ```
135
349
 
136
- ### Broadcast aman rate-limit
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
+ ```
377
+
378
+ Builders: `iq.article/photo/gif/video/audio/location/sticker`.
379
+
380
+ <a id="broadcast"></a>
381
+ ### ๐Ÿ“ฃ Broadcast (rate-limit safe)
382
+
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)
386
+ ```
387
+
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
+ ```
409
+
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.
414
+
415
+ <a id="ratelimit"></a>
416
+ ### ๐Ÿ›ก๏ธ Reliability & rate limiting
137
417
 
138
418
  ```js
139
- const hasil = await bot.broadcast([111, 222, 333], 'Pengumuman!', { delay: 35 });
140
- // โ†’ { terkirim: 3, gagal: 0, errors: [] } (yang diblokir-mu tercatat di errors)
419
+ const { autoRetry, throttler, limiter } = require('@xbibzlibrary/telebibz');
420
+
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
141
424
  ```
142
425
 
143
- ### Kirim file
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`).
429
+
430
+ <a id="sessions"></a>
431
+ ### ๐Ÿ—ƒ๏ธ Sessions
144
432
 
145
433
  ```js
146
- const { InputFile } = require('@xbibzlibrary/telebibz');
147
- bot.cmd('foto', (ctx) => ctx.replyWithPhoto(new InputFile(buf, 'x.jpg')));
434
+ const { session } = require('@xbibzlibrary/telebibz');
435
+
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
+ },
442
+ });
443
+
444
+ bot.on(':text', (ctx) => { ctx.session.count++; });
148
445
  ```
149
446
 
150
- ### Error yang bisa dibaca manusia
447
+ `ctx.session` is always present, even without configuration.
448
+
449
+ <a id="errors"></a>
450
+ ### ๐Ÿ‡ฎ๐Ÿ‡ฉ Human-readable errors
451
+
452
+ Every error is reported with an actionable suggestion:
151
453
 
152
- Default-nya setiap error dilaporkan dengan **saran penyelesaian**:
153
454
  ```
154
455
  โœ– Telegram error (403): Forbidden: bot was blocked by the user
155
456
  ๐Ÿ’ก saran: Bot diblokir pengguna โ€” jangan kirim ulang, hapus dari daftar broadcast.
156
457
  ```
157
- Kustom: `new TeleBibz(token, { onError: (err, ctx) => { ... } })`.
158
458
 
159
- ### Opsi konstruktor
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) => {} })`.
160
463
 
161
- | Opsi | Default | Fungsi |
162
- |---|---|---|
163
- | `allowedUpdates` | semua tipe umum + Business | batasi update yang diterima |
164
- | `onError` | reporter cantik bawaan | handle error sendiri |
165
- | `silent` | `false` | tanpa banner boot |
166
- | `dropPending` | `false` | buang update lama saat start |
167
- | `grammy` | `{}` | opsi mentah `new Bot()` grammY |
464
+ <a id="webhook"></a>
465
+ ### ๐Ÿ•ธ๏ธ Webhooks & serverless
466
+
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
476
+ ```
477
+
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 })`.
168
480
 
169
- ### Webhook / serverless
481
+ <a id="proxy"></a>
482
+ ### ๐Ÿ”Œ Proxy transport (VPS behind a proxy)
170
483
 
171
484
  ```js
172
- // express:
173
- app.use('/tg', bot.webhook('express'));
174
- // atau serverless manual:
175
- await bot.handleUpdate(req.body);
485
+ const { TeleBibz, createTransport } = require('@xbibzlibrary/telebibz');
486
+ const bot = new TeleBibz(token, {
487
+ transport: createTransport(token, { proxy: 'http://user:pass@proxy:8080' }),
488
+ });
176
489
  ```
177
490
 
178
- ### Escape hatch penuh
491
+ `createTransport(token, { apiRoot, proxy, timeoutMs, headers })` also lets you
492
+ point at a local Bot API server.
179
493
 
180
- Kapan pun butuh API mentah: `bot.api.sendMessage(...)`, `bot.bot` (instance grammY), `ctx.reply(...)`, `ctx.api.*` โ€” grammar lengkap grammY tetap berlaku 100%.
494
+ <a id="transformers"></a>
495
+ ### ๐Ÿงช Transformers (escape hatch)
181
496
 
182
- ---
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);
501
+ });
183
502
 
184
- ## ๐Ÿงฉ Contoh siap jalan (`examples/`)
503
+ // any method, even unreleased ones (Proxy magic):
504
+ await bot.api.sendDiceCustom({ chat_id: 1, emoji: '๐ŸŽฒ' });
505
+ ```
506
+
507
+ <a id="analytics"></a>
508
+ ## ๐Ÿ“ˆ Analytics & Statistics
185
509
 
186
- | File | Isi |
510
+ ### ๐Ÿ“Š This repo in numbers
511
+
512
+ | Metric | Value |
187
513
  |---|---|
188
- | `01-quickstart.js` | bot jalan dalam 6 baris |
189
- | `02-menu-tombol.js` | keyboard berwarna + ikon |
190
- | `03-wizard.js` | form pendaftaran |
191
- | `04-broadcast.js` | blast admin |
192
- | `05-kirim-file.js` | foto & dokumen dari buffer |
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 |
521
+
522
+ ### โฌ‡๏ธ Downloads & popularity (live from npm)
193
523
 
194
- ## ๐Ÿ”ฌ Test & bukti live
524
+ [![per day](https://img.shields.io/npm/dd/@xbibzlibrary/telebibz?style=flat-square&label=day&color=informational)](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
525
+ [![per week](https://img.shields.io/npm/dw/@xbibzlibrary/telebibz?style=flat-square&label=week&color=informational)](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
526
+ [![per month](https://img.shields.io/npm/dm/@xbibzlibrary/telebibz?style=flat-square&label=month&color=informational)](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
527
+ [![total](https://img.shields.io/npm/dt/@xbibzlibrary/telebibz?style=flat-square&label=total&color=informational)](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
195
528
 
529
+ ### ๐Ÿ“ Module size map (lines of code)
530
+
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
196
548
  ```
197
- npm test # 14 kasus, TANPA jaringan (transport disuntik)
549
+
550
+ ### ๐Ÿ—บ๏ธ Repo health
551
+
552
+ <div align="center">
553
+
554
+ [![repo card](https://github-readme-stats.vercel.app/api/pin/?username=XbibzOfficial777&repo=telebibz&show_owner=false)](https://github.com/XbibzOfficial777/telebibz)
555
+
556
+ </div>
557
+
558
+ <details>
559
+ <summary>๐Ÿ“… Star history (click to open)</summary>
560
+
561
+ ![Star History](https://api.star-history.com/svg?repos=XbibzOfficial777/telebibz&type=Date)
562
+
563
+ </details>
564
+
565
+ <a id="examples"></a>
566
+ ## ๐Ÿงฉ Ready Examples (`examples/`)
567
+
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 |
577
+
578
+ Run any of them with `BOT_TOKEN=123:abc node examples/01-quickstart.js`.
579
+
580
+ <a id="testing"></a>
581
+ ## ๐Ÿ”ฌ Testing & Live Proof
582
+
583
+ ```bash
584
+ npm test # 30 cases, NO network (transport injected)
198
585
  ```
199
586
 
200
- Tervalidasi **24/24 offline + 10 live** pada bot produksi @xbibzrat_bot: getMe, keyboard berwarna & ikon animasi asli,
201
- upload multipart (photo+document), edit keyboard, broadcast, deleteMessage, polling 409 retry.
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.
202
591
 
203
- ## ๐Ÿ“‚ Isi repo (11 file inti)
592
+ Debug logging: `DEBUG=telebibz:net,telebibz:ratelimit node yourbot.js`.
204
593
 
205
- | File | Peran |
594
+ <a id="structure"></a>
595
+ ## ๐Ÿ“‚ Repo Structure (16 core files)
596
+
597
+ | File | Role |
206
598
  |---|---|
207
- | `lib/net.js` | transport HTTP fetch murni + multipart `attach://` |
208
- | `lib/api.js` | metode Bot API + `api.callApi()` untuk segala metode |
209
- | `lib/composer.js` | middleware, filter `on('message:photo')`, `errorBoundary` |
210
- | `lib/context.js` | objek ctx + pintasan reply/edit/delete/callback |
211
- | `lib/session.js` | sesi per user:chat (dapat ditukar storagenya) |
212
- | `lib/runner.js` | long polling: retry 409, backoff jaringan, drop pending |
213
- | `lib/file.js` | `File`/`InputFile` (Buffer/path/stream) |
214
- | `lib/keyboard.js` | builder + `InlineKeyboard`/`Keyboard` fluent class |
215
- | `lib/wizard.js` | percakapan tanya-jawab berurutan |
216
- | `lib/broadcast.js` | blast aman rate limit |
217
- | `lib/errors.js` + `lib/logger.js` | error manusiawi + log berbingkai |
218
-
219
- ## ๐Ÿ†š Kenapa recode?
220
-
221
- | | v0.4 lama | v1.0 |
222
- |---|---|---|
223
- | Baris file sumber | 152 file TS | 7 file JS |
224
- | Build step | tsc ร—2 + script | โ€” |
225
- | Dependency runtime | โ€” | **0 (nol)** |
226
- | Bot API | manual update | 9.x penuh (uji live asli) |
227
- | Hello world | kelas + config | 6 baris |
228
- | Docs | 3 bahasa ร— belasan file | README ini |
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 |
615
+
616
+ <a id="changelog"></a>
617
+ ## ๐Ÿ• Changelog
618
+
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
623
+
624
+ > Full details in [`CHANGELOG.md`](CHANGELOG.md). Deep architecture study (๐Ÿ‡ฎ): [`ANALISIS-telebibz.md`](ANALISIS-telebibz.md).
625
+
626
+ <a id="license"></a>
627
+ ## ๐Ÿ“„ License
628
+
629
+ **MIT** ยฉ Xbibz Official โ€” architecture inspired by [grammY](https://grammy.dev) (MIT, see [`NOTICE.md`](NOTICE.md)).
630
+
631
+ ---
632
+
633
+ <div align="center">
634
+
635
+ **Made with โค๏ธ by //โ€”Xbibz Officialโ€”//**
636
+
637
+ If telebibz helps you, a โญ on this repo means a lot.
229
638
 
230
- ## ๐Ÿ“„ Lisensi
639
+ [![repo views](https://komarev.com/ghpvc/?username=XbibzOfficial777&repo=telebibz&style=flat-square&color=blueviolet&label=repo+views)](https://github.com/XbibzOfficial777/telebibz)
231
640
 
232
- MIT ยท //โ€”Xbibz Officialโ€”//
641
+ </div>