yaebal 0.0.1 β 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +140 -5
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
π΄
|
|
2
3
|
|
|
3
|
-
yaebal
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
### yaebal
|
|
5
|
+
|
|
6
|
+
*the batteries-included telegram bot framework*
|
|
7
|
+
**one import** Β· **type-safe** Β· **runtime-agnostic**
|
|
8
|
+
|
|
9
|
+
[π docs](https://yaebal.pages.dev) Β· [β github](https://github.com/neverlane/yaebal) Β· [π¦ npmx](https://npmx.dev/org/yaebal)
|
|
10
|
+
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
`yaebal` is the meta package: it bundles the [core engine](https://github.com/neverlane/yaebal/tree/master/packages/core),
|
|
16
|
+
the auto-generated per-update contexts, and the most-used plugins behind a **single import**.
|
|
17
|
+
no wiring, no platform package to pick β `media.path()` just works on node, bun and deno,
|
|
18
|
+
and the same bot runs behind long polling or a webhook on the edge.
|
|
7
19
|
|
|
8
20
|
## install
|
|
9
21
|
|
|
@@ -11,6 +23,129 @@ auto-generated shortcut methods) onto every update via the core context factory.
|
|
|
11
23
|
pnpm add yaebal
|
|
12
24
|
```
|
|
13
25
|
|
|
26
|
+
## quick start
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { Bot, html } from "yaebal";
|
|
30
|
+
|
|
31
|
+
const bot = new Bot(process.env.BOT_TOKEN!)
|
|
32
|
+
.command("start", (ctx) => ctx.send("hi π΄"))
|
|
33
|
+
.on("message:text", (ctx) => ctx.reply(html`you said: <b>${ctx.text}</b>`));
|
|
34
|
+
|
|
35
|
+
await bot.start(); // long polling β or hand updates to a webhook (see below)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`.on("message:text")` narrows the context β inside, `ctx.text` is a `string`, not
|
|
39
|
+
`string | undefined`. every chain method (`command` / `on` / `hears` / `derive` /
|
|
40
|
+
`install` / β¦) flows the context type forward, so plugin-added properties are typed
|
|
41
|
+
with no casting.
|
|
42
|
+
|
|
43
|
+
## rich, typed contexts
|
|
44
|
+
|
|
45
|
+
`createBot` grafts the auto-generated shortcut methods onto every update β `ctx.react`,
|
|
46
|
+
`ctx.editText`, `ctx.pin`, β¦ β typed to the matching update, not just present at runtime.
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { createBot } from "yaebal";
|
|
50
|
+
|
|
51
|
+
const bot = createBot(process.env.BOT_TOKEN!);
|
|
52
|
+
|
|
53
|
+
bot.on("message:text", (ctx) => ctx.react("π₯")); // MessageContext
|
|
54
|
+
bot.on("callback_query:data", (ctx) => ctx.answer("ok")); // CallbackQueryContext
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## what's in the box
|
|
58
|
+
|
|
59
|
+
one `import { β¦ } from "yaebal"` gives you, ready to use:
|
|
60
|
+
|
|
61
|
+
| from | exports | what |
|
|
62
|
+
|:------------------------|:---------------------------------------------------------------|:---------------------------------------|
|
|
63
|
+
| core | `Bot`, `Composer`, `Context`, `media`, `Api` hooks | the engine, filter queries, transports |
|
|
64
|
+
| contexts | `createBot`, the per-update context classes | typed `ctx.react` / `ctx.editText` / β¦ |
|
|
65
|
+
| `@yaebal/keyboard` | `InlineKeyboard`, `Keyboard` | fluent keyboard builders |
|
|
66
|
+
| `@yaebal/callback-data` | `callbackData` | typed `callback_data` pack / unpack |
|
|
67
|
+
| `@yaebal/fmt` | `html`, `md` (+ `*ToEntities`) | tagged templates with auto-escaping |
|
|
68
|
+
| `@yaebal/filters` | `filters`, `and`, `or`, `not` | composable, type-narrowing filters |
|
|
69
|
+
| `@yaebal/session` | `session` | per-chat state, pluggable storage |
|
|
70
|
+
| `@yaebal/i18n` | `i18n` | per-chat locale, `ctx.t` |
|
|
71
|
+
| `@yaebal/web` | `serve`, `webhook`, `setWebhook`, `deleteWebhook` | webhooks on edge/web runtimes |
|
|
72
|
+
|
|
73
|
+
## a quick tour
|
|
74
|
+
|
|
75
|
+
### keyboards + typed callback data
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { InlineKeyboard, callbackData } from "yaebal";
|
|
79
|
+
|
|
80
|
+
const vote = callbackData("vote", { id: Number });
|
|
81
|
+
|
|
82
|
+
bot.command("poll", (ctx) =>
|
|
83
|
+
ctx.send("pick one", {
|
|
84
|
+
reply_markup: new InlineKeyboard()
|
|
85
|
+
.text("π", vote.pack({ id: 1 }))
|
|
86
|
+
.text("π", vote.pack({ id: 2 }))
|
|
87
|
+
.build(),
|
|
88
|
+
}),
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
bot.on("callback_query:data", (ctx) => {
|
|
92
|
+
const data = vote.unpack(ctx.callbackQuery.data);
|
|
93
|
+
if (data) ctx.answer(`voted ${data.id}`);
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### per-chat sessions
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
import { session } from "yaebal";
|
|
101
|
+
|
|
102
|
+
bot.install(session({ initial: () => ({ count: 0 }) }));
|
|
103
|
+
bot.command("count", (ctx) => ctx.reply(`#${++ctx.session.count}`));
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### i18n (internationalization)
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import { i18n } from "yaebal";
|
|
110
|
+
|
|
111
|
+
bot.install(i18n({
|
|
112
|
+
defaultLocale: "en",
|
|
113
|
+
locales: { en: { hi: "hello" }, ru: { hi: "ΠΏΡΠΈΠ²Π΅Ρ" } },
|
|
114
|
+
}));
|
|
115
|
+
bot.command("start", (ctx) => ctx.reply(ctx.t("hi")));
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### media β no platform package
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { media } from "yaebal";
|
|
122
|
+
|
|
123
|
+
bot.command("pic", (ctx) => ctx.sendPhoto(media.path("./cat.jpg"))); // node/bun/deno
|
|
124
|
+
// on edge, send media.url(...) / media.buffer(...) instead
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### run on the edge (webhooks)
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
import { Bot, webhook } from "yaebal";
|
|
131
|
+
|
|
132
|
+
export default {
|
|
133
|
+
fetch(request: Request, env: { BOT_TOKEN: string; SECRET: string }) {
|
|
134
|
+
const bot = new Bot(env.BOT_TOKEN);
|
|
135
|
+
bot.command("start", (ctx) => ctx.reply("running on the edge β‘"));
|
|
136
|
+
|
|
137
|
+
return webhook(bot, { secretToken: env.SECRET })(request);
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## need more?
|
|
143
|
+
|
|
144
|
+
the bundle covers the essentials. everything else is a first-party plugin you add as
|
|
145
|
+
needed β auto-retry, scenes, conversations, routing, broadcast, the operator
|
|
146
|
+
[panel](https://github.com/neverlane/yaebal/tree/master/packages/panel), and more.
|
|
147
|
+
see the [full plugin catalog](https://github.com/neverlane/yaebal#plugins).
|
|
148
|
+
|
|
14
149
|
---
|
|
15
150
|
|
|
16
151
|
part of [**yaebal**](https://github.com/neverlane/yaebal) β a type-safe, runtime-agnostic Telegram Bot API framework. MIT.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yaebal",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "yaebal β batteries-included Telegram Bot API framework: core + auto-generated contexts + the common plugins, one import.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
"src"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@yaebal/core": "0.0.
|
|
19
|
+
"@yaebal/core": "0.0.2",
|
|
20
20
|
"@yaebal/contexts": "0.0.1",
|
|
21
|
-
"@yaebal/keyboard": "0.0.1",
|
|
22
21
|
"@yaebal/filters": "0.0.1",
|
|
22
|
+
"@yaebal/keyboard": "0.0.1",
|
|
23
23
|
"@yaebal/session": "0.0.1",
|
|
24
|
+
"@yaebal/i18n": "0.0.2",
|
|
24
25
|
"@yaebal/callback-data": "0.0.1",
|
|
25
26
|
"@yaebal/fmt": "0.0.1",
|
|
26
|
-
"@yaebal/i18n": "0.0.1",
|
|
27
27
|
"@yaebal/web": "0.0.1"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|