@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.
- package/CHANGELOG.md +35 -138
- package/LICENSE +1 -1
- package/NOTICE.md +9 -4
- package/README.md +173 -256
- package/examples/01-quickstart.js +13 -0
- package/examples/02-menu-tombol.js +22 -0
- package/examples/03-wizard.js +29 -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 +81 -0
- package/index.js +42 -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 +190 -0
- package/lib/wizard.js +81 -0
- package/package.json +35 -97
- package/test/all.test.js +334 -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.id.md +0 -306
- 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
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
# 从 Telegraf 迁移(简体中文)
|
|
2
|
-
|
|
3
|
-
telebibz 有意实现了 Telegraf 的 context 表面与启动选项,因此大多数 handler 只需极少改动即可移植。本指南把 Telegraf bot 的每个部分映射到 telebibz 对应物。
|
|
4
|
-
|
|
5
|
-
## 目录
|
|
6
|
-
|
|
7
|
-
1. [并排对照:完整 bot](#1-并排对照完整-bot)
|
|
8
|
-
2. [概念映射](#2-概念映射)
|
|
9
|
-
3. [Context 方法](#3-context-方法)
|
|
10
|
-
4. [启动选项](#4-启动选项)
|
|
11
|
-
5. [Scenes → Wizards](#5-scenes--wizards)
|
|
12
|
-
6. [会话存储](#6-会话存储)
|
|
13
|
-
7. [Webhook](#7-webhook)
|
|
14
|
-
8. [没有直接对应物的部分](#8-没有直接对应物的部分)
|
|
15
|
-
|
|
16
|
-
## 1. 并排对照:完整 bot
|
|
17
|
-
|
|
18
|
-
**Telegraf**
|
|
19
|
-
|
|
20
|
-
```ts
|
|
21
|
-
import { Telegraf } from "telegraf";
|
|
22
|
-
|
|
23
|
-
const bot = new Telegraf(process.env.TELEGRAM_BOT_TOKEN!);
|
|
24
|
-
|
|
25
|
-
bot.use(async (ctx, next) => { console.time("update"); await next(); console.timeEnd("update"); });
|
|
26
|
-
bot.start((ctx) => ctx.reply("Welcome!"));
|
|
27
|
-
bot.command("help", (ctx) => ctx.reply("Help"));
|
|
28
|
-
bot.action("menu:open", async (ctx) => { await ctx.answerCbQuery(); await ctx.reply("Menu"); });
|
|
29
|
-
bot.on("message", (ctx) => ctx.reply("got it"));
|
|
30
|
-
bot.catch((error) => console.error(error));
|
|
31
|
-
|
|
32
|
-
bot.launch({ dropPendingUpdates: true });
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
**telebibz**
|
|
36
|
-
|
|
37
|
-
```ts
|
|
38
|
-
import { Bot } from "@xbibzlibrary/telebibz";
|
|
39
|
-
|
|
40
|
-
const bot = new Bot(process.env.TELEGRAM_BOT_TOKEN!);
|
|
41
|
-
|
|
42
|
-
bot.use(async (ctx, next) => { console.time("update"); await next(); console.timeEnd("update"); });
|
|
43
|
-
bot.command("start", async (ctx) => { await ctx.reply("Welcome!"); }); // 具名命令,而非 bot.start()
|
|
44
|
-
bot.command("help", async (ctx) => { await ctx.reply("Help"); });
|
|
45
|
-
bot.action("menu:open", async (ctx) => { await ctx.answerCallbackQuery(); await ctx.reply("Menu"); });
|
|
46
|
-
bot.on("message", async (ctx) => { await ctx.reply("got it"); });
|
|
47
|
-
bot.catch(async (error) => { console.error(error); });
|
|
48
|
-
|
|
49
|
-
await bot.launch({ dropPendingUpdates: true }); // 选项名相同
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
只有两处机械差异:`bot.start(handler)` 变为 `bot.command("start", handler)`;`answerCbQuery()` 变为 `answerCallbackQuery()`。
|
|
53
|
-
|
|
54
|
-
## 2. 概念映射
|
|
55
|
-
|
|
56
|
-
| Telegraf | telebibz | 说明 |
|
|
57
|
-
|---|---|---|
|
|
58
|
-
| `new Telegraf(token)` | `new Bot(token)` 或 `new Bot({ token, ... })` | |
|
|
59
|
-
| `bot.launch()` | `bot.launch()` / `bot.start()` | `launch` 上显式声明 `mode: "polling"` |
|
|
60
|
-
| `bot.stop()` | `bot.stop()` | telebibz 先排空在途 handler |
|
|
61
|
-
| `bot.use(mw)` | `bot.use(mw)` | 中间件签名相同 `(ctx, next)` |
|
|
62
|
-
| `bot.command(name, h)` | `bot.command(name, h)` | |
|
|
63
|
-
| `bot.on(filter, h)` | `bot.on(filter, h)` | 过滤语法相同(`message:photo`、数组) |
|
|
64
|
-
| `bot.hears(trigger, h)` | `bot.hears(trigger, h)` | 字符串与 RegExp |
|
|
65
|
-
| `bot.action(pattern, h)` | `bot.action(pattern, h)` | `bot.callback` 的直接别名 |
|
|
66
|
-
| `bot.catch(handler)` | `bot.catch(handler)` | 接收 `(error, ctx)` |
|
|
67
|
-
|
|
68
|
-
## 3. Context 方法
|
|
69
|
-
|
|
70
|
-
Telegraf context 的每个快捷方法都在 —— 包括 Telegraf 留给插件的那部分:
|
|
71
|
-
|
|
72
|
-
- **回复**:`reply`、`replyWithPhoto`、`replyWithDocument`、`replyWithVideo`、`replyWithAudio`、`replyWithVoice`、`replyWithAnimation`、`replyWithVideoNote`、`replyWithSticker`、`replyWithMediaGroup`、`replyWithLocation`、`replyWithVenue`、`replyWithContact`、`replyWithPoll`、`replyWithQuiz`、`replyWithDice`、`replyWithGame`、`replyWithInvoice`、`replyWithHTML`、`replyWithMarkdown`(+V2)
|
|
73
|
-
- **管理/群管**:`banChatMember`、`unbanChatMember`、`restrictChatMember`、`promoteChatMember`、`banChatSenderChat`、`unbanChatSenderChat`
|
|
74
|
-
- **聊天**:`setChatTitle`、`setChatDescription`、`setChatPhoto`、`deleteChatPhoto`、`setChatPermissions`、`leaveChat`、`unpinAllChatMessages`、`setChatStickerSet`、`deleteChatStickerSet`
|
|
75
|
-
- **信息**:`getChat`、`getChatAdministrators`、`getChatMemberCount`、`getChatMember`
|
|
76
|
-
- **邀请链接/加群申请**:`exportChatInviteLink`、`createChatInviteLink`、`editChatInviteLink`、`revokeChatInviteLink`、`approveChatJoinRequest`、`declineChatJoinRequest`
|
|
77
|
-
- **实时位置/投票/游戏**:`editMessageLiveLocation`、`stopMessageLiveLocation`、`stopPoll`、`setGameScore`、`getGameHighScores`
|
|
78
|
-
- **论坛**:完整话题方法集(`createForumTopic` … `unhideGeneralForumTopic`)
|
|
79
|
-
- **超越 Telegraf 核心的新增**:`getFile`(带类型)、`downloadFile`、`edit`(改写当前消息文本),以及从包根导出的独立助手 —— `validateUpload`/`assertValidUpload` —— 它们不是 context 方法
|
|
80
|
-
|
|
81
|
-
移植时需修正的命名差异:`answerCbQuery` → `answerCallbackQuery`;`ctx.telegram` → `ctx.api`;键盘助手来自包根(`InlineKeyboard`、`ReplyKeyboard`、`removeKeyboard`、`forceReply`)而非 `Markup`。
|
|
82
|
-
|
|
83
|
-
## 4. 启动选项
|
|
84
|
-
|
|
85
|
-
| Telegraf | telebibz |
|
|
86
|
-
|---|---|
|
|
87
|
-
| `launch({ dropPendingUpdates })` | `launch({ dropPendingUpdates })` —— 完全相同 |
|
|
88
|
-
| `handlerTimeout`(默认 90 000) | `handlerTimeout`(默认 90 000;`0` 禁用) |
|
|
89
|
-
| `contextType` 选项 | `contextType` 选项 —— 你的 `Context` 子类会为每个更新实例化 |
|
|
90
|
-
| `webhookReply`(按更新) | 处理器 / `handleUpdate` 选项上的 `webhookReply` |
|
|
91
|
-
| `telegraf.use(session(...))` | `new Bot({ session: new MemoryStorage() })`(或 JSON/Redis/SQL/Mongo) |
|
|
92
|
-
|
|
93
|
-
## 5. Scenes → Wizards
|
|
94
|
-
|
|
95
|
-
Telegraf 的 `WizardScene` + `Stage` 变成单个 `Wizard`:显式步骤、无全局 session 键:
|
|
96
|
-
|
|
97
|
-
```ts
|
|
98
|
-
import { Bot, Wizard } from "@xbibzlibrary/telebibz";
|
|
99
|
-
|
|
100
|
-
const wizard = new Wizard()
|
|
101
|
-
.step({ id: "ask-name", run: async (flow) => { flow.next(); await flow.ctx.reply("名字?"); } })
|
|
102
|
-
.step({ id: "save", run: async (flow) => { await flow.ctx.reply(`你好 ${flow.ctx.message?.text}!`); } });
|
|
103
|
-
|
|
104
|
-
const bot = new Bot(process.env.TELEGRAM_BOT_TOKEN!);
|
|
105
|
-
bot.useWizard(wizard); // 取代 Stage 中间件
|
|
106
|
-
bot.command("start", async (ctx) => { await wizard.run(ctx); }); // 取代 scene.enter()
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
- 向导键自动由 chat + 发送者派生 —— 无需手工管理键。
|
|
110
|
-
- `flow.set(key, value)` / `flow.get(key)` 取代 `ctx.scene.session`。
|
|
111
|
-
- `/cancel` 取消;最后一步完成后对话自动收尾。
|
|
112
|
-
- 非线性流程图请用 `ConversationManager` 配合 router 组合(telebibz 刻意把场景编排留给应用;见 FEATURE_MATRIX 的 "Design decisions")。
|
|
113
|
-
|
|
114
|
-
## 6. 会话存储
|
|
115
|
-
|
|
116
|
-
Telegraf 默认把会话放在内存,持久化需要 store 插件。telebibz 在构造函数上接收 storage —— 换适配器,不换代码:
|
|
117
|
-
|
|
118
|
-
```ts
|
|
119
|
-
import { Bot, MemoryStorage, JsonFileStorage, RedisStorage } from "@xbibzlibrary/telebibz";
|
|
120
|
-
|
|
121
|
-
const bot = new Bot({
|
|
122
|
-
token: process.env.TELEGRAM_BOT_TOKEN!,
|
|
123
|
-
session: new JsonFileStorage("state/sessions.json"), // 或 MemoryStorage / RedisStorage / SqlStorage / MongoStorage
|
|
124
|
-
});
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
每个适配器的完整接线配方:[STORAGE.zh-CN.md](STORAGE.zh-CN.md)。
|
|
128
|
-
|
|
129
|
-
## 7. Webhook
|
|
130
|
-
|
|
131
|
-
```ts
|
|
132
|
-
// Telegraf: webhookCallback(bot, app)
|
|
133
|
-
// telebibz: 框架需显式指定
|
|
134
|
-
import { webhookCallback } from "@xbibzlibrary/telebibz";
|
|
135
|
-
app.post("/telegram", webhookCallback(bot, "express", { secretToken: process.env.TELEGRAM_WEBHOOK_SECRET }));
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
`createWebhookHandler()` 另外提供 Web 标准 `Request → Response` 处理器,适配 Bun/Deno/edge。完整部署指南:[WEBHOOK.zh-CN.md](WEBHOOK.zh-CN.md)。
|
|
139
|
-
|
|
140
|
-
## 8. 没有直接对应物的部分
|
|
141
|
-
|
|
142
|
-
- **`bot.telegram` 底层客户端** —— 使用 `bot.api`(`call`、`raw`、`methods`、`downloadFile`);flood gate 与重试内置于传输层,不能按调用配置。
|
|
143
|
-
- **Telegraf 插件生态** —— 把插件移植为带显式生命周期(`install`、`onStop`、`dispose`)的 `Plugin` 对象;插件管理器可干净重启。
|
|
144
|
-
- **`Composer.mount`/动态 scene** —— 改用 `Router` 嵌套与 `matchMode: "all"` 组合。
|
|
145
|
-
- **Markup 链式助手**(`Markup.keyboard(...).resize()`) —— 使用 `new ReplyKeyboard().text("A").resized().build()`;负载相同,builder 风格。
|
|
146
|
-
|
|
147
|
-
English: [MIGRATION_TELEGRAF.md](MIGRATION_TELEGRAF.md) · Bahasa Indonesia: [MIGRATION_TELEGRAF.id.md](MIGRATION_TELEGRAF.id.md)
|
package/docs/README.md
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
# telebibz Documentation
|
|
2
|
-
|
|
3
|
-
The default documentation language is **English**. Every guide below is available in English, Bahasa Indonesia, and 简体中文.
|
|
4
|
-
|
|
5
|
-
| Language | README | Getting started | Complete API reference |
|
|
6
|
-
|---|---|---|---|
|
|
7
|
-
| English (default) | [`README.md`](../README.md) | [`GETTING_STARTED.md`](GETTING_STARTED.md) | [`API.md`](API.md) |
|
|
8
|
-
| Bahasa Indonesia | [`README.id.md`](../README.id.md) | [`GETTING_STARTED.id.md`](GETTING_STARTED.id.md) | [`API.id.md`](API.id.md) |
|
|
9
|
-
| 简体中文 | [`README.zh-CN.md`](../README.zh-CN.md) | [`GETTING_STARTED.zh-CN.md`](GETTING_STARTED.zh-CN.md) | [`API.zh-CN.md`](API.zh-CN.md) |
|
|
10
|
-
|
|
11
|
-

|
|
12
|
-
|
|
13
|
-
The documentation covers the complete lifecycle: onboarding, bot startup and shutdown, API client and transport, update routing, middleware and context, state/session, interaction UI, background work, files, errors, webhook deployment, testing, migration, and production recipes.
|
|
14
|
-
|
|
15
|
-
## Complete guide catalog
|
|
16
|
-
|
|
17
|
-
Every topic guide ships in three languages (EN · ID · ZH). Pick a topic, pick a language:
|
|
18
|
-
|
|
19
|
-
| Guide | English | Bahasa Indonesia | 简体中文 | Purpose |
|
|
20
|
-
|---|---|---|---|---|
|
|
21
|
-
| Getting started | [`GETTING_STARTED.md`](GETTING_STARTED.md) | [`GETTING_STARTED.id.md`](GETTING_STARTED.id.md) | [`GETTING_STARTED.zh-CN.md`](GETTING_STARTED.zh-CN.md) | Five-minute onboarding from installation to a working bot. |
|
|
22
|
-
| Complete API reference | [`API.md`](API.md) | [`API.id.md`](API.id.md) | [`API.zh-CN.md`](API.zh-CN.md) | Every exported class, method, type, error, and generated Telegram method. |
|
|
23
|
-
| Files: upload & download | [`FILES.md`](FILES.md) | [`FILES.id.md`](FILES.id.md) | [`FILES.zh-CN.md`](FILES.zh-CN.md) | `downloadFile()`, manual `getFile()`, `file_path` vs `filePath`, upload sources, validation, limits, troubleshooting. |
|
|
24
|
-
| Errors | [`ERRORS.md`](ERRORS.md) | [`ERRORS.id.md`](ERRORS.id.md) | [`ERRORS.zh-CN.md`](ERRORS.zh-CN.md) | Error taxonomy, 429 and the flood gate, `bot.catch()`, `handlerTimeout`, retries, graceful shutdown. |
|
|
25
|
-
| Webhook | [`WEBHOOK.md`](WEBHOOK.md) | [`WEBHOOK.id.md`](WEBHOOK.id.md) | [`WEBHOOK.zh-CN.md`](WEBHOOK.zh-CN.md) | Polling vs webhook, `createWebhookHandler()`, Express/http/Fastify/Koa, `setWebhook`, secret tokens, tunnels, production checklist. |
|
|
26
|
-
| Testing | [`TESTING.md`](TESTING.md) | [`TESTING.id.md`](TESTING.id.md) | [`TESTING.zh-CN.md`](TESTING.zh-CN.md) | Fully offline testing with `MockTransport`, driving updates, wizards end to end, webhooks, error paths, Vitest patterns. |
|
|
27
|
-
| Migration from Telegraf | [`MIGRATION_TELEGRAF.md`](MIGRATION_TELEGRAF.md) | [`MIGRATION_TELEGRAF.id.md`](MIGRATION_TELEGRAF.id.md) | [`MIGRATION_TELEGRAF.zh-CN.md`](MIGRATION_TELEGRAF.zh-CN.md) | Side-by-side port, concept map, context methods, scenes → wizards, webhooks. |
|
|
28
|
-
| Storage | [`STORAGE.md`](STORAGE.md) | [`STORAGE.id.md`](STORAGE.id.md) | [`STORAGE.zh-CN.md`](STORAGE.zh-CN.md) | Memory/JSON/Redis/SQL/Mongo adapters, TTL, atomic `update()`. |
|
|
29
|
-
| Production cookbook | [`COOKBOOK.md`](COOKBOOK.md) | [`COOKBOOK.id.md`](COOKBOOK.id.md) | [`COOKBOOK.zh-CN.md`](COOKBOOK.zh-CN.md) | Thirteen verified recipes: rate limiting, auth, broadcast, scheduling, queues, menus, forms, caching, Mini Apps, payments, metrics. |
|
|
30
|
-
| GitHub Packages install | [`GITHUB_PACKAGES.md`](GITHUB_PACKAGES.md) | [`GITHUB_PACKAGES.id.md`](GITHUB_PACKAGES.id.md) | [`GITHUB_PACKAGES.zh-CN.md`](GITHUB_PACKAGES.zh-CN.md) | Installing via GitHub Packages with a personal access token. |
|
|
31
|
-
|
|
32
|
-
Also available: [`../examples/README.md`](../examples/README.md) — runnable minimal, wizard, file, and webhook starters, and [`../SHOWCASE.md`](../SHOWCASE.md) — community project showcase.
|
|
33
|
-
|
|
34
|
-
## Coverage status
|
|
35
|
-
|
|
36
|
-
| Area | Status |
|
|
37
|
-
|---|---|
|
|
38
|
-
| Getting started | Dedicated guides in EN/ID/ZH with runnable examples |
|
|
39
|
-
| Complete API reference | Available in EN/ID/ZH |
|
|
40
|
-
| Bot lifecycle, polling, webhook | Core implementation, per-update error isolation, reconnect backoff, and tests available |
|
|
41
|
-
| API client and generated method list | Available; full vendored Telegram declarations exposed through `TelegramTypes` |
|
|
42
|
-
| Router, middleware, context | Available and tested; first-match is default, all-match is explicit |
|
|
43
|
-
| Keyboard, callback, menus, pagination | Keyboard/callback core, permission menus, MenuController, and pagination available |
|
|
44
|
-
| Sessions, conversations, wizards, forms | Storage-backed session/conversation primitives and forms available; scene orchestration remains application-owned |
|
|
45
|
-
| Storage, cache, queue, scheduler | Memory, JSON file, Redis, SQL, Mongo driver adapters, cache, queue, and full five-field cron available |
|
|
46
|
-
| Files | Dedicated guide: one-call `downloadFile()`, upload sources, validation, limits, troubleshooting (EN/ID/ZH) |
|
|
47
|
-
| Errors | Dedicated guide: taxonomy, 429/flood gate, boundaries, timeouts, retries (EN/ID/ZH) |
|
|
48
|
-
| Webhook deployment | Dedicated guide: handler, four frameworks, registration, secrets, tunnels, checklist (EN/ID/ZH) |
|
|
49
|
-
| Testing | Dedicated guide: MockTransport, update drivers, wizards, webhooks, error paths (EN/ID/ZH) |
|
|
50
|
-
| Migration | Dedicated Telegraf migration guide (EN/ID/ZH) |
|
|
51
|
-
| Production recipes | Cookbook with thirteen verified recipes (EN/ID/ZH) |
|
|
52
|
-
| Plugins, services, observability | Lifecycle/plugin/service hooks available |
|
|
53
|
-
| Mini Apps, payments, business features | Web App signature validation and PaymentsClient wrappers available; UI is application-owned |
|
|
54
|
-
| Testing and security | Unit, integration, type-level, gated E2E, CI, and security policy available |
|
|
55
|
-
| Deployment and migration | Release automation is documented in `RELEASE_AUTOMATION.md`; webhook deployment is in `WEBHOOK.md` |
|
|
56
|
-
| Governance and community | `CODE_OF_CONDUCT.md`, `GOVERNANCE.md`, `CONTRIBUTING.md`, `CONTRIBUTION_RULES.md`, and `SHOWCASE.md` |
|
|
57
|
-
| Security and support | `SECURITY.md` and `SUPPORT.md` |
|
|
58
|
-
| Third-party notices | `NOTICE.md` and `LICENSE` |
|
|
59
|
-
| GitHub contribution templates | Bug, feature, documentation, question/support, security notice, and pull request templates under `.github/` |
|
|
60
|
-
|
|
61
|
-
## GitHub templates
|
|
62
|
-
|
|
63
|
-
Issue forms are available for bug reports, feature requests, documentation problems, and support questions. A security notice template redirects reporters to the private process in `SECURITY.md`; vulnerabilities must not be disclosed in public issues. Pull requests use `.github/PULL_REQUEST_TEMPLATE/pull_request_template.md` to require tests, documentation, compatibility, and security checks.
|
|
64
|
-
|
|
65
|
-
## Documentation principle
|
|
66
|
-
|
|
67
|
-
The documentation describes only capabilities that are implemented and tested in the current package, and every code snippet in the guides is verified against the actual implementation. Telegram-native API access, Mini App/Web App behavior, external persistence, and distributed adapters are described separately so the documentation does not promise features that are not included.
|
package/docs/STORAGE.id.md
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
# Panduan cepat storage (Bahasa Indonesia)
|
|
2
|
-
|
|
3
|
-
telebibz menyediakan interface `Storage<K, V>` generik dengan lima adapter. Core package **tanpa runtime dependency**: adapter Redis, SQL, dan Mongo menerima driver interface kecil yang sudah Anda punya, jadi Anda yang memilih driver dan versinya.
|
|
4
|
-
|
|
5
|
-
Semua adapter memakai kontrak yang sama — `get` / `set` / `delete` / `has` / `clear` / `keys()` / `entries()` — ditambah **`update(key, updater, { ttlMs })`** yang menyalin penulisan per key sehingga update bersamaan ke key yang sama tidak pernah saling menimpa. TTL diatur per penulisan lewat `{ ttlMs }`.
|
|
6
|
-
|
|
7
|
-
## MemoryStorage (default — tanpa konfigurasi)
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
import { Bot } from "@xbibzlibrary/telebibz";
|
|
11
|
-
|
|
12
|
-
const bot = new Bot({ token: process.env.TELEGRAM_BOT_TOKEN! });
|
|
13
|
-
// bot.session secara default adalah MemoryStorage<string, S>.
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
## JsonFileStorage (persistensi satu file, tetap tanpa dependency)
|
|
17
|
-
|
|
18
|
-
```ts
|
|
19
|
-
import { Bot, JsonFileStorage } from "@xbibzlibrary/telebibz";
|
|
20
|
-
|
|
21
|
-
const bot = new Bot({
|
|
22
|
-
token: process.env.TELEGRAM_BOT_TOKEN!,
|
|
23
|
-
session: new JsonFileStorage("state/sessions.json"),
|
|
24
|
-
});
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## RedisStorage (bawa client Anda sendiri)
|
|
28
|
-
|
|
29
|
-
Adapter ini hanya butuh lima method callback-style yang dimiliki setiap client Redis — `node-redis` langsung cocok:
|
|
30
|
-
|
|
31
|
-
```ts
|
|
32
|
-
import { Bot, RedisStorage } from "@xbibzlibrary/telebibz";
|
|
33
|
-
import { createClient } from "redis"; // driver dan versi pilihan Anda
|
|
34
|
-
|
|
35
|
-
const redis = createClient({ url: process.env.REDIS_URL });
|
|
36
|
-
await redis.connect();
|
|
37
|
-
|
|
38
|
-
const bot = new Bot({
|
|
39
|
-
token: process.env.TELEGRAM_BOT_TOKEN!,
|
|
40
|
-
session: new RedisStorage(redis, "mybot:"), // prefix untuk key Anda
|
|
41
|
-
});
|
|
42
|
-
// TTL per penulisan: await bot.session.set(key, value, { ttlMs: 24 * 60 * 60 * 1000 });
|
|
43
|
-
// (kedaluwarsa PX Redis diterapkan otomatis.)
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## SqlStorage (semua database SQL)
|
|
47
|
-
|
|
48
|
-
Implementasikan driver lima method di atas library SQL Anda; contoh ini memakai `better-sqlite3`:
|
|
49
|
-
|
|
50
|
-
```ts
|
|
51
|
-
import { Bot, SqlStorage } from "@xbibzlibrary/telebibz";
|
|
52
|
-
import Database from "better-sqlite3";
|
|
53
|
-
|
|
54
|
-
const db = new Database("state/bot.db");
|
|
55
|
-
db.exec("CREATE TABLE IF NOT EXISTS kv (key TEXT PRIMARY KEY, value TEXT NOT NULL, expires_at INTEGER)");
|
|
56
|
-
|
|
57
|
-
const storage = new SqlStorage({
|
|
58
|
-
async get(key) {
|
|
59
|
-
const row = db.prepare("SELECT value, expires_at FROM kv WHERE key = ?").get(key) as { value: string; expires_at: number | null } | undefined;
|
|
60
|
-
return row === undefined ? undefined : JSON.parse(row.value);
|
|
61
|
-
},
|
|
62
|
-
async set(key, value, expiresAt) {
|
|
63
|
-
db.prepare("INSERT INTO kv (key, value, expires_at) VALUES (?, ?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value, expires_at = excluded.expires_at")
|
|
64
|
-
.run(key, JSON.stringify(value), expiresAt ?? null);
|
|
65
|
-
},
|
|
66
|
-
async delete(key) { return db.prepare("DELETE FROM kv WHERE key = ?").run(key).changes > 0; },
|
|
67
|
-
async has(key) { return db.prepare("SELECT 1 FROM kv WHERE key = ?").get(key) !== undefined; },
|
|
68
|
-
async clear() { db.prepare("DELETE FROM kv").run(); },
|
|
69
|
-
async entries() {
|
|
70
|
-
const rows = db.prepare("SELECT key, value, expires_at FROM kv").all() as Array<{ key: string; value: string; expires_at: number | null }>;
|
|
71
|
-
return rows.map((row) => [row.key, JSON.parse(row.value), row.expiresAt ?? undefined] as [string, unknown, number | undefined]);
|
|
72
|
-
},
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const bot = new Bot({ token: process.env.TELEGRAM_BOT_TOKEN!, session: storage });
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## MongoStorage (bawa collection Anda sendiri)
|
|
79
|
-
|
|
80
|
-
Adapter ini berbicara langsung dengan bentuk collection MongoDB standar — cukup kirim collection Anda:
|
|
81
|
-
|
|
82
|
-
```ts
|
|
83
|
-
import { Bot, MongoStorage } from "@xbibzlibrary/telebibz";
|
|
84
|
-
import { MongoClient } from "mongodb";
|
|
85
|
-
|
|
86
|
-
const client = new MongoClient(process.env.MONGODB_URL!);
|
|
87
|
-
await client.connect();
|
|
88
|
-
|
|
89
|
-
const bot = new Bot({
|
|
90
|
-
token: process.env.TELEGRAM_BOT_TOKEN!,
|
|
91
|
-
session: new MongoStorage(client.db("mybot").collection("sessions")),
|
|
92
|
-
});
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
## Memilih
|
|
96
|
-
|
|
97
|
-
| Adapter | Pakai saat | Persistensi | Dependency tambahan |
|
|
98
|
-
|---|---|---|---|
|
|
99
|
-
| `MemoryStorage` | bot satu proses, test | selama proses hidup | tidak ada |
|
|
100
|
-
| `JsonFileStorage` | bot kecil, deploy sederhana | file di disk | tidak ada |
|
|
101
|
-
| `RedisStorage` | multi-instance, state bersama | Redis | client Redis Anda |
|
|
102
|
-
| `SqlStorage` | aplikasi berbasis SQL | semua database SQL | driver SQL Anda |
|
|
103
|
-
| `MongoStorage` | stack Mongo yang sudah ada | MongoDB | driver Mongo Anda |
|
|
104
|
-
|
|
105
|
-
Signature API lengkap: [API.id.md](API.id.md). English: [STORAGE.md](STORAGE.md) · 简体中文: [STORAGE.zh-CN.md](STORAGE.zh-CN.md).
|
package/docs/STORAGE.md
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
# Storage quick start (English)
|
|
2
|
-
|
|
3
|
-
telebibz ships a generic `Storage<K, V>` interface with five adapters. The core package has **zero runtime dependencies**: the Redis, SQL, and Mongo adapters accept a small driver interface you already have, so you pick the driver and version.
|
|
4
|
-
|
|
5
|
-
All adapters share one contract — `get` / `set` / `delete` / `has` / `clear` / `keys()` / `entries()` — plus **`update(key, updater, { ttlMs })`**, which serializes writes per key so concurrent updates to the same key never interleave. TTL is set per write through `{ ttlMs }`.
|
|
6
|
-
|
|
7
|
-
## MemoryStorage (default — nothing to configure)
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
import { Bot } from "@xbibzlibrary/telebibz";
|
|
11
|
-
|
|
12
|
-
const bot = new Bot({ token: process.env.TELEGRAM_BOT_TOKEN! });
|
|
13
|
-
// bot.session is a MemoryStorage<string, S> by default.
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
## JsonFileStorage (single-file persistence, still zero dependencies)
|
|
17
|
-
|
|
18
|
-
```ts
|
|
19
|
-
import { Bot, JsonFileStorage } from "@xbibzlibrary/telebibz";
|
|
20
|
-
|
|
21
|
-
const bot = new Bot({
|
|
22
|
-
token: process.env.TELEGRAM_BOT_TOKEN!,
|
|
23
|
-
session: new JsonFileStorage("state/sessions.json"),
|
|
24
|
-
});
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## RedisStorage (bring your own client)
|
|
28
|
-
|
|
29
|
-
The adapter needs exactly the five callback-style methods every Redis client exposes — `node-redis` works as-is:
|
|
30
|
-
|
|
31
|
-
```ts
|
|
32
|
-
import { Bot, RedisStorage } from "@xbibzlibrary/telebibz";
|
|
33
|
-
import { createClient } from "redis"; // your choice of driver and version
|
|
34
|
-
|
|
35
|
-
const redis = createClient({ url: process.env.REDIS_URL });
|
|
36
|
-
await redis.connect();
|
|
37
|
-
|
|
38
|
-
const bot = new Bot({
|
|
39
|
-
token: process.env.TELEGRAM_BOT_TOKEN!,
|
|
40
|
-
session: new RedisStorage(redis, "mybot:"), // prefix for your keys
|
|
41
|
-
});
|
|
42
|
-
// Per-write TTL: await bot.session.set(key, value, { ttlMs: 24 * 60 * 60 * 1000 });
|
|
43
|
-
// (Redis PX expiry is applied automatically.)
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## SqlStorage (any SQL database)
|
|
47
|
-
|
|
48
|
-
Implement the five-method driver over your SQL library; the example uses `better-sqlite3`:
|
|
49
|
-
|
|
50
|
-
```ts
|
|
51
|
-
import { Bot, SqlStorage } from "@xbibzlibrary/telebibz";
|
|
52
|
-
import Database from "better-sqlite3";
|
|
53
|
-
|
|
54
|
-
const db = new Database("state/bot.db");
|
|
55
|
-
db.exec("CREATE TABLE IF NOT EXISTS kv (key TEXT PRIMARY KEY, value TEXT NOT NULL, expires_at INTEGER)");
|
|
56
|
-
|
|
57
|
-
const storage = new SqlStorage({
|
|
58
|
-
async get(key) {
|
|
59
|
-
const row = db.prepare("SELECT value, expires_at FROM kv WHERE key = ?").get(key) as { value: string; expires_at: number | null } | undefined;
|
|
60
|
-
return row === undefined ? undefined : JSON.parse(row.value);
|
|
61
|
-
},
|
|
62
|
-
async set(key, value, expiresAt) {
|
|
63
|
-
db.prepare("INSERT INTO kv (key, value, expires_at) VALUES (?, ?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value, expires_at = excluded.expires_at")
|
|
64
|
-
.run(key, JSON.stringify(value), expiresAt ?? null);
|
|
65
|
-
},
|
|
66
|
-
async delete(key) { return db.prepare("DELETE FROM kv WHERE key = ?").run(key).changes > 0; },
|
|
67
|
-
async has(key) { return db.prepare("SELECT 1 FROM kv WHERE key = ?").get(key) !== undefined; },
|
|
68
|
-
async clear() { db.prepare("DELETE FROM kv").run(); },
|
|
69
|
-
async entries() {
|
|
70
|
-
const rows = db.prepare("SELECT key, value, expires_at FROM kv").all() as Array<{ key: string; value: string; expires_at: number | null }>;
|
|
71
|
-
return rows.map((row) => [row.key, JSON.parse(row.value), row.expiresAt ?? undefined] as [string, unknown, number | undefined]);
|
|
72
|
-
},
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const bot = new Bot({ token: process.env.TELEGRAM_BOT_TOKEN!, session: storage });
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## MongoStorage (bring your own collection)
|
|
79
|
-
|
|
80
|
-
The adapter talks to a standard MongoDB collection shape — pass your collection directly:
|
|
81
|
-
|
|
82
|
-
```ts
|
|
83
|
-
import { Bot, MongoStorage } from "@xbibzlibrary/telebibz";
|
|
84
|
-
import { MongoClient } from "mongodb";
|
|
85
|
-
|
|
86
|
-
const client = new MongoClient(process.env.MONGODB_URL!);
|
|
87
|
-
await client.connect();
|
|
88
|
-
|
|
89
|
-
const bot = new Bot({
|
|
90
|
-
token: process.env.TELEGRAM_BOT_TOKEN!,
|
|
91
|
-
session: new MongoStorage(client.db("mybot").collection("sessions")),
|
|
92
|
-
});
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
## Choosing
|
|
96
|
-
|
|
97
|
-
| Adapter | Use when | Persistence | Extra dependency |
|
|
98
|
-
|---|---|---|---|
|
|
99
|
-
| `MemoryStorage` | single-process bots, tests | process lifetime | none |
|
|
100
|
-
| `JsonFileStorage` | small bots, simple deploys | file on disk | none |
|
|
101
|
-
| `RedisStorage` | multi-instance, shared state | Redis | your Redis client |
|
|
102
|
-
| `SqlStorage` | SQL-backed apps | any SQL database | your SQL driver |
|
|
103
|
-
| `MongoStorage` | existing Mongo stack | MongoDB | your Mongo driver |
|
|
104
|
-
|
|
105
|
-
Full API signatures: [API.md](API.md). Bahasa Indonesia: [STORAGE.id.md](STORAGE.id.md) · 简体中文: [STORAGE.zh-CN.md](STORAGE.zh-CN.md).
|
package/docs/STORAGE.zh-CN.md
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
# 存储快速上手(简体中文)
|
|
2
|
-
|
|
3
|
-
telebibz 提供一个通用的 `Storage<K, V>` 接口和五个适配器。核心包**零运行时依赖**:Redis、SQL 和 Mongo 适配器只要求一个你已经拥有的小型 driver interface,由你自己选择驱动和版本。
|
|
4
|
-
|
|
5
|
-
所有适配器共享同一契约 —— `get` / `set` / `delete` / `has` / `clear` / `keys()` / `entries()` —— 以及 **`update(key, updater, { ttlMs })`**,它按 key 串行化写入,因此对同一 key 的并发更新永远不会交错。TTL 通过 `{ ttlMs }` 按每次写入设置。
|
|
6
|
-
|
|
7
|
-
## MemoryStorage(默认 —— 无需配置)
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
import { Bot } from "@xbibzlibrary/telebibz";
|
|
11
|
-
|
|
12
|
-
const bot = new Bot({ token: process.env.TELEGRAM_BOT_TOKEN! });
|
|
13
|
-
// bot.session 默认就是 MemoryStorage<string, S>。
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
## JsonFileStorage(单文件持久化,依然零依赖)
|
|
17
|
-
|
|
18
|
-
```ts
|
|
19
|
-
import { Bot, JsonFileStorage } from "@xbibzlibrary/telebibz";
|
|
20
|
-
|
|
21
|
-
const bot = new Bot({
|
|
22
|
-
token: process.env.TELEGRAM_BOT_TOKEN!,
|
|
23
|
-
session: new JsonFileStorage("state/sessions.json"),
|
|
24
|
-
});
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## RedisStorage(自带客户端)
|
|
28
|
-
|
|
29
|
-
适配器只需要每个 Redis 客户端都有的五个回调式方法 —— `node-redis` 可以直接使用:
|
|
30
|
-
|
|
31
|
-
```ts
|
|
32
|
-
import { Bot, RedisStorage } from "@xbibzlibrary/telebibz";
|
|
33
|
-
import { createClient } from "redis"; // 由你选择驱动和版本
|
|
34
|
-
|
|
35
|
-
const redis = createClient({ url: process.env.REDIS_URL });
|
|
36
|
-
await redis.connect();
|
|
37
|
-
|
|
38
|
-
const bot = new Bot({
|
|
39
|
-
token: process.env.TELEGRAM_BOT_TOKEN!,
|
|
40
|
-
session: new RedisStorage(redis, "mybot:"), // 你的 key 前缀
|
|
41
|
-
});
|
|
42
|
-
// 按次写入的 TTL:await bot.session.set(key, value, { ttlMs: 24 * 60 * 60 * 1000 });
|
|
43
|
-
// (Redis PX 过期会自动应用。)
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## SqlStorage(任意 SQL 数据库)
|
|
47
|
-
|
|
48
|
-
在你的 SQL 库之上实现这五个方法的 driver;示例使用 `better-sqlite3`:
|
|
49
|
-
|
|
50
|
-
```ts
|
|
51
|
-
import { Bot, SqlStorage } from "@xbibzlibrary/telebibz";
|
|
52
|
-
import Database from "better-sqlite3";
|
|
53
|
-
|
|
54
|
-
const db = new Database("state/bot.db");
|
|
55
|
-
db.exec("CREATE TABLE IF NOT EXISTS kv (key TEXT PRIMARY KEY, value TEXT NOT NULL, expires_at INTEGER)");
|
|
56
|
-
|
|
57
|
-
const storage = new SqlStorage({
|
|
58
|
-
async get(key) {
|
|
59
|
-
const row = db.prepare("SELECT value, expires_at FROM kv WHERE key = ?").get(key) as { value: string; expires_at: number | null } | undefined;
|
|
60
|
-
return row === undefined ? undefined : JSON.parse(row.value);
|
|
61
|
-
},
|
|
62
|
-
async set(key, value, expiresAt) {
|
|
63
|
-
db.prepare("INSERT INTO kv (key, value, expires_at) VALUES (?, ?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value, expires_at = excluded.expires_at")
|
|
64
|
-
.run(key, JSON.stringify(value), expiresAt ?? null);
|
|
65
|
-
},
|
|
66
|
-
async delete(key) { return db.prepare("DELETE FROM kv WHERE key = ?").run(key).changes > 0; },
|
|
67
|
-
async has(key) { return db.prepare("SELECT 1 FROM kv WHERE key = ?").get(key) !== undefined; },
|
|
68
|
-
async clear() { db.prepare("DELETE FROM kv").run(); },
|
|
69
|
-
async entries() {
|
|
70
|
-
const rows = db.prepare("SELECT key, value, expires_at FROM kv").all() as Array<{ key: string; value: string; expires_at: number | null }>;
|
|
71
|
-
return rows.map((row) => [row.key, JSON.parse(row.value), row.expiresAt ?? undefined] as [string, unknown, number | undefined]);
|
|
72
|
-
},
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const bot = new Bot({ token: process.env.TELEGRAM_BOT_TOKEN!, session: storage });
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## MongoStorage(自带 collection)
|
|
79
|
-
|
|
80
|
-
适配器直接对接标准 MongoDB collection 形状 —— 直接传入你的 collection:
|
|
81
|
-
|
|
82
|
-
```ts
|
|
83
|
-
import { Bot, MongoStorage } from "@xbibzlibrary/telebibz";
|
|
84
|
-
import { MongoClient } from "mongodb";
|
|
85
|
-
|
|
86
|
-
const client = new MongoClient(process.env.MONGODB_URL!);
|
|
87
|
-
await client.connect();
|
|
88
|
-
|
|
89
|
-
const bot = new Bot({
|
|
90
|
-
token: process.env.TELEGRAM_BOT_TOKEN!,
|
|
91
|
-
session: new MongoStorage(client.db("mybot").collection("sessions")),
|
|
92
|
-
});
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
## 如何选择
|
|
96
|
-
|
|
97
|
-
| 适配器 | 适用场景 | 持久化 | 额外依赖 |
|
|
98
|
-
|---|---|---|---|
|
|
99
|
-
| `MemoryStorage` | 单进程 bot、测试 | 进程生命周期 | 无 |
|
|
100
|
-
| `JsonFileStorage` | 小型 bot、简单部署 | 磁盘文件 | 无 |
|
|
101
|
-
| `RedisStorage` | 多实例、共享状态 | Redis | 你的 Redis 客户端 |
|
|
102
|
-
| `SqlStorage` | 基于 SQL 的应用 | 任意 SQL 数据库 | 你的 SQL 驱动 |
|
|
103
|
-
| `MongoStorage` | 已有 Mongo 技术栈 | MongoDB | 你的 Mongo 驱动 |
|
|
104
|
-
|
|
105
|
-
完整 API 签名:[API.zh-CN.md](API.zh-CN.md)。English: [STORAGE.md](STORAGE.md) · Bahasa Indonesia: [STORAGE.id.md](STORAGE.id.md)。
|