@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.id.md
CHANGED
|
@@ -1,306 +1,642 @@
|
|
|
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="Buka telebibz di 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
|
+
**Library Telegram paling gampang untuk Node.js — set fitur penuh setara grammY.**<br>
|
|
14
|
+
Recode mandiri atas arsitektur elegan [grammY](https://grammy.dev), dengan dependency
|
|
15
|
+
produksi yang *benar-benar dipakai*, dokumentasi 🇮🇩 Indonesia-first, dan nol drama.
|
|
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
|
+
[](#-test--bukti-live)
|
|
23
|
+
[](#-analitik--statistik)
|
|
24
|
+
[](LICENSE)
|
|
25
|
+
[](https://github.com/XbibzOfficial777/telebibz)
|
|
26
|
+
|
|
27
|
+
<br>
|
|
28
|
+
|
|
29
|
+
`//—Xbibz Official—//`
|
|
30
|
+
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 📑 Daftar Isi
|
|
36
|
+
|
|
37
|
+
| | | |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| ⚡ [Kenapa telebibz?](#kenapa) | 📊 [Matriks fitur vs grammY](#matriks) | 📥 [Instalasi & persyaratan](#instalasi) |
|
|
40
|
+
| 🚀 [Mulai cepat](#mulai) | 🧠 [Cara kerja (arsitektur)](#arsitektur) | 📖 [Dokumentasi lengkap](#dokumentasi) |
|
|
41
|
+
| 🎛️ [Handler & filter](#handler) | 💬 [Shortcut Context](#context) | 🔘 [Keyboard & tombol](#keyboard) |
|
|
42
|
+
| 🍽️ [Menu interaktif](#menu) | 🧙 [Wizard (form + tombol + edit/delete)](#wizard) | ❓ [Mode inline](#inline) |
|
|
43
|
+
| 📣 [Broadcast](#broadcast) | 📎 [File & media](#file) | 🛡️ [Keandalan & rate limit](#ratelimit) |
|
|
44
|
+
| 🗃️ [Session](#session) | 🇮🇩 [Error manusiawi](#error) | 🕸️ [Webhook & serverless](#webhook) |
|
|
45
|
+
| 🔌 [Transport proxy](#proxy) | 🧪 [Transformer](#transformer) | 📈 [Analitik & statistik](#analitik) |
|
|
46
|
+
| 🧩 [Contoh siap jalan](#contoh) | 🔬 [Test & bukti live](#test) | 📂 [Struktur repo](#struktur) |
|
|
47
|
+
| 🕐 [Changelog](#changelog) | 📄 [Lisensi](#lisensi) | |
|
|
48
|
+
|
|
49
|
+
<a id="kenapa"></a>
|
|
50
|
+
## ⚡ Kenapa telebibz?
|
|
51
|
+
|
|
52
|
+
> [!TIP]
|
|
53
|
+
> **Satu prinsip:** semua fitur yang di grammY butuh plugin, di telebibz sudah
|
|
54
|
+
> **bawaan** — wizard, menu, rate-limit, broadcast, download file — dan polling
|
|
55
|
+
> yang *tidak mati* kena 409.
|
|
56
|
+
|
|
57
|
+
- 🧠 **API grammY yang sudah kamu kenal** — `bot.cmd()`, `bot.hears()`, `ctx.reply()`, middleware, transformer
|
|
58
|
+
- 🧙 **Wizard bawaan v3.1** — form tanya-jawab dengan **tombol pilihan** (reply/inline) dan mode **edit/delete** pesan
|
|
59
|
+
- 🛡️ **Tahan banting** — auto-retry 429, throttler, limiter anti-spam, polling retry saat konflik 409
|
|
60
|
+
- 🇮🇩 **Error manusiawi** — setiap error Telegram diterjemahkan + dikasih saran penyelesaian
|
|
61
|
+
- 🔌 **Proxy API segala metode** — `api.metodeApaPun({...})` otomatis tersedia, bahkan untuk metode yang belum rilis
|
|
62
|
+
- 🪶 **Ringan & jujur** — 4 dependency, semuanya terpakai nyata dan ter-test
|
|
63
|
+
|
|
64
|
+
<a id="matriks"></a>
|
|
65
|
+
## 📊 Matriks Fitur — parity grammY
|
|
66
|
+
|
|
67
|
+
| Fitur | grammY | telebibz |
|
|
68
|
+
|---|:---:|:---:|
|
|
69
|
+
| Proxy API **segala metode** (auto-generated) | ✅ | ✅ |
|
|
70
|
+
| ~60 shortcut bertipe (sendMessage, banChatMember…) | ✅ | ✅ |
|
|
71
|
+
| Context lengkap (~70 pintasan reply/edit/admin/react) | ✅ | ✅ |
|
|
72
|
+
| Context flavor business (`business_connection_id` otomatis) | plugin | ✅ bawaan |
|
|
73
|
+
| Filter `on('message:photo' / ':text' / 'chat_type:private' …)` | ✅ | ✅ |
|
|
74
|
+
| `cmd / hears / action / inlineQuery` | ✅ | ✅ (+ inlineQuery matcher) |
|
|
75
|
+
| `branch / filter / drop / route / lazy / fork` | ✅ | ✅ |
|
|
76
|
+
| Error boundary + catch | ✅ | ✅ (semua shortcut otomatis terlindungi) |
|
|
77
|
+
| Session + storage swappable | ✅ | ✅ |
|
|
78
|
+
| Transformer API (`api.config.use`) | ✅ | ✅ |
|
|
79
|
+
| `auto-retry` 429 hormati `retry_after` | plugin | ✅ bawaan `autoRetry()` |
|
|
80
|
+
| Throttler antre-rate-limit | plugin | ✅ bawaan `throttler()` |
|
|
81
|
+
| Rate limit per-user | plugin | ✅ bawaan `limiter()` |
|
|
82
|
+
| `InputFile` Buffer/path/stream + multipart `attach://` | ✅ | ✅ |
|
|
83
|
+
| `InputMedia` builder + media group | ✅ | ✅ `InputMediaBuilder` |
|
|
84
|
+
| Download file (`getFile`/`downloadFile`) | plugin | ✅ bawaan |
|
|
85
|
+
| Keyboard & InlineKeyboard fluent class | ✅ | ✅ |
|
|
86
|
+
| Menu interaktif | plugin | ✅ bawaan `Menu/MenuContainer` |
|
|
87
|
+
| Wizard/percakapan | plugin | ✅ bawaan — **+ tombol pilihan & mode `edit`/`delete`** |
|
|
88
|
+
| Long polling tahan-409 | ❌ (fatal crash) | ✅ bawaan (auto-retry 5 dtk) |
|
|
89
|
+
| Broadcast siap pakai | ❌ | ✅ `bot.broadcast()` |
|
|
90
|
+
| Humanisasi error + saran (🇮🇩) | ❌ | ✅ `humanize()` |
|
|
91
|
+
| Banner boot + log debug | ❌ | ✅ (`DEBUG=telebibz*`) |
|
|
92
|
+
| Proxy HTTP(S) untuk VPS | ⚠️ manual | ✅ opsi `proxy` transport |
|
|
93
|
+
| TypeScript | ✅ full | d.ts longgar (JS-first) |
|
|
94
|
+
| Bahasa dokumentasi | en | **🇬🇧 + 🇮🇩** |
|
|
95
|
+
|
|
96
|
+
<a id="instalasi"></a>
|
|
97
|
+
## 📥 Instalasi & Persyaratan
|
|
98
|
+
|
|
99
|
+
**Persyaratan:** Node.js ≥ 18 (memakai `FormData`/`Blob` global untuk upload).
|
|
2
100
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
101
|
+
```bash
|
|
102
|
+
npm install @xbibzlibrary/telebibz
|
|
103
|
+
# atau
|
|
104
|
+
yarn add @xbibzlibrary/telebibz
|
|
105
|
+
# atau
|
|
106
|
+
pnpm add @xbibzlibrary/telebibz
|
|
107
|
+
```
|
|
9
108
|
|
|
10
|
-
|
|
109
|
+
**Dependency runtime (semuanya dipakai & ter-test):**
|
|
11
110
|
|
|
12
|
-
|
|
111
|
+
| Paket | Untuk |
|
|
112
|
+
|---|---|
|
|
113
|
+
| `axios ^1.20` | transport keep-alive + streaming `downloadFile` |
|
|
114
|
+
| `mime-types ^3.0` | deteksi content-type upload |
|
|
115
|
+
| `https-proxy-agent ^9.1` | opsi proxy transport VPS |
|
|
116
|
+
| `debug ^4.4` | log `DEBUG=telebibz:net,telebibz:ratelimit` |
|
|
13
117
|
|
|
14
|
-
|
|
118
|
+
Ambil token bot dari **@BotFather** → `/newbot`. Konstruktor memvalidasi format
|
|
119
|
+
token (`123456:ABC…`) dan melempar error yang jelas kalau salah.
|
|
15
120
|
|
|
16
|
-
|
|
121
|
+
<a id="mulai"></a>
|
|
122
|
+
## 🚀 Mulai Cepat
|
|
17
123
|
|
|
18
|
-
|
|
124
|
+
```js
|
|
125
|
+
const { TeleBibz } = require('@xbibzlibrary/telebibz');
|
|
19
126
|
|
|
20
|
-
|
|
127
|
+
const bot = new TeleBibz('TOKEN_DARI_BOTFATHER');
|
|
21
128
|
|
|
22
|
-
|
|
129
|
+
bot.cmd('start', (ctx) => ctx.reply('Halo!'));
|
|
130
|
+
bot.hears(/halo|hai/i, (ctx) => ctx.reply('halo juga 👋'));
|
|
131
|
+
bot.hears('ping', (ctx) => ctx.reply('pong 🏓'));
|
|
23
132
|
|
|
24
|
-
|
|
133
|
+
bot.launch();
|
|
134
|
+
```
|
|
25
135
|
|
|
26
|
-
|
|
136
|
+
```bash
|
|
137
|
+
BOT_TOKEN=123:abc node index.js
|
|
138
|
+
```
|
|
27
139
|
|
|
28
|
-
|
|
140
|
+
```
|
|
141
|
+
┌──────────────────────────────────┐
|
|
142
|
+
│ 🤖 TeleBibz ON │
|
|
143
|
+
│ bot : @botkamu (id 123456) │
|
|
144
|
+
│ mode : long-polling │
|
|
145
|
+
│ library : telebibz 3.1.0 │
|
|
146
|
+
│ brand : //—Xbibz Official—// │
|
|
147
|
+
└──────────────────────────────────┘
|
|
148
|
+
✔ menunggu update… (Ctrl+C untuk berhenti)
|
|
149
|
+
```
|
|
29
150
|
|
|
30
|
-
|
|
151
|
+
> [!NOTE]
|
|
152
|
+
> **Hidup di VPS:** kalau ada instance bot lain yang masih polling (409 Conflict —
|
|
153
|
+
> misal deploy ganda atau hosting restart), telebibz **otomatis retry tiap 5 detik
|
|
154
|
+
> tanpa crash** dan menyala begitu jalur bebas. Tidak perlu PM2 babysitter.
|
|
31
155
|
|
|
32
|
-
|
|
156
|
+
<a id="arsitektur"></a>
|
|
157
|
+
## 🧠 Cara Kerja (Arsitektur)
|
|
33
158
|
|
|
34
|
-
|
|
159
|
+
```
|
|
160
|
+
┌─────────────────────────────────────────────┐
|
|
161
|
+
Telegram Bot API ────►│ long polling (lib/runner.js) │
|
|
162
|
+
│ atau webhook / handleUpdate (lib/telebibz) │
|
|
163
|
+
└──────────────────┬──────────────────────────┘
|
|
164
|
+
│ update JSON mentah
|
|
165
|
+
▼
|
|
166
|
+
Context(update, api, me) lib/context.js
|
|
167
|
+
│
|
|
168
|
+
┌────────────────────────────▼───────────────────────────┐
|
|
169
|
+
│ Pohon middleware `_root` (urutan tetap): │
|
|
170
|
+
│ 1. session() lib/session.js │
|
|
171
|
+
│ 2. wizard.middleware() lib/wizard.js │
|
|
172
|
+
│ 3. errorBoundary(reporter) │
|
|
173
|
+
│ └─► handler kamu: use/cmd/hears/action/on/ │
|
|
174
|
+
│ inlineQuery/Menu/wizard lib/composer.js │
|
|
175
|
+
└────────────────────────────┬───────────────────────────┘
|
|
176
|
+
│ ctx.reply / ctx.api.*
|
|
177
|
+
▼
|
|
178
|
+
ApiBase + Proxy + pipeline transformer lib/api.js
|
|
179
|
+
(api.config.use → autoRetry / throttler)
|
|
180
|
+
│
|
|
181
|
+
▼
|
|
182
|
+
transport axios: JSON atau multipart attach:// lib/net.js
|
|
183
|
+
│
|
|
184
|
+
▼
|
|
185
|
+
https://api.telegram.org
|
|
186
|
+
```
|
|
35
187
|
|
|
36
|
-
|
|
188
|
+
**Lifecycle satu update** (mis. `/start`): `getUpdates` → `pollLoop` →
|
|
189
|
+
`handleUpdate` → `Context` baru → session dimuat → middleware wizard (tak ada
|
|
190
|
+
wizard aktif → lanjut) → error boundary → handler kamu yang cocok jalan →
|
|
191
|
+
`ctx.reply()` → pipeline transformer → axios → Telegram. Error yang dilempar
|
|
192
|
+
jadi `BotError` dan mengalir ke `opts.onError` atau reporter manusiawi.
|
|
193
|
+
|
|
194
|
+
<a id="dokumentasi"></a>
|
|
195
|
+
## 📖 Dokumentasi Lengkap
|
|
196
|
+
|
|
197
|
+
### 🏗️ Konstruktor & opsi
|
|
198
|
+
|
|
199
|
+
```js
|
|
200
|
+
const bot = new TeleBibz('TOKEN', {
|
|
201
|
+
allowedUpdates: [...], // batasi tipe update (default: tipe umum + Business)
|
|
202
|
+
onError: (err, ctx) {}, // handle error sendiri (default: reporter manusiawi)
|
|
203
|
+
silent: false, // tanpa banner boot
|
|
204
|
+
dropPending: false, // buang update lama saat start
|
|
205
|
+
session: { ... }, // { initial, getKey, storage } — lihat bagian Session
|
|
206
|
+
transport: fn, // suntik transport custom (test / proxy)
|
|
207
|
+
});
|
|
208
|
+
```
|
|
37
209
|
|
|
38
|
-
|
|
210
|
+
<a id="handler"></a>
|
|
211
|
+
### 🎛️ Handler & filter
|
|
212
|
+
|
|
213
|
+
```js
|
|
214
|
+
bot.cmd('ping', (ctx) => ctx.reply('pong')); // /ping
|
|
215
|
+
bot.cmd(['a', 'b'], handler); // /a ATAU /b
|
|
216
|
+
bot.start('Selamat datang!'); // shortcut: daftarkan /start
|
|
217
|
+
bot.hears('daftar', handler); // teks persis "daftar" (case-insensitive)
|
|
218
|
+
bot.hears(/kuc?ing/i, handler); // regex bebas
|
|
219
|
+
bot.on('message:photo', handler); // filter gaya grammY
|
|
220
|
+
bot.on([':text', 'chat_type:private'], handler);
|
|
221
|
+
bot.action('menu:premium', handler); // callback_query data (string / RegExp)
|
|
222
|
+
bot.inlineQuery(/kucing/i, handler); // mode inline (regex / string / '*')
|
|
223
|
+
bot.use(middleware); // middleware manual
|
|
224
|
+
```
|
|
39
225
|
|
|
40
|
-
|
|
226
|
+
Kombinator composer (semantik grammY):
|
|
41
227
|
|
|
42
|
-
```
|
|
43
|
-
|
|
228
|
+
```js
|
|
229
|
+
bot.branch(pred, kalauYa, kalauTidak); // pilih subpohon berdasar predikat
|
|
230
|
+
bot.filter(pred, ...mw); // jalan hanya jika pred(ctx) true
|
|
231
|
+
bot.drop(pred, ...mw); // dilewati jika pred(ctx) true
|
|
232
|
+
bot.route('chat.type', { private: mwA, group: mwB }); // petakan ctx → handler
|
|
233
|
+
bot.lazy((ctx) => ctx.from.is_bot ? mwBot : mwUser); // bangun mw per update
|
|
234
|
+
bot.fork(mwLambat); // jalan di latar, tidak menahan next()
|
|
44
235
|
```
|
|
45
236
|
|
|
46
|
-
|
|
237
|
+
Filter yang didukung `on()`: field update (`message`, `edited_message`,
|
|
238
|
+
`callback_query`, `inline_query`, `my_chat_member`, …), properti pesan
|
|
239
|
+
(`message:photo`, `message:text`, `:caption`, `:document`, `:sticker`, `:media`, …),
|
|
240
|
+
tipe chat (`chat_type:private/group/supergroup/channel`), plus
|
|
241
|
+
`callback_query:data`, payment, reaksi, join request.
|
|
47
242
|
|
|
48
|
-
|
|
243
|
+
Handler perintah menerima argumen di `ctx.match`:
|
|
49
244
|
|
|
50
|
-
```
|
|
51
|
-
|
|
245
|
+
```js
|
|
246
|
+
bot.cmd('echo', (ctx) => ctx.reply(`argumen: ${ctx.match}`)); // /echo halo → "halo"
|
|
247
|
+
```
|
|
52
248
|
|
|
53
|
-
|
|
249
|
+
<a id="context"></a>
|
|
250
|
+
### 💬 Shortcut Context
|
|
54
251
|
|
|
55
|
-
|
|
56
|
-
|
|
252
|
+
`ctx` membungkus semua jenis update (message, edited, channel, business,
|
|
253
|
+
callback, inline…) dengan accessor seragam: `chat`, `from`, `chatId`, `msgId`,
|
|
254
|
+
`msg`, `senderChat`, `inlineMessageId`, `businessConnectionId`.
|
|
57
255
|
|
|
58
|
-
|
|
256
|
+
| Kategori | Shortcut |
|
|
257
|
+
|---|---|
|
|
258
|
+
| **Balasan** | `reply`, `replyWithHTML`, `replyWithMarkdown`, `replyWithPhoto/Video/Audio/Document/Animation/Voice/VideoNote/Sticker/MediaGroup/Location/Venue/Contact/Poll/Dice/Invoice/ChatAction` |
|
|
259
|
+
| **Edit & hapus** | `editMessageText/Caption/Media/ReplyMarkup`, `deleteMessage`, `deleteMessages` — sadar callback & inline-message |
|
|
260
|
+
| **Reaksi** | `react('👍')` |
|
|
261
|
+
| **Teruskan/salin** | `forwardMessage(tujuan)`, `copyMessage(tujuan)` (default pesan saat ini) |
|
|
262
|
+
| **Callback & inline** | `answerCallbackQuery` (string atau objek), `answerInlineQuery` |
|
|
263
|
+
| **Admin** | `banChatMember`, `restrictChatMember`, `promoteChatMember`, `banAuthor`, `restrictAuthor`, `getChat*`, `getAuthor`, `leaveChat`, `setChatTitle/Description`, `pin/unpinChatMessage` |
|
|
264
|
+
| **File** | `getFile()` (pintar: photo terbesar), `downloadFile(dest)` |
|
|
265
|
+
|
|
266
|
+
Akun business: balasan dalam konteks business otomatis menyertakan
|
|
267
|
+
`business_connection_id`.
|
|
268
|
+
|
|
269
|
+
<a id="keyboard"></a>
|
|
270
|
+
### 🔘 Keyboard & tombol
|
|
271
|
+
|
|
272
|
+
```js
|
|
273
|
+
const { btn, url, webApp, copy, kb, InlineKeyboard, Keyboard } = require('@xbibzlibrary/telebibz');
|
|
274
|
+
|
|
275
|
+
bot.cmd('menu', (ctx) =>
|
|
276
|
+
ctx.reply('Pilih:', kb([
|
|
277
|
+
[btn('💎 Premium', 'prem', 'primary'), // biru/ungu
|
|
278
|
+
btn('✅ Daftar', 'reg', 'success')], // hijau
|
|
279
|
+
[url('🌐 Web', 'https://situsmu.com')],
|
|
280
|
+
[btn('❌ Tutup', 'close', 'danger', '5408846744727334338')], // merah + IKON ANIMASI
|
|
281
|
+
])));
|
|
59
282
|
```
|
|
60
283
|
|
|
61
|
-
`
|
|
284
|
+
- 🎨 Warna `style` (`primary`/`success`/`danger`) butuh aplikasi Telegram rilis ≥ Feb 2026 — versi lama tampil biasa, tidak error.
|
|
285
|
+
- ✨ `icon_custom_emoji_id` butuh **owner bot ber-Premium** atau username Fragment.
|
|
286
|
+
- Helper: `copy(text, nilai)` (salin ke clipboard), `webApp(text, link)`, `kb.confirm(yaData, tidakData)`, `kb.markup(rows)`.
|
|
287
|
+
- Kelas fluent: `new InlineKeyboard().text(...).url(...).row().text(...).build()` dan `new Keyboard().text(...).requestContact(...).resized().build()` (reply keyboard asli).
|
|
62
288
|
|
|
63
|
-
|
|
289
|
+
<a id="menu"></a>
|
|
290
|
+
### 🍽️ Menu interaktif
|
|
64
291
|
|
|
65
|
-
|
|
292
|
+
```js
|
|
293
|
+
const { Menu, MenuContainer } = require('@xbibzlibrary/telebibz');
|
|
66
294
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
295
|
+
const mc = new MenuContainer();
|
|
296
|
+
const utama = mc.create('utama'), lanjut = mc.create('lanjut');
|
|
297
|
+
|
|
298
|
+
utama.text('🔔 Notif', async (ctx) => ctx.answerCallbackQuery('dinyalakan!'))
|
|
299
|
+
.row()
|
|
300
|
+
.url('🌐 Web', 'https://x.com')
|
|
301
|
+
.submenu('Lanjut ▶', 'lanjut');
|
|
302
|
+
lanjut.back('◀️ Kembali', 'utama');
|
|
303
|
+
|
|
304
|
+
bot.use(mc); // handler tombol terdaftar otomatis
|
|
305
|
+
bot.cmd('cfg', (ctx) => ctx.reply('Menu:', { reply_markup: utama.render(ctx) }));
|
|
70
306
|
```
|
|
71
307
|
|
|
72
|
-
|
|
308
|
+
Submenu menukar keyboard di tempat lewat `editMessageReplyMarkup`; tombol usang
|
|
309
|
+
dijawab alert ramah, bukan crash.
|
|
73
310
|
|
|
74
|
-
|
|
311
|
+
<a id="wizard"></a>
|
|
312
|
+
### 🧙 Wizard — form percakapan, nol boilerplate
|
|
75
313
|
|
|
76
|
-
```
|
|
77
|
-
bot.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
314
|
+
```js
|
|
315
|
+
bot.wizard('daftar', {
|
|
316
|
+
steps: [
|
|
317
|
+
{ key: 'nama', ask: 'Siapa namamu?' },
|
|
318
|
+
{ key: 'umur', ask: 'Umur?', parse: Number,
|
|
319
|
+
validate: (n) => (n > 0 && n < 120 ? null : 'Angka saja ya:') },
|
|
320
|
+
],
|
|
321
|
+
done: async (ans, ctx) => ctx.reply(`Oke ${ans.nama} (${ans.umur})!`),
|
|
81
322
|
});
|
|
323
|
+
// user tinggal /daftar → bot bertanya sampai selesai.
|
|
324
|
+
// ketik "batal" / "cancel" kapan pun untuk berhenti. Sesi otomatis aktif.
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
`bot.wizard(id, def, bindCommand = true)` otomatis mengikat `/id` sebagai
|
|
328
|
+
pemicu; pakai `bot.wizardStart(ctx, id)` dari handler mana pun (tombol, menu, …).
|
|
329
|
+
|
|
330
|
+
#### 🆕 v3.1 — tombol pilihan + mode `edit`/`delete`
|
|
331
|
+
|
|
332
|
+
```js
|
|
333
|
+
bot.wizard('survey', {
|
|
334
|
+
mode: 'edit', // 'send' (default) | 'edit' | 'delete'
|
|
335
|
+
steps: [
|
|
336
|
+
// reply keyboard — user ketuk, tak perlu mengetik
|
|
337
|
+
{ key: 'jk', ask: 'Jenis kelamin?', buttons: ['👨 Laki-laki', '👩 Perempuan'], onlyButtons: true },
|
|
82
338
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
339
|
+
// inline keyboard (callback) — nilai boleh beda dari label
|
|
340
|
+
{ key: 'pulau', ask: 'Domisili pulau?', inline: true, onlyButtons: true,
|
|
341
|
+
buttons: [[{ text: '🌋 Jawa', value: 'jawa' }, { text: '🌴 Sumatera', value: 'sumatera' }]] },
|
|
342
|
+
|
|
343
|
+
// ketikan bebas dengan validasi (mode bisa di-override per langkah)
|
|
344
|
+
{ key: 'umur', ask: 'Umur?', parse: Number, mode: 'send',
|
|
345
|
+
validate: (n) => (n > 0 && n < 120 ? null : 'Angka saja ya:') },
|
|
346
|
+
],
|
|
347
|
+
done: async (ans, ctx) => ctx.reply(`Tersimpan: ${JSON.stringify(ans)}`),
|
|
348
|
+
});
|
|
91
349
|
```
|
|
92
350
|
|
|
93
|
-
|
|
351
|
+
| Opsi | Level | Fungsi |
|
|
352
|
+
|---|:---:|---|
|
|
353
|
+
| `buttons` | step | `['A','B']`, `[{text,value}]`, atau baris eksplisit `[['A'],['B','C']]` |
|
|
354
|
+
| `inline` | step | `true` → tombol callback (klik = nilai, tanpa mengetik) |
|
|
355
|
+
| `onlyButtons` | step | `true`/string → tolak ketikan bebas, wajib pilih tombol |
|
|
356
|
+
| `mode` | def/step | `'send'` pesan baru · `'edit'` satu pesan diedit terus · `'delete'` pesan lama dihapus dulu |
|
|
357
|
+
| `cleanup` | def | hapus pesan tanya terakhir saat selesai (default aktif pada mode `'delete'`) |
|
|
358
|
+
| `removeKeyboard` | def | singkirkan reply keyboard saat selesai (default `true` bila sempat dipakai) |
|
|
359
|
+
|
|
360
|
+
Helper programatis: `bot.wizardCancel(ctx)`, `bot.wizardEdit(ctx, teks)`,
|
|
361
|
+
`bot.wizardDelete(ctx)`, plus modul `wizard` (`cancel/editAsk/deleteAsk`).
|
|
362
|
+
Tombol usang (diklik setelah wizard pindah/selesai) dijawab alert aman — bot
|
|
363
|
+
tidak pernah crash. `parse`/`validate` juga berlaku untuk nilai tombol.
|
|
364
|
+
|
|
365
|
+
<a id="inline"></a>
|
|
366
|
+
### ❓ Mode inline
|
|
367
|
+
|
|
368
|
+
```js
|
|
369
|
+
const { iq } = require('@xbibzlibrary/telebibz');
|
|
370
|
+
|
|
371
|
+
bot.inlineQuery(/kucing/i, async (ctx) => {
|
|
372
|
+
await ctx.answerInlineQuery([
|
|
373
|
+
iq.article('1', 'Fakta kucing', { message_text: 'meong!' }),
|
|
374
|
+
iq.photo('2', 'https://x/1.jpg'),
|
|
375
|
+
], { cache_time: 0 });
|
|
376
|
+
});
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Builder hasil: `iq.article/photo/gif/video/audio/location/sticker`.
|
|
94
380
|
|
|
95
|
-
|
|
381
|
+
<a id="broadcast"></a>
|
|
382
|
+
### 📣 Broadcast (aman rate-limit)
|
|
96
383
|
|
|
97
|
-
|
|
384
|
+
```js
|
|
385
|
+
const hasil = await bot.broadcast([111, 222, 333], 'Pengumuman!', { delay: 35 });
|
|
386
|
+
// → { terkirim: 3, gagal: 0, errors: [] } (yang memblokir tercatat di errors)
|
|
387
|
+
```
|
|
98
388
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
389
|
+
`pesan` boleh string, objek payload `sendMessage`, atau fungsi
|
|
390
|
+
`(chatId) => payload` untuk personalisasi per penerima. Pacing default 35 ms
|
|
391
|
+
(≈28 pesan/detik, aman di bawah limit Telegram).
|
|
392
|
+
|
|
393
|
+
<a id="file"></a>
|
|
394
|
+
### 📎 File & media
|
|
395
|
+
|
|
396
|
+
```js
|
|
397
|
+
const { InputFile, InputMediaBuilder } = require('@xbibzlibrary/telebibz');
|
|
398
|
+
|
|
399
|
+
bot.cmd('foto', (ctx) => ctx.replyWithPhoto(new InputFile(buffer, 'x.jpg')));
|
|
400
|
+
bot.cmd('dok', (ctx) => ctx.replyWithDocument(new InputFile('/path/file.pdf')));
|
|
401
|
+
bot.cmd('album', (ctx) => ctx.replyWithMediaGroup([
|
|
402
|
+
InputMediaBuilder.photo('https://a/1.jpg'),
|
|
403
|
+
InputMediaBuilder.photo('https://a/2.jpg', { caption: 'dua' }),
|
|
404
|
+
]));
|
|
405
|
+
bot.on('message:photo', async (ctx) => {
|
|
406
|
+
const f = await ctx.getFile(); // ukuran photo terbesar, otomatis
|
|
407
|
+
await ctx.downloadFile('./foto.jpg'); // streaming ke disk
|
|
408
|
+
});
|
|
104
409
|
```
|
|
105
410
|
|
|
106
|
-
|
|
411
|
+
`InputFile` menerima Buffer / Uint8Array / path file / stream fs / async
|
|
412
|
+
iterable; upload dikirim sebagai `multipart` dengan `attach://` di mana pun
|
|
413
|
+
dalam payload (media group, thumbnail, …). `api.downloadFile(file_id, dest)`
|
|
414
|
+
juga bisa berdiri sendiri.
|
|
415
|
+
|
|
416
|
+
<a id="ratelimit"></a>
|
|
417
|
+
### 🛡️ Keandalan & rate limit
|
|
418
|
+
|
|
419
|
+
```js
|
|
420
|
+
const { autoRetry, throttler, limiter } = require('@xbibzlibrary/telebibz');
|
|
421
|
+
|
|
422
|
+
bot.api.config.use(autoRetry()); // retry 429, hormati retry_after (maks 5)
|
|
423
|
+
bot.api.config.use(throttler()); // antrean global ≤ 28 panggilan/detik
|
|
424
|
+
bot.use(limiter({ windowMs: 2000, limit: 3, onExceeded })); // anti-spam per-user
|
|
425
|
+
```
|
|
107
426
|
|
|
108
|
-
|
|
427
|
+
Long polling tahan banting secara default: konflik 409 retry tiap 5 detik
|
|
428
|
+
(atur via `launch({ conflictDelay: 5000 })`), gangguan jaringan backoff 1
|
|
429
|
+
detik, `stop()` keluar dengan bersih (`await bot.runPromise`).
|
|
109
430
|
|
|
110
|
-
|
|
431
|
+
<a id="session"></a>
|
|
432
|
+
### 🗃️ Session
|
|
111
433
|
|
|
112
|
-
```
|
|
113
|
-
|
|
434
|
+
```js
|
|
435
|
+
const { session } = require('@xbibzlibrary/telebibz');
|
|
114
436
|
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
437
|
+
const bot = new TeleBibz(token, {
|
|
438
|
+
session: {
|
|
439
|
+
initial: () => ({ hitung: 0 }),
|
|
440
|
+
getKey: (ctx) => `${ctx.from?.id}:${ctx.chat?.id}`, // default
|
|
441
|
+
storage: adapterRedisKu, // { read(k), write(k,v), delete(k) } — default: Map memori
|
|
442
|
+
},
|
|
443
|
+
});
|
|
119
444
|
|
|
120
|
-
|
|
445
|
+
bot.on(':text', (ctx) => { ctx.session.hitung++; });
|
|
121
446
|
```
|
|
122
447
|
|
|
123
|
-
|
|
448
|
+
`ctx.session` selalu ada bahkan tanpa konfigurasi apa pun.
|
|
124
449
|
|
|
125
|
-
|
|
450
|
+
<a id="error"></a>
|
|
451
|
+
### 🇮🇩 Error yang bisa dibaca manusia
|
|
126
452
|
|
|
127
|
-
|
|
453
|
+
Setiap error dilaporkan dengan saran yang bisa ditindaklanjuti:
|
|
128
454
|
|
|
129
|
-
|
|
455
|
+
```
|
|
456
|
+
✖ Telegram error (403): Forbidden: bot was blocked by the user
|
|
457
|
+
💡 saran: Bot diblokir pengguna — jangan kirim ulang, hapus dari daftar broadcast.
|
|
458
|
+
```
|
|
130
459
|
|
|
131
|
-
|
|
460
|
+
`humanize(err)` mengembalikan `{ pesan, saran, method, code }` untuk 15+ error
|
|
461
|
+
Telegram umum (token salah, chat not found, hak admin, parse error, rate
|
|
462
|
+
limit, callback basi, file kegedean, …). Override lewat
|
|
463
|
+
`new TeleBibz(token, { onError: (err, ctx) => {} })`.
|
|
132
464
|
|
|
133
|
-
|
|
134
|
-
|
|
465
|
+
<a id="webhook"></a>
|
|
466
|
+
### 🕸️ Webhook & serverless
|
|
135
467
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
.
|
|
468
|
+
```js
|
|
469
|
+
const http = require('http');
|
|
470
|
+
http.createServer((req, res) =>
|
|
471
|
+
req.url === '/tg' ? bot.webhook()(req, res) : res.end('ok')
|
|
472
|
+
).listen(8443);
|
|
140
473
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
bot.
|
|
144
|
-
await bot.start();
|
|
474
|
+
// framework apa pun (Express/Fastify/Hono): pasang handler (req, res) dari bot.webhook()
|
|
475
|
+
// — atau serverless, langsung:
|
|
476
|
+
await bot.handleUpdate(req.body); // satu update mentah → pipeline penuh
|
|
145
477
|
```
|
|
146
478
|
|
|
147
|
-
|
|
479
|
+
Jangan lupa `await bot.init()` dulu kalau tidak memakai `launch()` (untuk
|
|
480
|
+
mengambil info bot), dan pasang webhook via `bot.api.setWebhook({ url })`.
|
|
481
|
+
|
|
482
|
+
<a id="proxy"></a>
|
|
483
|
+
### 🔌 Transport proxy (VPS di balik proxy)
|
|
484
|
+
|
|
485
|
+
```js
|
|
486
|
+
const { TeleBibz, createTransport } = require('@xbibzlibrary/telebibz');
|
|
487
|
+
const bot = new TeleBibz(token, {
|
|
488
|
+
transport: createTransport(token, { proxy: 'http://user:pass@proxy:8080' }),
|
|
489
|
+
});
|
|
490
|
+
```
|
|
148
491
|
|
|
149
|
-
|
|
492
|
+
`createTransport(token, { apiRoot, proxy, timeoutMs, headers })` juga bisa
|
|
493
|
+
diarahkan ke Bot API server lokal.
|
|
150
494
|
|
|
151
|
-
|
|
152
|
-
|
|
495
|
+
<a id="transformer"></a>
|
|
496
|
+
### 🧪 Transformer (escape hatch)
|
|
153
497
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
498
|
+
```js
|
|
499
|
+
bot.api.config.use(async (prev, method, payload) => {
|
|
500
|
+
console.log('→', method); // lihat/modifikasi semua panggilan Bot API
|
|
501
|
+
return prev(method, payload);
|
|
157
502
|
});
|
|
503
|
+
|
|
504
|
+
// metode apa pun, bahkan yang belum rilis (sihir Proxy):
|
|
505
|
+
await bot.api.sendDiceCustom({ chat_id: 1, emoji: '🎲' });
|
|
158
506
|
```
|
|
159
507
|
|
|
160
|
-
|
|
508
|
+
<a id="analitik"></a>
|
|
509
|
+
## 📈 Analitik & Statistik
|
|
161
510
|
|
|
162
|
-
|
|
511
|
+
### 📊 Repo ini dalam angka
|
|
163
512
|
|
|
164
|
-
|
|
513
|
+
| Metrik | Nilai |
|
|
514
|
+
|---|---|
|
|
515
|
+
| 📦 Modul sumber | **16 file** di `lib/` |
|
|
516
|
+
| 📝 Total baris kode | **±1.700** (tanpa build step) |
|
|
517
|
+
| 🔌 Metode Bot API | **90+** — 75 shortcut bertipe + Proxy tanpa batas |
|
|
518
|
+
| ⌨️ Shortcut Context | **50+** (reply/edit/delete/admin/react…) |
|
|
519
|
+
| 🧪 Test offline | **30/30 lulus**, tanpa jaringan |
|
|
520
|
+
| 🧩 Contoh siap jalan | **7** di `examples/` |
|
|
521
|
+
| 📦 Dependency runtime | **4** — semuanya terpakai & ter-test |
|
|
165
522
|
|
|
166
|
-
|
|
167
|
-
- **Tidak ada throttling proaktif.** Permintaan keluar tidak pernah ditunda oleh library. Ketika Telegram menjawab 429, transport menunggu tepat jendela `retry_after` yang diperintahkan Telegram ("flood gate" global melindungi seluruh trafik) lalu otomatis retry — sehingga burst tetap terkirim lengkap, bukan gagal. Untuk batasan downstream Anda sendiri, `Limiter` dan `mapWithConcurrency()` mengatur laju beban kerja apa pun.
|
|
168
|
-
- **Broadcast ke 1000+ user sekaligus.** `bot.broadcast()` langsung mencoba semua chat, me-retry 429 sesuai `retry_after` dari Telegram sendiri, dan mengembalikan laporan lengkap.
|
|
169
|
-
- **Shutdown yang anggun.** `bot.stop()` lebih dulu menunggu handler yang sedang berjalan selesai (dibatasi `handlerTimeout`) dan baru kemudian menghentikan plugin manager — conversation yang aktif tidak pernah terpotong di tengah penulisan.
|
|
523
|
+
### ⬇️ Download & popularitas (live dari npm)
|
|
170
524
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
{ onProgress: (p) => console.log(`${p.delivered}/${p.total} terkirim`) },
|
|
176
|
-
);
|
|
177
|
-
console.log(`Terkirim ${report.delivered}/${report.total} dalam ${report.durationMs}ms`);
|
|
178
|
-
```
|
|
525
|
+
[](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
|
|
526
|
+
[](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
|
|
527
|
+
[](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
|
|
528
|
+
[](https://www.npmjs.com/package/@xbibzlibrary/telebibz)
|
|
179
529
|
|
|
180
|
-
|
|
530
|
+
### 📏 Peta ukuran modul (baris kode)
|
|
181
531
|
|
|
182
|
-
|
|
532
|
+
```
|
|
533
|
+
wizard.js █████████████████████████ 247 ← form + tombol + edit/delete
|
|
534
|
+
telebibz.js ███████████████████▎ 193 ← kelas utama & siklus hidup
|
|
535
|
+
context.js ███████████████████ 190 ← ctx + 50-an shortcut
|
|
536
|
+
composer.js █████████████████▍ 174 ← mesin middleware & filter
|
|
537
|
+
api.js ███████████████▍ 154 ← 75 shortcut + Proxy + transformer
|
|
538
|
+
net.js ███████████▌ 115 ← transport axios + multipart
|
|
539
|
+
menus.js █████████ 90 ← Menu/MenuContainer
|
|
540
|
+
keyboard.js ████████▎ 83 ← btn/url/kb + kelas fluent
|
|
541
|
+
ratelimit.js ██████ 61 ← autoRetry · throttler · limiter
|
|
542
|
+
runner.js ████▌ 45 ← polling tahan-409
|
|
543
|
+
file.js ████ 41 ← InputFile + InputMediaBuilder
|
|
544
|
+
logger.js ███▊ 38 ← log + banner
|
|
545
|
+
session.js ███▌ 36 ← session swappable
|
|
546
|
+
errors.js ███▌ 35 ← humanize error 🇮
|
|
547
|
+
broadcast.js ███▌ 35 ← blast aman rate-limit
|
|
548
|
+
inline-query.js██▊ 28 ← matcher + builder hasil
|
|
549
|
+
```
|
|
183
550
|
|
|
184
|
-
|
|
551
|
+
### 🗺️ Kesehatan repo
|
|
185
552
|
|
|
186
|
-
|
|
187
|
-
- **Manajemen chat** — `ctx.setChatTitle/Description/Photo`, `ctx.setChatPermissions`, `ctx.leaveChat`, `ctx.unpinAllChatMessages`, `ctx.setChatStickerSet`, `ctx.deleteChatStickerSet`
|
|
188
|
-
- **Info** — `ctx.getChatAdministrators`, `ctx.getChatMemberCount`, `ctx.getChatMember`
|
|
189
|
-
- **Invite link & join request** — `ctx.exportChatInviteLink`, `ctx.createChatInviteLink`, `ctx.editChatInviteLink`, `ctx.revokeChatInviteLink`, `ctx.approveChatJoinRequest`, `ctx.declineChatJoinRequest`
|
|
190
|
-
- **Poll, game, pembayaran** — `ctx.replyWithQuiz`, `ctx.stopPoll`, `ctx.editMessageLiveLocation`, `ctx.stopMessageLiveLocation`, `ctx.replyWithGame`, `ctx.setGameScore`, `ctx.getGameHighScores`, `ctx.replyWithInvoice`
|
|
191
|
-
- **Forum topic** — `ctx.createForumTopic`, `ctx.closeForumTopic`, `ctx.editGeneralForumTopic`, dan sembilan lainnya
|
|
192
|
-
- **Opsi launch** — `handlerTimeout` (default 90 detik, seperti Telegraf) melempar `UpdateTimeoutError` untuk update yang menggantung sementara handler tetap berjalan; `0` menonaktifkan timeout; `contextType` memasang subclass `Context` Anda sendiri; `dropPendingUpdates` di `start()`/`launch()`
|
|
193
|
-
- **Webhook reply** — opt-in `webhookReply: true` menjawab panggilan API pertama lewat respons HTTP webhook itu sendiri (ala Telegraf), dengan `getMe` malas yang tidak pernah mengklaim slot
|
|
194
|
-
- **Alias handler drop-in** — `bot.action(...)` mendaftarkan handler callback query sama seperti `bot.callback(...)`, sehingga handler yang ditulis untuk Telegraf bisa dipindahkan tanpa perubahan
|
|
553
|
+
<div align="center">
|
|
195
554
|
|
|
196
|
-
|
|
555
|
+
[](https://github.com/XbibzOfficial777/telebibz)
|
|
197
556
|
|
|
198
|
-
|
|
557
|
+
</div>
|
|
199
558
|
|
|
200
|
-
|
|
559
|
+
<details>
|
|
560
|
+
<summary>📅 Riwayat bintang (klik untuk buka)</summary>
|
|
201
561
|
|
|
202
|
-
|
|
562
|
+

|
|
203
563
|
|
|
204
|
-
|
|
564
|
+
</details>
|
|
205
565
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
↳ Text: /start
|
|
209
|
-
[ => ] Callback From 123456789 John Doe 29/08/2026 15:04:07
|
|
210
|
-
↳ Data: menu:open
|
|
211
|
-
```
|
|
566
|
+
<a id="contoh"></a>
|
|
567
|
+
## 🧩 Contoh Siap Jalan (`examples/`)
|
|
212
568
|
|
|
213
|
-
|
|
569
|
+
| File | Isi |
|
|
570
|
+
|---|---|
|
|
571
|
+
| `01-quickstart.js` | bot jalan dalam 6 baris |
|
|
572
|
+
| `02-menu-tombol.js` | keyboard berwarna + ikon animasi |
|
|
573
|
+
| `03-wizard.js` | form pendaftaran + **tombol + mode edit** |
|
|
574
|
+
| `04-broadcast.js` | blast admin |
|
|
575
|
+
| `05-kirim-file.js` | foto & dokumen dari buffer |
|
|
576
|
+
| `06-menu.js` | menu interaktif + submenu |
|
|
577
|
+
| `07-inline-query.js` | mode inline dengan builder hasil |
|
|
214
578
|
|
|
215
|
-
|
|
579
|
+
Jalankan dengan `BOT_TOKEN=123:abc node examples/01-quickstart.js`.
|
|
216
580
|
|
|
217
|
-
|
|
581
|
+
<a id="test"></a>
|
|
582
|
+
## 🔬 Test & Bukti Live
|
|
218
583
|
|
|
219
584
|
```bash
|
|
220
|
-
|
|
221
|
-
npx telebibz doctor
|
|
222
|
-
npx telebibz build
|
|
223
|
-
npx telebibz test
|
|
585
|
+
npm test # 30 kasus, TANPA jaringan (transport disuntik)
|
|
224
586
|
```
|
|
225
587
|
|
|
226
|
-
|
|
588
|
+
Tervalidasi **30/30 offline + 10 live** pada bot produksi `@xbibzrat_bot`:
|
|
589
|
+
getMe · keyboard berwarna & ikon animasi asli · upload multipart
|
|
590
|
+
(photo+document) · edit keyboard · broadcast · deleteMessage · polling 409
|
|
591
|
+
retry · wizard tombol & edit/delete.
|
|
227
592
|
|
|
228
|
-
|
|
229
|
-
import { printTeleBibzBanner, printTerminalBranding } from "@xbibzlibrary/telebibz";
|
|
593
|
+
Log debug: `DEBUG=telebibz:net,telebibz:ratelimit node botkamu.js`.
|
|
230
594
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
```
|
|
595
|
+
<a id="struktur"></a>
|
|
596
|
+
## 📂 Struktur Repo (16 file inti)
|
|
234
597
|
|
|
235
|
-
|
|
598
|
+
| File | Peran |
|
|
599
|
+
|---|---|
|
|
600
|
+
| `lib/net.js` | transport axios keep-alive + multipart `attach://` |
|
|
601
|
+
| `lib/api.js` | metode Bot API + Proxy segala metode + transformer |
|
|
602
|
+
| `lib/composer.js` | middleware, filter `on('message:photo')`, `errorBoundary` |
|
|
603
|
+
| `lib/context.js` | objek ctx + 50-an pintasan reply/edit/delete/callback |
|
|
604
|
+
| `lib/session.js` | sesi per user:chat (storage swappable) |
|
|
605
|
+
| `lib/runner.js` | long polling: retry 409, backoff jaringan, drop pending |
|
|
606
|
+
| `lib/wizard.js` | form percakapan + tombol pilihan + mode edit/delete |
|
|
607
|
+
| `lib/menus.js` | menu interaktif `Menu`/`MenuContainer` |
|
|
608
|
+
| `lib/keyboard.js` | builder tombol + kelas fluent `InlineKeyboard`/`Keyboard` |
|
|
609
|
+
| `lib/ratelimit.js` | `autoRetry` 429 · antre `throttler` · `limiter` per-user |
|
|
610
|
+
| `lib/broadcast.js` | blast aman rate-limit |
|
|
611
|
+
| `lib/file.js` | `File`/`InputFile` (Buffer/path/stream) + `InputMediaBuilder` |
|
|
612
|
+
| `lib/inline-query.js` | matcher query + builder hasil inline |
|
|
613
|
+
| `lib/errors.js` | humanisasi error + saran |
|
|
614
|
+
| `lib/logger.js` | log berbingkai + banner boot |
|
|
615
|
+
| `index.js` / `index.d.ts` | pintu ekspor + tipe TypeScript |
|
|
236
616
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
npm run test:types
|
|
240
|
-
npm run lint
|
|
241
|
-
npm test
|
|
242
|
-
npm run build
|
|
243
|
-
npm run security
|
|
244
|
-
npm run release:check
|
|
245
|
-
```
|
|
617
|
+
<a id="changelog"></a>
|
|
618
|
+
## 🕐 Changelog
|
|
246
619
|
|
|
247
|
-
|
|
620
|
+
- **3.1.0** — wizard: tombol pilihan (reply/inline), mode `edit`/`delete`, cleanup otomatis, helper programatis · test 24 → 30
|
|
621
|
+
- **3.0.0** — parity grammY production-grade: axios keep-alive, transformer, menu, inline query, limiter
|
|
622
|
+
- **2.0.0** — engine ditulis ulang dari nol, transport multipart, webhook Node murni
|
|
623
|
+
- **1.0.0** — recode arsitektur grammY
|
|
248
624
|
|
|
249
|
-
|
|
625
|
+
> Detail lengkap di [`CHANGELOG.md`](CHANGELOG.md). Studi arsitektur mendalam: [`ANALISIS-telebibz.md`](ANALISIS-telebibz.md).
|
|
250
626
|
|
|
251
|
-
|
|
627
|
+
<a id="lisensi"></a>
|
|
628
|
+
## 📄 Lisensi
|
|
252
629
|
|
|
253
|
-
|
|
630
|
+
**MIT** © Xbibz Official — arsitektur terinspirasi [grammY](https://grammy.dev) (MIT, lihat [`NOTICE.md`](NOTICE.md)).
|
|
254
631
|
|
|
255
|
-
|
|
632
|
+
---
|
|
256
633
|
|
|
257
|
-
|
|
258
|
-
|---|---|
|
|
259
|
-
| Bot & lifecycle | `Bot` dengan `on`, `onText`, `onRegex`, `command`, `hears`, `callback`, `action`, `catch`, `use`, `usePlugin`, `useWizard`, `handleUpdate`, `handleUpdates`, `start`/`launch`, `stop`, `restart`, `init`, `health`, `broadcast`, `getMe`, `setCommands`, `deleteCommands`, `downloadFile`; `UpdateTimeoutError` |
|
|
260
|
-
| Context | `Context`, `ContextOptions`, opsi launch `contextType`; ~80 shortcut di `ctx` untuk balasan, aksi admin, manajemen chat, invite link, poll, game, pembayaran, dan forum topic |
|
|
261
|
-
| Telegram API | `ApiClient` dengan `call()`, `request()`, `raw()`, `downloadFile()`, dan `methods` (seluruh generated Bot API method); `FetchTransport` dengan retry 429/5xx otomatis, flood gate global, upload multipart (Blob/byte/path/stream), dan unduhan file |
|
|
262
|
-
| Error | `TelegramError` dengan taksonomi `kind` (`retryable`, `rate-limit`, `authentication`, `validation`, `network`, `server`, `unknown`) dan `retryAfter`, plus `TelegramRateLimitError`, `TelegramAuthError`, `TelegramValidationError`, `TelegramNetworkError` |
|
|
263
|
-
| Router & middleware | `Router`, `compose`, 24 filter update (`message:photo`, `callback_query:data`, …), `matchMode` (`first`/`all`) |
|
|
264
|
-
| Keyboard | `InlineKeyboard`, `ReplyKeyboard`, `removeKeyboard()`, `forceReply()` |
|
|
265
|
-
| Storage | `MemoryStorage` (TTL, serialisasi per-key), `JsonFileStorage`, `RedisStorage`, `SqlStorage`, `MongoStorage`, beserta driver interface kecil yang menjadi dasarnya |
|
|
266
|
-
| Cache & limiting | `MemoryCache`, `TokenBucketLimiter`, `Limiter`, `mapWithConcurrency()` |
|
|
267
|
-
| Queue & scheduler | `TaskQueue` (prioritas, retry, backoff, delay, cancel), `Scheduler` (interval, one-shot, cron), `parseCronExpression()`, `nextCronOccurrence()` |
|
|
268
|
-
| State & dialog | `Wizard`, `ConversationManager`, `ConversationFlow`, `Form` dengan `validators`, `Menu` berbasis permission, `MenuController`, `paginate()` |
|
|
269
|
-
| Webhook | `createWebhookHandler()` (Request/Response Web), `webhookCallback()` untuk Express/Koa/Fastify/Node `http`, `runWithWebhookReply()`, `claimWebhookReply()` |
|
|
270
|
-
| Web App & pembayaran | `parseWebAppInitData()`, `validateWebAppInitData()`, `PaymentsClient`, `TelegramTypes` (deklarasi Telegram yang dibundel) |
|
|
271
|
-
| Observability | `Logger` (level, redaction, format JSON), `EventBus` dengan event map `update:*`, `bot:*`, `broadcast:*`, `redact()` |
|
|
272
|
-
| Terminal | `printTeleBibzBanner()`, `printTerminalBranding()`, `buildTerminalBranding()`, `runStartupSequence()`, `startTeleBibzBanner()`, `paintRainbow()`, `printStatusLine()` |
|
|
273
|
-
| Utilitas teks | `splitMessage()`, `splitCaption()`, `escapeMarkdownV2()`, `escapeHtml()`, `md`, `html`, `template()` |
|
|
274
|
-
| Utilitas file | `validateUpload()`, `assertValidUpload()`, `UploadValidationError` (aturan ukuran, MIME, ekstensi) |
|
|
275
|
-
| Testing (`@xbibzlibrary/telebibz/testing`) | `MockTransport` (dengan unduhan mock), `createTestBot()`, `createMockUpdate()`, `createMockCallbackUpdate()`, `createMockContext()` |
|
|
276
|
-
| CLI (`telebibz …`) | `init`, `doctor`, `build`, `test`, `start`, `webhook`, `generate` |
|
|
277
|
-
|
|
278
|
-
## API target dan batasan
|
|
279
|
-
|
|
280
|
-
Daftar method dihasilkan dari dokumentasi Telegram Bot API saat skema diperbarui. Akses runtime tersedia untuk method resmi yang terdeteksi, sedangkan inferensi parameter/result khusus dipusatkan pada core method map. Full declaration Telegram untuk object, union, enum, dan method tersedia melalui `TelegramTypes`. Lihat [FEATURE_MATRIX.md](FEATURE_MATRIX.md) untuk status implementasi dan `docs/API.id.md` untuk referensi API lengkap.
|
|
281
|
-
|
|
282
|
-
## Otomatisasi release
|
|
283
|
-
|
|
284
|
-
Repository GitHub menyediakan CI dan workflow auto-publish. Setiap push ke `main` menjalankan quality gates lalu menurunkan versi berikutnya dari Conventional Commits yang didorong: commit `feat:` dan breaking change menaikkan minor selama package belum 1.0 (footer `BREAKING-CHANGE` atau subjek `type!:` menaikkan major mulai 1.0.0), sisanya menaikkan patch. Versi yang sudah dideklarasikan di `package.json` lebih tinggi dari npm diterbitkan persis apa adanya, dan workflow tidak pernah menerbitkan versi yang kurang dari atau sama dengan rilis npm terbaru. Workflow membuat commit versi, tag, menerbitkan ke npm (dengan provenance dinonaktifkan lewat `--provenance=false`), lalu membuat GitHub Release. Commit yang memuat `[skip release]` tidak memicu penerbitan. Konfigurasikan secret `NPM_TOKEN` pada GitHub Actions sebelum mengandalkan publish otomatis. Lihat [RELEASE_AUTOMATION.md](RELEASE_AUTOMATION.md) dan panduan [GitHub Packages](docs/GITHUB_PACKAGES.id.md).
|
|
285
|
-
|
|
286
|
-
## Policy project dan kontribusi
|
|
287
|
-
|
|
288
|
-
| Dokumen | Tujuan |
|
|
289
|
-
|---|---|
|
|
290
|
-
| [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) | Perilaku komunitas, penegakan, pelaporan, dan banding. |
|
|
291
|
-
| [CONTRIBUTING.md](CONTRIBUTING.md) | Setup lokal, branch/commit, test, review, dan release workflow. |
|
|
292
|
-
| [CONTRIBUTION_RULES.md](CONTRIBUTION_RULES.md) | Aturan API, compatibility, testing, dependency, security, dan release. |
|
|
293
|
-
| [GOVERNANCE.md](GOVERNANCE.md) | Peran, pengambilan keputusan, triage, perlindungan repository, dan perubahan aturan. |
|
|
294
|
-
| [SECURITY.md](SECURITY.md) | Pelaporan vulnerability privat, batas security, dan rotasi credential. |
|
|
295
|
-
| [SUPPORT.md](SUPPORT.md) | Channel support, aturan laporan aman, dan ekspektasi response. |
|
|
296
|
-
| [RELEASE_AUTOMATION.md](RELEASE_AUTOMATION.md) | Automation GitHub-to-npm dan setup `NPM_TOKEN`. |
|
|
297
|
-
| [RELEASE_POLICY.md](RELEASE_POLICY.md) | Kontrol immutable release dan hardening. |
|
|
298
|
-
| [NOTICE.md](NOTICE.md) | Atribusi declaration pihak ketiga. |
|
|
634
|
+
<div align="center">
|
|
299
635
|
|
|
300
|
-
|
|
636
|
+
**Dibuat dengan ❤️ oleh //—Xbibz Official—//**
|
|
301
637
|
|
|
302
|
-
|
|
638
|
+
Kalau telebibz membantumu, bintang ⭐ repo ini sangat berarti.
|
|
303
639
|
|
|
304
|
-
|
|
640
|
+
[](https://github.com/XbibzOfficial777/telebibz)
|
|
305
641
|
|
|
306
|
-
|
|
642
|
+
</div>
|