@xbibzlibrary/telebibz 0.4.5 → 3.0.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.
Files changed (276) hide show
  1. package/CHANGELOG.md +35 -138
  2. package/LICENSE +1 -1
  3. package/NOTICE.md +9 -4
  4. package/README.md +173 -256
  5. package/examples/01-quickstart.js +13 -0
  6. package/examples/02-menu-tombol.js +22 -0
  7. package/examples/03-wizard.js +29 -0
  8. package/examples/04-broadcast.js +25 -0
  9. package/examples/05-kirim-file.js +19 -0
  10. package/examples/06-menu.js +35 -0
  11. package/examples/07-inline-query.js +18 -0
  12. package/index.d.ts +81 -0
  13. package/index.js +42 -0
  14. package/lib/api.js +154 -0
  15. package/lib/broadcast.js +35 -0
  16. package/lib/composer.js +174 -0
  17. package/lib/context.js +190 -0
  18. package/lib/errors.js +35 -0
  19. package/lib/file.js +41 -0
  20. package/lib/inline-query.js +28 -0
  21. package/lib/keyboard.js +83 -0
  22. package/lib/logger.js +38 -0
  23. package/lib/menus.js +90 -0
  24. package/lib/net.js +115 -0
  25. package/lib/ratelimit.js +61 -0
  26. package/lib/runner.js +45 -0
  27. package/lib/session.js +36 -0
  28. package/lib/telebibz.js +190 -0
  29. package/lib/wizard.js +81 -0
  30. package/package.json +35 -97
  31. package/test/all.test.js +334 -0
  32. package/CODE_OF_CONDUCT.md +0 -37
  33. package/CONTRIBUTING.md +0 -59
  34. package/CONTRIBUTION_RULES.md +0 -41
  35. package/GOVERNANCE.md +0 -47
  36. package/README.id.md +0 -306
  37. package/README.zh-CN.md +0 -306
  38. package/RELEASE_AUTOMATION.md +0 -78
  39. package/RELEASE_POLICY.md +0 -32
  40. package/SECURITY.md +0 -47
  41. package/SHOWCASE.md +0 -29
  42. package/SUPPORT.md +0 -30
  43. package/assets/readme-preview.html +0 -75
  44. package/assets/telebibz-logo.png +0 -0
  45. package/assets/telebibz-readme-preview.png +0 -0
  46. package/bin/telebibz.mjs +0 -3
  47. package/dist/generated/api.d.ts +0 -13
  48. package/dist/generated/api.d.ts.map +0 -1
  49. package/dist/generated/api.js +0 -192
  50. package/dist/generated/api.js.map +0 -1
  51. package/dist/src/api/client.d.ts +0 -62
  52. package/dist/src/api/client.d.ts.map +0 -1
  53. package/dist/src/api/client.js +0 -104
  54. package/dist/src/api/client.js.map +0 -1
  55. package/dist/src/api/errors.d.ts +0 -45
  56. package/dist/src/api/errors.d.ts.map +0 -1
  57. package/dist/src/api/errors.js +0 -65
  58. package/dist/src/api/errors.js.map +0 -1
  59. package/dist/src/api/index.d.ts +0 -6
  60. package/dist/src/api/index.d.ts.map +0 -1
  61. package/dist/src/api/index.js +0 -6
  62. package/dist/src/api/index.js.map +0 -1
  63. package/dist/src/api/telegram-types/LICENSE +0 -21
  64. package/dist/src/api/telegram-types/api.d.ts +0 -22
  65. package/dist/src/api/telegram-types/checklist.d.ts +0 -72
  66. package/dist/src/api/telegram-types/inline.d.ts +0 -692
  67. package/dist/src/api/telegram-types/langs.d.ts +0 -193
  68. package/dist/src/api/telegram-types/manage.d.ts +0 -1144
  69. package/dist/src/api/telegram-types/markup.d.ts +0 -268
  70. package/dist/src/api/telegram-types/message.d.ts +0 -1537
  71. package/dist/src/api/telegram-types/methods.d.ts +0 -2870
  72. package/dist/src/api/telegram-types/mod.d.ts +0 -14
  73. package/dist/src/api/telegram-types/passport.d.ts +0 -163
  74. package/dist/src/api/telegram-types/payment.d.ts +0 -570
  75. package/dist/src/api/telegram-types/rich.d.ts +0 -1010
  76. package/dist/src/api/telegram-types/settings.d.ts +0 -120
  77. package/dist/src/api/telegram-types/story.d.ts +0 -89
  78. package/dist/src/api/telegram-types/update.d.ts +0 -84
  79. package/dist/src/api/telegram.d.ts +0 -7
  80. package/dist/src/api/telegram.d.ts.map +0 -1
  81. package/dist/src/api/telegram.js +0 -2
  82. package/dist/src/api/telegram.js.map +0 -1
  83. package/dist/src/api/transport.d.ts +0 -68
  84. package/dist/src/api/transport.d.ts.map +0 -1
  85. package/dist/src/api/transport.js +0 -264
  86. package/dist/src/api/transport.js.map +0 -1
  87. package/dist/src/api/types.d.ts +0 -466
  88. package/dist/src/api/types.d.ts.map +0 -1
  89. package/dist/src/api/types.js +0 -2
  90. package/dist/src/api/types.js.map +0 -1
  91. package/dist/src/branding/terminal.d.ts +0 -77
  92. package/dist/src/branding/terminal.d.ts.map +0 -1
  93. package/dist/src/branding/terminal.js +0 -328
  94. package/dist/src/branding/terminal.js.map +0 -1
  95. package/dist/src/broadcast/broadcast.d.ts +0 -50
  96. package/dist/src/broadcast/broadcast.d.ts.map +0 -1
  97. package/dist/src/broadcast/broadcast.js +0 -56
  98. package/dist/src/broadcast/broadcast.js.map +0 -1
  99. package/dist/src/cache/cache.d.ts +0 -34
  100. package/dist/src/cache/cache.d.ts.map +0 -1
  101. package/dist/src/cache/cache.js +0 -41
  102. package/dist/src/cache/cache.js.map +0 -1
  103. package/dist/src/cli.d.ts +0 -2
  104. package/dist/src/cli.d.ts.map +0 -1
  105. package/dist/src/cli.js +0 -84
  106. package/dist/src/cli.js.map +0 -1
  107. package/dist/src/context/context.d.ts +0 -124
  108. package/dist/src/context/context.d.ts.map +0 -1
  109. package/dist/src/context/context.js +0 -302
  110. package/dist/src/context/context.js.map +0 -1
  111. package/dist/src/core/bot.d.ts +0 -204
  112. package/dist/src/core/bot.d.ts.map +0 -1
  113. package/dist/src/core/bot.js +0 -506
  114. package/dist/src/core/bot.js.map +0 -1
  115. package/dist/src/core/events.d.ts +0 -75
  116. package/dist/src/core/events.d.ts.map +0 -1
  117. package/dist/src/core/events.js +0 -35
  118. package/dist/src/core/events.js.map +0 -1
  119. package/dist/src/core/webhook-reply.d.ts +0 -34
  120. package/dist/src/core/webhook-reply.d.ts.map +0 -1
  121. package/dist/src/core/webhook-reply.js +0 -37
  122. package/dist/src/core/webhook-reply.js.map +0 -1
  123. package/dist/src/index.d.ts +0 -24
  124. package/dist/src/index.d.ts.map +0 -1
  125. package/dist/src/index.js +0 -24
  126. package/dist/src/index.js.map +0 -1
  127. package/dist/src/keyboard/index.d.ts +0 -46
  128. package/dist/src/keyboard/index.d.ts.map +0 -1
  129. package/dist/src/keyboard/index.js +0 -55
  130. package/dist/src/keyboard/index.js.map +0 -1
  131. package/dist/src/middleware/compose.d.ts +0 -5
  132. package/dist/src/middleware/compose.d.ts.map +0 -1
  133. package/dist/src/middleware/compose.js +0 -17
  134. package/dist/src/middleware/compose.js.map +0 -1
  135. package/dist/src/observability/logger.d.ts +0 -78
  136. package/dist/src/observability/logger.d.ts.map +0 -1
  137. package/dist/src/observability/logger.js +0 -285
  138. package/dist/src/observability/logger.js.map +0 -1
  139. package/dist/src/plugins/plugin.d.ts +0 -38
  140. package/dist/src/plugins/plugin.d.ts.map +0 -1
  141. package/dist/src/plugins/plugin.js +0 -59
  142. package/dist/src/plugins/plugin.js.map +0 -1
  143. package/dist/src/queue/queue.d.ts +0 -77
  144. package/dist/src/queue/queue.d.ts.map +0 -1
  145. package/dist/src/queue/queue.js +0 -213
  146. package/dist/src/queue/queue.js.map +0 -1
  147. package/dist/src/router/router.d.ts +0 -61
  148. package/dist/src/router/router.d.ts.map +0 -1
  149. package/dist/src/router/router.js +0 -183
  150. package/dist/src/router/router.js.map +0 -1
  151. package/dist/src/state/conversation.d.ts +0 -56
  152. package/dist/src/state/conversation.d.ts.map +0 -1
  153. package/dist/src/state/conversation.js +0 -133
  154. package/dist/src/state/conversation.js.map +0 -1
  155. package/dist/src/state/forms.d.ts +0 -34
  156. package/dist/src/state/forms.d.ts.map +0 -1
  157. package/dist/src/state/forms.js +0 -44
  158. package/dist/src/state/forms.js.map +0 -1
  159. package/dist/src/state/menu.d.ts +0 -78
  160. package/dist/src/state/menu.d.ts.map +0 -1
  161. package/dist/src/state/menu.js +0 -127
  162. package/dist/src/state/menu.js.map +0 -1
  163. package/dist/src/storage/storage.d.ts +0 -146
  164. package/dist/src/storage/storage.d.ts.map +0 -1
  165. package/dist/src/storage/storage.js +0 -195
  166. package/dist/src/storage/storage.js.map +0 -1
  167. package/dist/src/telegram-features.d.ts +0 -33
  168. package/dist/src/telegram-features.d.ts.map +0 -1
  169. package/dist/src/telegram-features.js +0 -71
  170. package/dist/src/telegram-features.js.map +0 -1
  171. package/dist/src/testing.d.ts +0 -24
  172. package/dist/src/testing.d.ts.map +0 -1
  173. package/dist/src/testing.js +0 -38
  174. package/dist/src/testing.js.map +0 -1
  175. package/dist/src/utils/concurrency.d.ts +0 -25
  176. package/dist/src/utils/concurrency.d.ts.map +0 -1
  177. package/dist/src/utils/concurrency.js +0 -52
  178. package/dist/src/utils/concurrency.js.map +0 -1
  179. package/dist/src/utils/files.d.ts +0 -45
  180. package/dist/src/utils/files.d.ts.map +0 -1
  181. package/dist/src/utils/files.js +0 -53
  182. package/dist/src/utils/files.js.map +0 -1
  183. package/dist/src/utils/text.d.ts +0 -39
  184. package/dist/src/utils/text.d.ts.map +0 -1
  185. package/dist/src/utils/text.js +0 -56
  186. package/dist/src/utils/text.js.map +0 -1
  187. package/dist/src/webhook/handler.d.ts +0 -19
  188. package/dist/src/webhook/handler.d.ts.map +0 -1
  189. package/dist/src/webhook/handler.js +0 -141
  190. package/dist/src/webhook/handler.js.map +0 -1
  191. package/dist-cjs/generated/api.js +0 -194
  192. package/dist-cjs/package.json +0 -3
  193. package/dist-cjs/src/api/client.js +0 -107
  194. package/dist-cjs/src/api/errors.js +0 -74
  195. package/dist-cjs/src/api/index.js +0 -21
  196. package/dist-cjs/src/api/telegram-types/LICENSE +0 -21
  197. package/dist-cjs/src/api/telegram-types/api.d.ts +0 -22
  198. package/dist-cjs/src/api/telegram-types/checklist.d.ts +0 -72
  199. package/dist-cjs/src/api/telegram-types/inline.d.ts +0 -692
  200. package/dist-cjs/src/api/telegram-types/langs.d.ts +0 -193
  201. package/dist-cjs/src/api/telegram-types/manage.d.ts +0 -1144
  202. package/dist-cjs/src/api/telegram-types/markup.d.ts +0 -268
  203. package/dist-cjs/src/api/telegram-types/message.d.ts +0 -1537
  204. package/dist-cjs/src/api/telegram-types/methods.d.ts +0 -2870
  205. package/dist-cjs/src/api/telegram-types/mod.d.ts +0 -14
  206. package/dist-cjs/src/api/telegram-types/passport.d.ts +0 -163
  207. package/dist-cjs/src/api/telegram-types/payment.d.ts +0 -570
  208. package/dist-cjs/src/api/telegram-types/rich.d.ts +0 -1010
  209. package/dist-cjs/src/api/telegram-types/settings.d.ts +0 -120
  210. package/dist-cjs/src/api/telegram-types/story.d.ts +0 -89
  211. package/dist-cjs/src/api/telegram-types/update.d.ts +0 -84
  212. package/dist-cjs/src/api/telegram.js +0 -2
  213. package/dist-cjs/src/api/transport.js +0 -267
  214. package/dist-cjs/src/api/types.js +0 -2
  215. package/dist-cjs/src/branding/terminal.js +0 -338
  216. package/dist-cjs/src/broadcast/broadcast.js +0 -58
  217. package/dist-cjs/src/cache/cache.js +0 -45
  218. package/dist-cjs/src/cli.js +0 -86
  219. package/dist-cjs/src/context/context.js +0 -305
  220. package/dist-cjs/src/core/bot.js +0 -510
  221. package/dist-cjs/src/core/events.js +0 -38
  222. package/dist-cjs/src/core/webhook-reply.js +0 -42
  223. package/dist-cjs/src/index.js +0 -47
  224. package/dist-cjs/src/keyboard/index.js +0 -61
  225. package/dist-cjs/src/middleware/compose.js +0 -20
  226. package/dist-cjs/src/observability/logger.js +0 -293
  227. package/dist-cjs/src/plugins/plugin.js +0 -63
  228. package/dist-cjs/src/queue/queue.js +0 -219
  229. package/dist-cjs/src/router/router.js +0 -186
  230. package/dist-cjs/src/state/conversation.js +0 -139
  231. package/dist-cjs/src/state/forms.js +0 -47
  232. package/dist-cjs/src/state/menu.js +0 -133
  233. package/dist-cjs/src/storage/storage.js +0 -202
  234. package/dist-cjs/src/telegram-features.js +0 -76
  235. package/dist-cjs/src/testing.js +0 -45
  236. package/dist-cjs/src/utils/concurrency.js +0 -57
  237. package/dist-cjs/src/utils/files.js +0 -58
  238. package/dist-cjs/src/utils/text.js +0 -63
  239. package/dist-cjs/src/webhook/handler.js +0 -144
  240. package/docs/API.id.md +0 -1935
  241. package/docs/API.md +0 -1969
  242. package/docs/API.zh-CN.md +0 -1929
  243. package/docs/COOKBOOK.id.md +0 -321
  244. package/docs/COOKBOOK.md +0 -321
  245. package/docs/COOKBOOK.zh-CN.md +0 -321
  246. package/docs/ERRORS.id.md +0 -194
  247. package/docs/ERRORS.md +0 -194
  248. package/docs/ERRORS.zh-CN.md +0 -194
  249. package/docs/FILES.id.md +0 -243
  250. package/docs/FILES.md +0 -243
  251. package/docs/FILES.zh-CN.md +0 -243
  252. package/docs/GETTING_STARTED.id.md +0 -89
  253. package/docs/GETTING_STARTED.md +0 -89
  254. package/docs/GETTING_STARTED.zh-CN.md +0 -89
  255. package/docs/GITHUB_PACKAGES.id.md +0 -82
  256. package/docs/GITHUB_PACKAGES.md +0 -82
  257. package/docs/GITHUB_PACKAGES.zh-CN.md +0 -82
  258. package/docs/MIGRATION_TELEGRAF.id.md +0 -147
  259. package/docs/MIGRATION_TELEGRAF.md +0 -154
  260. package/docs/MIGRATION_TELEGRAF.zh-CN.md +0 -147
  261. package/docs/README.md +0 -67
  262. package/docs/STORAGE.id.md +0 -105
  263. package/docs/STORAGE.md +0 -105
  264. package/docs/STORAGE.zh-CN.md +0 -105
  265. package/docs/TESTING.id.md +0 -203
  266. package/docs/TESTING.md +0 -203
  267. package/docs/TESTING.zh-CN.md +0 -203
  268. package/docs/WEBHOOK.id.md +0 -212
  269. package/docs/WEBHOOK.md +0 -215
  270. package/docs/WEBHOOK.zh-CN.md +0 -212
  271. package/examples/README.md +0 -37
  272. package/examples/files.ts +0 -35
  273. package/examples/minimal.ts +0 -12
  274. package/examples/tsconfig.json +0 -9
  275. package/examples/webhook.ts +0 -42
  276. package/examples/wizard-registration.ts +0 -42
@@ -1,212 +0,0 @@
1
- # Webhook (Bahasa Indonesia)
2
-
3
- Cara melayani update lewat webhook — untuk platform tanpa long-polling (serverless, container), atau saat butuh endpoint terbuka HTTPS.
4
-
5
- ## Daftar isi
6
-
7
- 1. [Polling vs webhook](#1-polling-vs-webhook)
8
- 2. [Handler: `createWebhookHandler()`](#2-handler-createwebhookhandler)
9
- 3. [Framework populer](#3-framework-populer)
10
- 4. [Mendaftarkan URL ke Telegram](#4-mendaftarkan-url-ke-telegram)
11
- 5. [Secret token](#5-secret-token)
12
- 6. [Mode `webhookReply`](#6-mode-webhookreply)
13
- 7. [Local development dengan tunnel](#7-local-development-dengan-tunnel)
14
- 8. [Checklist produksi](#8-checklist-produksi)
15
- 9. [Troubleshooting](#9-troubleshooting)
16
-
17
- ## 1. Polling vs webhook
18
-
19
- | | Polling (`bot.start()`) | Webhook |
20
- |---|---|---|
21
- | Menghubungi Telegram | Ya (long-polling) | Tidak — Telegram yang menghubungi Anda |
22
- | Butuh domain + HTTPS publik | Tidak | Ya |
23
- | Cocok untuk | Skrip lokal, development, VPS | Serverless (Lambda/Workers/Cloud Functions), container, k8s |
24
- | Konkurensi | Pipeline per-update yang sama | Pipeline per-update yang sama |
25
- | Menerima `POST /<path>` Anda sendiri | — | Ya — handler mengembalikan `Response`, routing tetap milik Anda |
26
-
27
- Hanya satu yang aktif: Telegram mengirim update ke webhook terdaftar dan mengabaikan `getUpdates` selama webhook aktif.
28
-
29
- ## 2. Handler: `createWebhookHandler()`
30
-
31
- Handler menerima **Web-standard `Request`** dan mengembalikan **`Response`** — berjalan di Node, Bun, Deno, dan edge runtime:
32
-
33
- ```ts
34
- import { createWebhookHandler } from "@xbibzlibrary/telebibz";
35
-
36
- const handleUpdate = createWebhookHandler(bot, {
37
- secretToken: process.env.TELEGRAM_WEBHOOK_SECRET, // verifikasi X-Telegram-Bot-Api-Secret-Token
38
- webhookReply: true, // jawab API via body respons (opsional)
39
- });
40
-
41
- export default {
42
- async fetch(request: Request): Promise<Response> {
43
- if (request.method === "POST" && new URL(request.url).pathname === "/telegram") {
44
- return handleUpdate(request);
45
- }
46
- return new Response("Not Found", { status: 404 });
47
- },
48
- };
49
- ```
50
-
51
- - Body > 1 MB → `413 Payload Too Large` (atur `maxBodyBytes`).
52
- - Secret salah → `401 Unauthorized`.
53
- - Method non-POST → `405 Method Not Allowed`.
54
- - Update diproses via pipeline normal — error handler, session, conversation, semuanya bekerja.
55
-
56
- Untuk server Node ala Express (objek req/res, bukan `Request`), gunakan `webhookCallback()` — lihat [Framework populer](#3-framework-populer).
57
-
58
- ## 3. Framework populer
59
-
60
- ### Express
61
-
62
- ```ts
63
- import express from "express";
64
- import { webhookCallback } from "@xbibzlibrary/telebibz";
65
-
66
- const app = express();
67
- app.use(express.json({ limit: "1mb" }));
68
- app.post("/telegram", webhookCallback(bot, "express", { secretToken: process.env.TELEGRAM_WEBHOOK_SECRET }));
69
- app.listen(3000);
70
- ```
71
-
72
- ### Node `http`
73
-
74
- ```ts
75
- import http from "node:http";
76
- import { webhookCallback } from "@xbibzlibrary/telebibz";
77
-
78
- const callback = webhookCallback(bot, "http", { secretToken: process.env.TELEGRAM_WEBHOOK_SECRET });
79
- http
80
- .createServer(async (req, res) => {
81
- if (req.method === "POST" && req.url === "/telegram") return callback(req, res);
82
- res.writeHead(404).end();
83
- })
84
- .listen(3000);
85
- ```
86
-
87
- ### Fastify
88
-
89
- ```ts
90
- import Fastify from "fastify";
91
- import { webhookCallback } from "@xbibzlibrary/telebibz";
92
-
93
- const fastify = Fastify({ bodyLimit: 1_048_576 });
94
- fastify.post("/telegram", (req, reply) => webhookCallback(bot, "fastify", { secretToken: process.env.TELEGRAM_WEBHOOK_SECRET })(req, reply));
95
- await fastify.listen({ port: 3000 });
96
- ```
97
-
98
- ### Koa (dengan `koa-bodyparser` agar `ctx.request.body` terisi)
99
-
100
- ```ts
101
- import Koa from "koa";
102
- import bodyParser from "koa-bodyparser";
103
- import { webhookCallback } from "@xbibzlibrary/telebibz";
104
-
105
- const app = new Koa();
106
- app.use(bodyParser());
107
- app.use(async (ctx) => {
108
- if (ctx.method === "POST" && ctx.path === "/telegram") {
109
- await webhookCallback(bot, "koa", { secretToken: process.env.TELEGRAM_WEBHOOK_SECRET })(ctx.request, ctx);
110
- return;
111
- }
112
- ctx.status = 404;
113
- });
114
- app.listen(3000);
115
- ```
116
-
117
- ## 4. Mendaftarkan URL ke Telegram
118
-
119
- Webhook hanya mengirim ke URL yang Anda daftarkan. Setelah server jalan di URL publik, panggil `setWebhook` sekali:
120
-
121
- ```ts
122
- const secret = process.env.TELEGRAM_WEBHOOK_SECRET;
123
-
124
- await bot.api.methods.setWebhook({
125
- url: "https://bot.example.com/telegram",
126
- secret_token: secret, // sama persis dengan secretToken handler
127
- max_connections: 40, // default 40; sesuaikan dengan kapasitas
128
- allowed_updates: ["message", "callback_query"], // opsional: kurangi trafik
129
- drop_pending_updates: false,
130
- });
131
- ```
132
-
133
- **Menghentikan webhook** — dua opsi:
134
-
135
- ```ts
136
- await bot.api.methods.deleteWebhook({ drop_pending_updates: true }); // kembali ke polling
137
- ```
138
-
139
- Saat bot Anda berjalan di local Bot API server, `setWebhook` juga menerima `ip_address` untuk menghindari resolusi DNS publik.
140
-
141
- ## 5. Secret token
142
-
143
- Tanpa secret, siapa pun yang tahu URL bisa mengirim update palsu. Secret memverifikasi bahwa request berasal dari Telegram:
144
-
145
- ```bash
146
- openssl rand -hex 32
147
- ```
148
-
149
- Simpan sebagai environment variable dan berikan **nilai yang sama persis** ke `setWebhook` (parameter `secret_token`) dan ke handler (opsi `secretToken`). Perbandingan dilakukan constant-time — tidak bisa diTiming-attack. Aturan: 1–256 karakter dari `A-Z a-z 0-9 _ -`.
150
-
151
- Perhatikan `webhookReply` **tidak** terkait secret — mode itu memilih *bagaimana* respons API dikirim, bukan siapa pengirimnya.
152
-
153
- ## 6. Mode `webhookReply`
154
-
155
- Telegram mengizinkan bot menjawab satu panggilan API langsung di body respons webhook. Mengaktifkan mode ini menghilangkan satu round-trip per balasan — sangat berguna di serverless:
156
-
157
- ```ts
158
- const handleUpdate = createWebhookHandler(bot, { webhookReply: true });
159
- ```
160
-
161
- Hanya **satu** panggilan API per update yang mendapat manfaat ini — panggilan pertama yang selesai menang; sisanya dikirim sebagai request HTTP normal. Ketika body respons sudah dipakai, handler mengembalikan `{}` (Telegram tetap menganggapnya sukses).
162
-
163
- Telegraf menyebutnya `telegram.webhookReply`; konsep dan default-nya sama persi di telebibz.
164
-
165
- ## 7. Local development dengan tunnel
166
-
167
- Telegram hanya mengirim ke URL **publik HTTPS**. Saat development, arahkan URL publik ke localhost:
168
-
169
- ```bash
170
- # cloudflared (tanpa akun)
171
- cloudflared tunnel --url http://localhost:3000
172
-
173
- # atau ngrok
174
- ngrok http 3000
175
- ```
176
-
177
- Lalu daftarkan URL yang dihasilkan:
178
-
179
- ```bash
180
- TOKEN="…"
181
- URL="https://random-words.loca.lt" # dari output tunnel
182
- SECRET="…"
183
- curl "https://api.telegram.org/bot$TOKEN/setWebhook" \
184
- -d "url=$URL/telegram" -d "secret_token=$SECRET"
185
- ```
186
-
187
- Lepas webhook setelah selesai (`deleteWebhook`) agar `bot.start()` berfungsi kembali.
188
-
189
- ## 8. Checklist produksi
190
-
191
- - [ ] HTTPS publik + sertifikat valid (Telegram menolak self-signed)
192
- - [ ] `secret_token` ter-set dan cocok di kedua sisi
193
- - [ ] `max_connections` disetel (default 40)
194
- - [ ] Body parser limit ≥ 1 MB (`express.json({ limit: "1mb" })` dkk.)
195
- - [ ] Timeout upstream > `handlerTimeout` (agar `UpdateTimeoutError` sempat mengambil alih, bukan 504 load balancer)
196
- - [ ] `drop_pending_updates` dipertimbangkan saat redeploy
197
- - [ ] Error ter-observasi: `bot.catch()` + `update:error`
198
- - [ ] Graceful shutdown: `bot.stop()` sebelum exit
199
-
200
- ## 9. Troubleshooting
201
-
202
- | Gejala | Penyebab | Perbaikan |
203
- |---|---|---|
204
- | Telegram selalu timeout (baris `getUpdates` kosong) | Webhook aktif — Telegram mengabaikan polling | `deleteWebhook` atau gunakan handler |
205
- | 401 di setiap request | Secret handler ≠ `secret_token` yang terdaftar | Samakan nilainya di `setWebhook` dan handler |
206
- | 413 Payload Too Large | Body melebihi `maxBodyBytes` (default 1 MB) | Naikkan `maxBodyBytes` + limit body parser |
207
- | 502 dari proxy | Webhook mengirim `content-type: application/json` — proxy menolak | Hapus rewrite content-type; handler menerima JSON |
208
- | `409 Conflict` saat `getUpdates` | Webhook masih terdaftar | `deleteWebhook` dulu |
209
- | Update diterima lalu menggantung | Handler menunggu network call yang lambat | Turunkan `handlerTimeout`; pastikan observabilitas via `update:error` |
210
- | Serverless: jawaban tidak pernah sampai | Terlalu banyak await di satu handler | Aktifkan `webhookReply` agar panggilan pertama menumpang respons |
211
-
212
- English: [WEBHOOK.md](WEBHOOK.md) · 简体中文: [WEBHOOK.zh-CN.md](WEBHOOK.zh-CN.md)
package/docs/WEBHOOK.md DELETED
@@ -1,215 +0,0 @@
1
- # Webhook deployment guide (English)
2
-
3
- Everything needed to run telebibz behind a webhook: choosing polling vs webhook, the four framework integrations, secret tokens, registering the webhook, webhook replies, and local development tunnels.
4
-
5
- ## Contents
6
-
7
- 1. [Polling or webhook?](#1-polling-or-webhook)
8
- 2. [The Web-standard handler](#2-the-web-standard-handler)
9
- 3. [Express, Koa, Fastify, and Node http](#3-express-koa-fastify-and-node-http)
10
- 4. [Registering the webhook](#4-registering-the-webhook)
11
- 5. [Secret tokens](#5-secret-tokens)
12
- 6. [Webhook replies (Telegraf-style)](#6-webhook-replies-telegraf-style)
13
- 7. [Local development with a tunnel](#7-local-development-with-a-tunnel)
14
- 8. [Production checklist](#8-production-checklist)
15
- 9. [Troubleshooting](#9-troubleshooting)
16
-
17
- ## 1. Polling or webhook?
18
-
19
- | | Long polling (`bot.start()`) | Webhook |
20
- |---|---|---|
21
- | Setup | zero | needs HTTPS endpoint |
22
- | Works behind NAT/laptop | ✅ | needs tunnel |
23
- | Best for | development, small bots | production, serverless, high volume |
24
- | Update delivery | bot pulls | Telegram pushes |
25
-
26
- Both share the exact same update pipeline (parallel across chats, ordered per chat). Switch freely — handlers do not change.
27
-
28
- ## 2. The Web-standard handler
29
-
30
- `createWebhookHandler()` takes a Web `Request` and returns a `Response` — it works on Node 22 (via `node:http` bridging below), Bun, Deno, and edge runtimes:
31
-
32
- ```ts
33
- import { Bot, createWebhookHandler } from "@xbibzlibrary/telebibz";
34
-
35
- const bot = new Bot(process.env.TELEGRAM_BOT_TOKEN!);
36
- bot.on("message", async (ctx) => { await ctx.reply("hello"); });
37
-
38
- export const handler = createWebhookHandler(bot, {
39
- secretToken: process.env.TELEGRAM_WEBHOOK_SECRET, // verifies X-Telegram-Bot-Api-Secret-Token
40
- maxBodyBytes: 1_048_576, // reject bodies over 1 MB (default)
41
- webhookReply: false, // see section 6
42
- });
43
- ```
44
-
45
- The handler verifies, in order: HTTP method and path, secret token header, body size, JSON parsing, and update shape — answering each failure with the right status code before your handlers ever run.
46
-
47
- ## 3. Express, Koa, Fastify, and Node http
48
-
49
- `webhookCallback()` adapts the handler to each framework's request/response style:
50
-
51
- **Express**
52
-
53
- ```ts
54
- import express from "express";
55
- import { Bot, webhookCallback } from "@xbibzlibrary/telebibz";
56
-
57
- const bot = new Bot(process.env.TELEGRAM_BOT_TOKEN!);
58
- bot.on("message", async (ctx) => { await ctx.reply("hello"); });
59
-
60
- const app = express();
61
- app.use(express.json({ limit: "1mb" }));
62
- app.post("/telegram", webhookCallback(bot, "express", { secretToken: process.env.TELEGRAM_WEBHOOK_SECRET }));
63
- app.get("/healthz", (_req, res) => res.json({ ok: true }));
64
-
65
- app.listen(3000);
66
- ```
67
-
68
- **Node http (no framework)**
69
-
70
- ```ts
71
- import { createServer } from "node:http";
72
- import { webhookCallback } from "@xbibzlibrary/telebibz";
73
-
74
- const callback = webhookCallback(bot, "http", { secretToken: process.env.TELEGRAM_WEBHOOK_SECRET });
75
- createServer((req, res) => {
76
- if (req.method === "POST" && req.url === "/telegram") return void callback(req, res);
77
- res.writeHead(404).end();
78
- }).listen(3000);
79
- ```
80
-
81
- **Fastify**
82
-
83
- ```ts
84
- import Fastify from "fastify";
85
- import { webhookCallback } from "@xbibzlibrary/telebibz";
86
-
87
- const fastify = Fastify({ logger: true });
88
- fastify.post("/telegram", (req, reply) => webhookCallback(bot, "fastify", { secretToken: process.env.TELEGRAM_WEBHOOK_SECRET })(req, reply));
89
- await fastify.listen({ port: 3000, host: "0.0.0.0" });
90
- ```
91
-
92
- **Koa** (with `koa-bodyparser` so `ctx.request.body` is parsed)
93
-
94
- ```ts
95
- import Koa from "koa";
96
- import bodyParser from "koa-bodyparser";
97
- import { webhookCallback } from "@xbibzlibrary/telebibz";
98
-
99
- const app = new Koa();
100
- app.use(bodyParser());
101
- app.use(async (ctx) => {
102
- if (ctx.method === "POST" && ctx.path === "/telegram") {
103
- await webhookCallback(bot, "koa", { secretToken: process.env.TELEGRAM_WEBHOOK_SECRET })(ctx.request, ctx);
104
- return;
105
- }
106
- ctx.status = 404;
107
- });
108
- app.listen(3000);
109
- ```
110
-
111
- Framework ids: `"express" | "http" | "fastify" | "koa"`.
112
-
113
- ## 4. Registering the webhook
114
-
115
- Point Telegram at your endpoint once (not on every boot):
116
-
117
- ```ts
118
- await bot.api.methods.setWebhook({
119
- url: "https://bot.example.com/telegram",
120
- secret_token: process.env.TELEGRAM_WEBHOOK_SECRET,
121
- max_connections: 40, // 1–100, default 40
122
- drop_pending_updates: true, // optional: discard updates queued while down
123
- allowed_updates: ["message", "callback_query"],
124
- });
125
- ```
126
-
127
- Check registration and tear it down:
128
-
129
- ```ts
130
- const info = await bot.api.methods.getWebhookInfo();
131
- await bot.api.methods.deleteWebhook({ drop_pending_updates: false });
132
- ```
133
-
134
- A small CLI-style script makes this repeatable:
135
-
136
- ```ts
137
- // scripts/register-webhook.ts — run with: npx tsx scripts/register-webhook.ts
138
- import { Bot } from "@xbibzlibrary/telebibz";
139
- const bot = new Bot(process.env.TELEGRAM_BOT_TOKEN!);
140
- await bot.api.methods.setWebhook({
141
- url: process.env.WEBHOOK_URL!,
142
- secret_token: process.env.TELEGRAM_WEBHOOK_SECRET,
143
- max_connections: 40,
144
- });
145
- console.log("webhook registered:", process.env.WEBHOOK_URL);
146
- ```
147
-
148
- ## 5. Secret tokens
149
-
150
- Always set a secret token. Telegram then sends it in the `X-Telegram-Bot-Api-Secret-Token` header on every update; the handler rejects anything that does not match with `401 Unauthorized`. Generate one with `openssl rand -hex 32`. Two rules:
151
-
152
- - Between 1 and 256 characters of `A-Z, a-z, 0-9, _` and `-`.
153
- - Pass the **same value** to `setWebhook` (`secret_token`) and to `createWebhookHandler`/`webhookCallback` (`secretToken`).
154
-
155
- ## 6. Webhook replies (Telegraf-style)
156
-
157
- With `webhookReply: true`, the **first** API call while handling an update is answered through the webhook HTTP response itself — Telegram executes the method for you and you save one round trip:
158
-
159
- ```ts
160
- const handler = createWebhookHandler(bot, { webhookReply: true });
161
- ```
162
-
163
- - Only the first call is claimed; later calls go through the transport as usual.
164
- - The claimed call resolves with `true` (Telegram never sends the method result back through the webhook response).
165
- - The lazy `getMe` initialization never claims the slot.
166
- - Per-update override: `bot.handleUpdate(update, { webhookReply: sink })` for fully custom servers.
167
-
168
- Most bots should keep it off — the default reply-then-200 flow is simpler to reason about, and the transport's connection reuse already keeps latency low.
169
-
170
- ## 7. Local development with a tunnel
171
-
172
- Telegram must reach your endpoint over HTTPS. For local development, expose your port through a tunnel and register the tunnel URL:
173
-
174
- ```bash
175
- # Option A: cloudflared (no account, no install to project)
176
- cloudflared tunnel --url http://localhost:3000
177
- # → https://random-name.trycloudflare.com
178
-
179
- # Option B: ngrok
180
- ngrok http 3000
181
- # → https://random-name.ngrok-free.app
182
- ```
183
-
184
- Then:
185
-
186
- ```bash
187
- WEBHOOK_URL=https://random-name.trycloudflare.com npx tsx scripts/register-webhook.ts
188
- ```
189
-
190
- Tunnel URLs change on restart — re-register after each restart, or keep using polling during development and switch to webhooks only in staging/production (the handler code is identical).
191
-
192
- ## 8. Production checklist
193
-
194
- - [ ] HTTPS endpoint with a valid certificate (Telegram rejects self-signed certs unless you upload `certificate`)
195
- - [ ] Secret token set on both `setWebhook` and the handler
196
- - [ ] `max_connections` tuned (default 40; range 1–100)
197
- - [ ] Health endpoint (`/healthz`) for your load balancer
198
- - [ ] Graceful shutdown: `process.on("SIGTERM", () => bot.stop())` — drains in-flight handlers before plugins are disposed
199
- - [ ] Body limit enforced (the handler rejects oversized bodies, but the framework's own limit should match)
200
- - [ ] Logging: `logger: { format: "json" }` for structured ingestion
201
- - [ ] Monitoring: subscribe to `update:error` and `bot:error` events
202
- - [ ] `getWebhookInfo()` polled by your ops dashboard (watch `pending_update_count`)
203
-
204
- ## 9. Troubleshooting
205
-
206
- | Symptom | Cause | Fix |
207
- |---|---|---|
208
- | Telegram never calls the endpoint | Webhook not registered / wrong URL | `getWebhookInfo()` shows the registered URL and the last error |
209
- | Every update answers 401 | Secret token mismatch | Same value in `setWebhook` and the handler |
210
- | 404 from Telegram | Wrong path | Register the exact path you serve (`/telegram`) |
211
- | Updates arrive twice | Both polling and webhook active | `deleteWebhook()` or stop calling `bot.start()` |
212
- | `ai_response`/ssl errors in `getWebhookInfo` | Invalid certificate | Use a CA-signed cert or upload the self-signed one as `certificate` |
213
- | Handler never sees large bodies | Framework body limit below Telegram's payload | Raise the framework's JSON limit (e.g. `express.json({ limit: "1mb" })`) |
214
-
215
- Bahasa Indonesia: [WEBHOOK.id.md](WEBHOOK.id.md) · 简体中文: [WEBHOOK.zh-CN.md](WEBHOOK.zh-CN.md)
@@ -1,212 +0,0 @@
1
- # Webhook 指南(简体中文)
2
-
3
- 通过 webhook 提供更新服务 —— 适用于无长轮询的平台(serverless、容器),或需要公网 HTTPS 端点的场景。
4
-
5
- ## 目录
6
-
7
- 1. [轮询 vs webhook](#1-轮询-vs-webhook)
8
- 2. [处理器:`createWebhookHandler()`](#2-处理器createwebhookhandler)
9
- 3. [常见框架](#3-常见框架)
10
- 4. [向 Telegram 注册 URL](#4-向-telegram-注册-url)
11
- 5. [Secret token](#5-secret-token)
12
- 6. [`webhookReply` 模式](#6-webhookreply-模式)
13
- 7. [本地开发:隧道](#7-本地开发隧道)
14
- 8. [生产检查清单](#8-生产检查清单)
15
- 9. [故障排查](#9-故障排查)
16
-
17
- ## 1. 轮询 vs webhook
18
-
19
- | | 轮询(`bot.start()`) | Webhook |
20
- |---|---|---|
21
- | 主动连接 Telegram | 是(长轮询) | 否 —— Telegram 主动连接你 |
22
- | 需要公网域名 + HTTPS | 否 | 是 |
23
- | 适合 | 本地脚本、开发、VPS | Serverless(Lambda/Workers/Cloud Functions)、容器、k8s |
24
- | 并发 | 相同的逐更新流水线 | 相同的逐更新流水线 |
25
- | 自定义 `POST /<path>` 路由 | — | 是 —— 处理器返回 `Response`,路由仍归你 |
26
-
27
- 同一时间只有一种生效:webhook 注册后 Telegram 把更新推到该 URL,并忽略 `getUpdates`。
28
-
29
- ## 2. 处理器:`createWebhookHandler()`
30
-
31
- 处理器接受 **Web 标准 `Request`** 并返回 **`Response`** —— 可运行于 Node、Bun、Deno 与 edge runtime:
32
-
33
- ```ts
34
- import { createWebhookHandler } from "@xbibzlibrary/telebibz";
35
-
36
- const handleUpdate = createWebhookHandler(bot, {
37
- secretToken: process.env.TELEGRAM_WEBHOOK_SECRET, // 校验 X-Telegram-Bot-Api-Secret-Token
38
- webhookReply: true, // 通过响应体应答 API(可选)
39
- });
40
-
41
- export default {
42
- async fetch(request: Request): Promise<Response> {
43
- if (request.method === "POST" && new URL(request.url).pathname === "/telegram") {
44
- return handleUpdate(request);
45
- }
46
- return new Response("Not Found", { status: 404 });
47
- },
48
- };
49
- ```
50
-
51
- - Body 超过 1 MB → `413 Payload Too Large`(可用 `maxBodyBytes` 调整)。
52
- - Secret 不匹配 → `401 Unauthorized`。
53
- - 非 POST 方法 → `405 Method Not Allowed`。
54
- - 更新经正常流水线处理 —— 错误处理器、session、conversation 全部照常工作。
55
-
56
- 对 Express 风格的 Node 服务器(req/res 对象而非 `Request`),使用 `webhookCallback()` —— 见[常见框架](#3-常见框架)。
57
-
58
- ## 3. 常见框架
59
-
60
- ### Express
61
-
62
- ```ts
63
- import express from "express";
64
- import { webhookCallback } from "@xbibzlibrary/telebibz";
65
-
66
- const app = express();
67
- app.use(express.json({ limit: "1mb" }));
68
- app.post("/telegram", webhookCallback(bot, "express", { secretToken: process.env.TELEGRAM_WEBHOOK_SECRET }));
69
- app.listen(3000);
70
- ```
71
-
72
- ### Node `http`
73
-
74
- ```ts
75
- import http from "node:http";
76
- import { webhookCallback } from "@xbibzlibrary/telebibz";
77
-
78
- const callback = webhookCallback(bot, "http", { secretToken: process.env.TELEGRAM_WEBHOOK_SECRET });
79
- http
80
- .createServer(async (req, res) => {
81
- if (req.method === "POST" && req.url === "/telegram") return callback(req, res);
82
- res.writeHead(404).end();
83
- })
84
- .listen(3000);
85
- ```
86
-
87
- ### Fastify
88
-
89
- ```ts
90
- import Fastify from "fastify";
91
- import { webhookCallback } from "@xbibzlibrary/telebibz";
92
-
93
- const fastify = Fastify({ bodyLimit: 1_048_576 });
94
- fastify.post("/telegram", (req, reply) => webhookCallback(bot, "fastify", { secretToken: process.env.TELEGRAM_WEBHOOK_SECRET })(req, reply));
95
- await fastify.listen({ port: 3000 });
96
- ```
97
-
98
- ### Koa(配合 `koa-bodyparser` 使 `ctx.request.body` 被解析)
99
-
100
- ```ts
101
- import Koa from "koa";
102
- import bodyParser from "koa-bodyparser";
103
- import { webhookCallback } from "@xbibzlibrary/telebibz";
104
-
105
- const app = new Koa();
106
- app.use(bodyParser());
107
- app.use(async (ctx) => {
108
- if (ctx.method === "POST" && ctx.path === "/telegram") {
109
- await webhookCallback(bot, "koa", { secretToken: process.env.TELEGRAM_WEBHOOK_SECRET })(ctx.request, ctx);
110
- return;
111
- }
112
- ctx.status = 404;
113
- });
114
- app.listen(3000);
115
- ```
116
-
117
- ## 4. 向 Telegram 注册 URL
118
-
119
- webhook 只会推送到你注册的 URL。服务器在公网地址就绪后,调用一次 `setWebhook`:
120
-
121
- ```ts
122
- const secret = process.env.TELEGRAM_WEBHOOK_SECRET;
123
-
124
- await bot.api.methods.setWebhook({
125
- url: "https://bot.example.com/telegram",
126
- secret_token: secret, // 与处理器的 secretToken 完全一致
127
- max_connections: 40, // 默认 40;按容量调整
128
- allowed_updates: ["message", "callback_query"], // 可选:减少流量
129
- drop_pending_updates: false,
130
- });
131
- ```
132
-
133
- **撤销 webhook** —— 两种选择:
134
-
135
- ```ts
136
- await bot.api.methods.deleteWebhook({ drop_pending_updates: true }); // 回到轮询
137
- ```
138
-
139
- 当 bot 运行在本地 Bot API 服务器上时,`setWebhook` 还接受 `ip_address`,避免公网 DNS 解析。
140
-
141
- ## 5. Secret token
142
-
143
- 没有 secret,任何知道 URL 的人都能伪造更新。secret 用于确认请求确实来自 Telegram:
144
-
145
- ```bash
146
- openssl rand -hex 32
147
- ```
148
-
149
- 保存为环境变量,并把**完全相同的值**传给 `setWebhook`(`secret_token` 参数)和处理器(`secretToken` 选项)。比较采用常数时间 —— 无法计时攻击。规则:1–256 个字符,仅限 `A-Z a-z 0-9 _ -`。
150
-
151
- 注意 `webhookReply` 与 secret 无关 —— 该模式决定 API 响应*如何*发送,而非请求来自谁。
152
-
153
- ## 6. `webhookReply` 模式
154
-
155
- Telegram 允许 bot 直接在 webhook 响应体里应答一次 API 调用。开启后每次回复省去一次往返 —— 在 serverless 上尤其有价值:
156
-
157
- ```ts
158
- const handleUpdate = createWebhookHandler(bot, { webhookReply: true });
159
- ```
160
-
161
- 每个 update 只有**一次** API 调用能享受此机制 —— 最先完成的那次获胜;其余照常走 HTTP 请求。响应体被占用后,处理器返回 `{}`(Telegram 仍视为成功)。
162
-
163
- Telegraf 中称为 `telegram.webhookReply`;概念与默认值在 telebibz 中完全一致。
164
-
165
- ## 7. 本地开发:隧道
166
-
167
- Telegram 只向**公网 HTTPS** URL 推送。开发时把公网 URL 隧道到 localhost:
168
-
169
- ```bash
170
- # cloudflared(无需账号)
171
- cloudflared tunnel --url http://localhost:3000
172
-
173
- # 或 ngrok
174
- ngrok http 3000
175
- ```
176
-
177
- 然后注册得到的 URL:
178
-
179
- ```bash
180
- TOKEN="…"
181
- URL="https://random-words.loca.lt" # 来自隧道输出
182
- SECRET="…"
183
- curl "https://api.telegram.org/bot$TOKEN/setWebhook" \
184
- -d "url=$URL/telegram" -d "secret_token=$SECRET"
185
- ```
186
-
187
- 开发完成后记得 `deleteWebhook`,让 `bot.start()` 重新可用。
188
-
189
- ## 8. 生产检查清单
190
-
191
- - [ ] 公网 HTTPS + 有效证书(Telegram 拒绝自签名)
192
- - [ ] `secret_token` 已设置且两端一致
193
- - [ ] `max_connections` 已调整(默认 40)
194
- - [ ] Body parser 上限 ≥ 1 MB(`express.json({ limit: "1mb" })` 等)
195
- - [ ] 上游超时 > `handlerTimeout`(让 `UpdateTimeoutError` 先接管,而不是负载均衡器返回 504)
196
- - [ ] 重新部署时考虑 `drop_pending_updates`
197
- - [ ] 错误可观测:`bot.catch()` + `update:error`
198
- - [ ] 优雅关机:退出前 `bot.stop()`
199
-
200
- ## 9. 故障排查
201
-
202
- | 症状 | 原因 | 修复 |
203
- |---|---|---|
204
- | Telegram 一直超时(`getUpdates` 空转) | webhook 处于激活状态 —— Telegram 忽略轮询 | `deleteWebhook` 或改用处理器 |
205
- | 每个请求都 401 | 处理器 secret ≠ 已注册的 `secret_token` | 两端改为一致 |
206
- | 413 Payload Too Large | Body 超过 `maxBodyBytes`(默认 1 MB) | 调大 `maxBodyBytes` 与 body parser 上限 |
207
- | 代理返回 502 | webhook 发送 `content-type: application/json` —— 代理拒绝 | 移除 content-type 改写;处理器接受 JSON |
208
- | `getUpdates` 报 `409 Conflict` | webhook 仍注册着 | 先 `deleteWebhook` |
209
- | 更新收到后挂起 | handler 在等待缓慢的网络调用 | 降低 `handlerTimeout`;通过 `update:error` 保证可观测 |
210
- | Serverless:回复从未送达 | 单个 handler 里 await 过多 | 开启 `webhookReply`,让第一次调用搭响应的便车 |
211
-
212
- English: [WEBHOOK.md](WEBHOOK.md) · Bahasa Indonesia: [WEBHOOK.id.md](WEBHOOK.id.md)
@@ -1,37 +0,0 @@
1
- # Telebibz examples
2
-
3
- These examples are intentionally small, runnable starting points for developers evaluating Telebibz. They use environment variables for secrets and do not contain real Telegram credentials.
4
-
5
- ## Run the examples
6
-
7
- From the repository root:
8
-
9
- ```bash
10
- npm install
11
- export TELEGRAM_BOT_TOKEN="<your-bot-token>"
12
- npx tsx examples/minimal.ts
13
- ```
14
-
15
- The official npm package can be used from a separate project by replacing the local import path with `@xbibzlibrary/telebibz` and installing the package from npm.
16
-
17
- ## Available starters
18
-
19
- | Example | Demonstrates | Start command |
20
- |---|---|---|
21
- | `minimal.ts` | Commands, text routing, and a minimal long-polling bot. | `npx tsx examples/minimal.ts` |
22
- | `wizard-registration.ts` | A two-step name/age conversation with automatic continuation across messages. | `npx tsx examples/wizard-registration.ts` |
23
- | `webhook.ts` | A Node.js HTTP server, webhook secret validation, and Telegram update handling. | `TELEGRAM_WEBHOOK_SECRET=<secret> npx tsx examples/webhook.ts` |
24
-
25
- The wizard example starts the flow with `/register`, asks for a name, then asks for an age. Send `/cancel` to cancel an active flow. The webhook example requires both `TELEGRAM_BOT_TOKEN` and `TELEGRAM_WEBHOOK_SECRET`; expose the server through HTTPS in a deployment environment and configure the matching Telegram webhook secret.
26
-
27
- ## Production checklist
28
-
29
- Use a secret manager or deployment environment for `TELEGRAM_BOT_TOKEN` and `TELEGRAM_WEBHOOK_SECRET`. Do not commit `.env` files or literal credentials. Run `npm run test:examples` before submitting changes. For production deployments, prefer a managed HTTPS endpoint, structured JSON logs, health checks, graceful shutdown, and a persistent storage adapter when conversations or sessions must survive restarts.
30
-
31
- ## More documentation
32
-
33
- - [English API reference](../docs/API.md)
34
- - [Bahasa Indonesia API reference](../docs/API.id.md)
35
- - [简体中文 API reference](../docs/API.zh-CN.md)
36
- - [GitHub Packages guide](../docs/GITHUB_PACKAGES.md)
37
- - [Contributing guide](../CONTRIBUTING.md)