@effect-ak/tg-bot 1.2.4 → 1.3.0
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/dist/index.cjs +396 -3971
- package/dist/index.d.ts +110 -81
- package/dist/index.js +391 -3955
- package/package.json +5 -10
- package/readme.md +34 -465
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect-ak/tg-bot",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Telegram Bot runner",
|
|
6
6
|
"license": "MIT",
|
|
@@ -10,12 +10,9 @@
|
|
|
10
10
|
},
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
13
|
-
"url": "https://github.com/kondaurovDev/tg-bot-
|
|
13
|
+
"url": "https://github.com/kondaurovDev/tg-bot-sdk",
|
|
14
14
|
"directory": "packages/bot"
|
|
15
15
|
},
|
|
16
|
-
"bugs": {
|
|
17
|
-
"url": "https://github.com/effect-ak/tg-bot-client/issues"
|
|
18
|
-
},
|
|
19
16
|
"publishConfig": {
|
|
20
17
|
"access": "public"
|
|
21
18
|
},
|
|
@@ -26,7 +23,8 @@
|
|
|
26
23
|
"types": "./dist/index.d.ts",
|
|
27
24
|
"import": "./dist/index.js",
|
|
28
25
|
"require": "./dist/index.cjs"
|
|
29
|
-
}
|
|
26
|
+
},
|
|
27
|
+
"./dist/*": "./dist/*"
|
|
30
28
|
},
|
|
31
29
|
"files": [
|
|
32
30
|
"dist/*.js",
|
|
@@ -34,12 +32,9 @@
|
|
|
34
32
|
"dist/*.d.ts"
|
|
35
33
|
],
|
|
36
34
|
"dependencies": {
|
|
37
|
-
"@effect-ak/tg-bot-client": "^1.
|
|
35
|
+
"@effect-ak/tg-bot-client": "^1.4.0",
|
|
38
36
|
"@effect-ak/tg-bot-api": "^1.3.0"
|
|
39
37
|
},
|
|
40
|
-
"peerDependencies": {
|
|
41
|
-
"effect": "^3.12.7"
|
|
42
|
-
},
|
|
43
38
|
"scripts": {
|
|
44
39
|
"build": "tsup",
|
|
45
40
|
"typecheck": "tsc"
|
package/readme.md
CHANGED
|
@@ -1,507 +1,76 @@
|
|
|
1
1
|
# @effect-ak/tg-bot
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@effect-ak/tg-bot)
|
|
4
|
-
](https://opensource.org/licenses/MIT)
|
|
4
|
+

|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
## Table of Contents
|
|
10
|
-
|
|
11
|
-
- [Features](#features)
|
|
12
|
-
- [Installation](#installation)
|
|
13
|
-
- [Quick Start](#quick-start)
|
|
14
|
-
- [Core Concepts](#core-concepts)
|
|
15
|
-
- [Single Mode](#single-mode)
|
|
16
|
-
- [Batch Mode](#batch-mode)
|
|
17
|
-
- [Bot Response](#bot-response)
|
|
18
|
-
- [Usage Examples](#usage-examples)
|
|
19
|
-
- [Echo Bot](#echo-bot)
|
|
20
|
-
- [Command Handler](#command-handler)
|
|
21
|
-
- [Batch Processing](#batch-processing)
|
|
22
|
-
- [Using Effect](#using-effectjs)
|
|
23
|
-
- [Hot Reload](#hot-reload)
|
|
24
|
-
- [Configuration](#configuration)
|
|
25
|
-
- [API Reference](#api-reference)
|
|
26
|
-
- [How It Works](#how-it-works)
|
|
27
|
-
- [Error Handling](#error-handling)
|
|
28
|
-
- [Playground](#playground)
|
|
29
|
-
- [Related Packages](#related-packages)
|
|
30
|
-
- [License](#license)
|
|
31
|
-
|
|
32
|
-
## Features
|
|
33
|
-
|
|
34
|
-
- **Effect-based**: Built on top of [Effect](https://effect.website/) for powerful functional programming patterns
|
|
35
|
-
- **Two Processing Modes**: Handle updates one-by-one or in batches
|
|
36
|
-
- **Automatic Long Polling**: Manages connection to Telegram servers
|
|
37
|
-
- **Type-Safe Handlers**: Full TypeScript support for all update types
|
|
38
|
-
- **Error Recovery**: Configurable error handling strategies
|
|
39
|
-
- **Concurrent Processing**: Process multiple updates in parallel (up to 10 concurrent handlers)
|
|
40
|
-
- **Hot Reload**: Reload bot handlers without restarting
|
|
41
|
-
- **Built-in Logging**: Configurable logging levels
|
|
42
|
-
- **No Public URL Required**: Uses pull model - run bots anywhere, even in a browser
|
|
6
|
+
Telegram bot framework with fluent builder API, long polling, webhooks, and hot reload.
|
|
43
7
|
|
|
44
8
|
## Installation
|
|
45
9
|
|
|
46
10
|
```bash
|
|
47
|
-
npm install @effect-ak/tg-bot
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
pnpm add @effect-ak/tg-bot effect
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
yarn add @effect-ak/tg-bot effect
|
|
11
|
+
npm install @effect-ak/tg-bot
|
|
56
12
|
```
|
|
57
13
|
|
|
58
|
-
**Note:** `effect` is a peer dependency and must be installed separately.
|
|
59
|
-
|
|
60
14
|
## Quick Start
|
|
61
15
|
|
|
62
16
|
```typescript
|
|
63
|
-
import {
|
|
17
|
+
import { createBot } from "@effect-ak/tg-bot"
|
|
64
18
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
{
|
|
70
|
-
|
|
71
|
-
handle: ({ update, ctx }) => ctx.reply(`You said: ${update.text}`)
|
|
72
|
-
}
|
|
73
|
-
]
|
|
74
|
-
})
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
## Core Concepts
|
|
78
|
-
|
|
79
|
-
### Single Mode
|
|
80
|
-
|
|
81
|
-
In single mode, the bot processes each update individually with a dedicated handler for each update type.
|
|
82
|
-
|
|
83
|
-
**Handler Format (v2 with guards):**
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
on_message: [
|
|
87
|
-
{
|
|
88
|
-
match: ({ update, ctx }) => ctx.command === "/start", // optional filter
|
|
89
|
-
handle: ({ update, ctx }) => ctx.reply("Welcome!") // handler
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
match: ({ update }) => !!update.text,
|
|
93
|
-
handle: ({ ctx }) => ctx.reply("Got your message!")
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
handle: ({ ctx }) => ctx.ignore // fallback (no match = always runs)
|
|
97
|
-
}
|
|
98
|
-
]
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
**Context helpers:**
|
|
102
|
-
- `ctx.reply(text, options?)` - Send a message
|
|
103
|
-
- `ctx.replyWithDocument(document, options?)` - Send a document
|
|
104
|
-
- `ctx.replyWithPhoto(photo, options?)` - Send a photo
|
|
105
|
-
- `ctx.command` - Parsed command (e.g., "/start", "/help")
|
|
106
|
-
- `ctx.ignore` - Skip response
|
|
19
|
+
const bot = createBot()
|
|
20
|
+
.onMessage(({ command, text, fallback }) => [
|
|
21
|
+
command("/start", ({ ctx }) => ctx.reply("Welcome!")),
|
|
22
|
+
text(({ update, ctx }) => ctx.reply(`You said: ${update.text}`)),
|
|
23
|
+
fallback(({ ctx }) => ctx.reply("Send me a text message"))
|
|
24
|
+
])
|
|
107
25
|
|
|
108
|
-
|
|
109
|
-
- `on_message` - New incoming message
|
|
110
|
-
- `on_edited_message` - Message was edited
|
|
111
|
-
- `on_channel_post` - New channel post
|
|
112
|
-
- `on_edited_channel_post` - Channel post was edited
|
|
113
|
-
- `on_inline_query` - Inline query
|
|
114
|
-
- `on_chosen_inline_result` - Chosen inline result
|
|
115
|
-
- `on_callback_query` - Callback query from inline keyboard
|
|
116
|
-
- `on_shipping_query` - Shipping query
|
|
117
|
-
- `on_pre_checkout_query` - Pre-checkout query
|
|
118
|
-
- `on_poll` - Poll state update
|
|
119
|
-
- `on_poll_answer` - User changed their answer in a poll
|
|
120
|
-
- `on_my_chat_member` - Bot's chat member status changed
|
|
121
|
-
- `on_chat_member` - Chat member status changed
|
|
122
|
-
- `on_chat_join_request` - Request to join chat
|
|
123
|
-
|
|
124
|
-
**Legacy format (v1 - still supported):**
|
|
125
|
-
|
|
126
|
-
```typescript
|
|
127
|
-
on_message: (message) => {
|
|
128
|
-
if (!message.text) return BotResponse.ignore
|
|
129
|
-
return BotResponse.make({ type: "message", text: "Hello!" })
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### Batch Mode
|
|
134
|
-
|
|
135
|
-
In batch mode, the bot receives all updates as an array and processes them together.
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
runTgChatBot({
|
|
139
|
-
bot_token: "YOUR_BOT_TOKEN",
|
|
140
|
-
mode: "batch",
|
|
141
|
-
on_batch: async (updates) => {
|
|
142
|
-
console.log(`Processing ${updates.length} updates`)
|
|
143
|
-
// Process updates...
|
|
144
|
-
return true // Continue polling
|
|
145
|
-
}
|
|
146
|
-
})
|
|
26
|
+
await bot.run({ bot_token: "YOUR_BOT_TOKEN" })
|
|
147
27
|
```
|
|
148
28
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
Handlers return a `BotResponse` object that describes what to send back to the user.
|
|
152
|
-
|
|
153
|
-
**Creating Responses:**
|
|
29
|
+
## Webhook
|
|
154
30
|
|
|
155
31
|
```typescript
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
text: "Hello!"
|
|
162
|
-
})
|
|
32
|
+
const handler = createBot()
|
|
33
|
+
.onMessage(({ command }) => [
|
|
34
|
+
command("/start", ({ ctx }) => ctx.reply("Hello!"))
|
|
35
|
+
])
|
|
36
|
+
.webhook({ bot_token: "YOUR_BOT_TOKEN" })
|
|
163
37
|
|
|
164
|
-
//
|
|
165
|
-
|
|
166
|
-
type: "photo",
|
|
167
|
-
photo: {
|
|
168
|
-
file_content: photoBuffer,
|
|
169
|
-
file_name: "image.jpg"
|
|
170
|
-
},
|
|
171
|
-
caption: "Check this out!"
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
// Ignore update (don't send anything)
|
|
175
|
-
BotResponse.ignore
|
|
38
|
+
// Use as a Request -> Response handler
|
|
39
|
+
export default handler
|
|
176
40
|
```
|
|
177
41
|
|
|
178
|
-
|
|
179
|
-
All Telegram `send_*` methods are supported: `message`, `photo`, `document`, `video`, `audio`, `voice`, `sticker`, `dice`, etc.
|
|
180
|
-
|
|
181
|
-
## Usage Examples
|
|
42
|
+
## Advanced: Low-Level API
|
|
182
43
|
|
|
183
|
-
|
|
44
|
+
For full control without the builder, use `runBot` and `createWebhook` directly:
|
|
184
45
|
|
|
185
46
|
```typescript
|
|
186
|
-
import {
|
|
187
|
-
|
|
188
|
-
const ECHO_BOT = defineBot({
|
|
189
|
-
on_message: [
|
|
190
|
-
{
|
|
191
|
-
match: ({ update }) => !!update.text,
|
|
192
|
-
handle: ({ update, ctx }) => ctx.reply(update.text!)
|
|
193
|
-
}
|
|
194
|
-
]
|
|
195
|
-
})
|
|
47
|
+
import { runBot } from "@effect-ak/tg-bot"
|
|
196
48
|
|
|
197
|
-
|
|
198
|
-
bot_token: "YOUR_BOT_TOKEN",
|
|
199
|
-
mode: "single",
|
|
200
|
-
...ECHO_BOT
|
|
201
|
-
})
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
### Command Handler
|
|
205
|
-
|
|
206
|
-
```typescript
|
|
207
|
-
import { runTgChatBot } from "@effect-ak/tg-bot"
|
|
208
|
-
import { MESSAGE_EFFECTS } from "@effect-ak/tg-bot-client"
|
|
209
|
-
|
|
210
|
-
runTgChatBot({
|
|
211
|
-
bot_token: "YOUR_BOT_TOKEN",
|
|
212
|
-
mode: "single",
|
|
213
|
-
on_message: [
|
|
214
|
-
{
|
|
215
|
-
match: ({ ctx }) => ctx.command === "/start",
|
|
216
|
-
handle: ({ ctx }) => ctx.reply("Welcome! Send me any message.", {
|
|
217
|
-
message_effect_id: MESSAGE_EFFECTS["🎉"]
|
|
218
|
-
})
|
|
219
|
-
},
|
|
220
|
-
{
|
|
221
|
-
match: ({ ctx }) => ctx.command === "/help",
|
|
222
|
-
handle: ({ ctx }) => ctx.reply("Available commands:\n/start - Start bot\n/help - Show help")
|
|
223
|
-
}
|
|
224
|
-
]
|
|
225
|
-
})
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
### Batch Processing
|
|
229
|
-
|
|
230
|
-
```typescript
|
|
231
|
-
import { runTgChatBot } from "@effect-ak/tg-bot"
|
|
232
|
-
import { makeTgBotClient } from "@effect-ak/tg-bot-client"
|
|
233
|
-
|
|
234
|
-
const client = makeTgBotClient({ bot_token: "YOUR_BOT_TOKEN" })
|
|
235
|
-
|
|
236
|
-
runTgChatBot({
|
|
237
|
-
bot_token: "YOUR_BOT_TOKEN",
|
|
238
|
-
mode: "batch",
|
|
239
|
-
poll: {
|
|
240
|
-
batch_size: 100,
|
|
241
|
-
poll_timeout: 60
|
|
242
|
-
},
|
|
243
|
-
on_batch: async (updates) => {
|
|
244
|
-
const messages = updates
|
|
245
|
-
.map(u => u.message)
|
|
246
|
-
.filter(m => m != null)
|
|
247
|
-
|
|
248
|
-
await client.execute("send_message", {
|
|
249
|
-
chat_id: "ADMIN_CHAT_ID",
|
|
250
|
-
text: `Processed ${messages.length} messages`
|
|
251
|
-
})
|
|
252
|
-
|
|
253
|
-
return true // Continue polling
|
|
254
|
-
}
|
|
255
|
-
})
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
### Using Effect
|
|
259
|
-
|
|
260
|
-
Advanced usage with Effect for composable async operations:
|
|
261
|
-
|
|
262
|
-
```typescript
|
|
263
|
-
import { Effect, Micro, pipe } from "effect"
|
|
264
|
-
import { launchBot } from "@effect-ak/tg-bot"
|
|
265
|
-
|
|
266
|
-
Effect.gen(function* () {
|
|
267
|
-
const bot = yield* launchBot({
|
|
268
|
-
bot_token: "YOUR_BOT_TOKEN",
|
|
269
|
-
mode: "single",
|
|
270
|
-
poll: {
|
|
271
|
-
log_level: "debug"
|
|
272
|
-
},
|
|
273
|
-
on_message: [
|
|
274
|
-
{
|
|
275
|
-
match: ({ update }) => !!update.text,
|
|
276
|
-
handle: async ({ ctx }) => {
|
|
277
|
-
await Effect.sleep("2 seconds").pipe(Effect.runPromise)
|
|
278
|
-
return ctx.reply("Delayed response!")
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
]
|
|
282
|
-
})
|
|
283
|
-
|
|
284
|
-
// Access bot fiber for control
|
|
285
|
-
yield* pipe(
|
|
286
|
-
Micro.fiberAwait(bot.fiber()!),
|
|
287
|
-
Effect.andThen(Effect.logInfo("Bot stopped")),
|
|
288
|
-
Effect.forkDaemon
|
|
289
|
-
)
|
|
290
|
-
}).pipe(Effect.runPromise)
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
### Hot Reload
|
|
294
|
-
|
|
295
|
-
```typescript
|
|
296
|
-
import { runTgChatBot } from "@effect-ak/tg-bot"
|
|
297
|
-
|
|
298
|
-
const bot = await runTgChatBot({
|
|
49
|
+
runBot({
|
|
299
50
|
bot_token: "YOUR_BOT_TOKEN",
|
|
300
51
|
mode: "single",
|
|
301
52
|
on_message: [
|
|
302
53
|
{
|
|
303
54
|
match: ({ update }) => !!update.text,
|
|
304
|
-
handle: ({ ctx }) => ctx.reply(
|
|
55
|
+
handle: ({ update, ctx }) => ctx.reply(`You said: ${update.text}`)
|
|
305
56
|
}
|
|
306
57
|
]
|
|
307
58
|
})
|
|
308
|
-
|
|
309
|
-
// Later, reload with new handlers
|
|
310
|
-
setTimeout(() => {
|
|
311
|
-
bot.reload({
|
|
312
|
-
type: "single",
|
|
313
|
-
on_message: [
|
|
314
|
-
{
|
|
315
|
-
match: ({ update }) => !!update.text,
|
|
316
|
-
handle: ({ ctx }) => ctx.reply("Version 2 - Hot reloaded!")
|
|
317
|
-
}
|
|
318
|
-
]
|
|
319
|
-
})
|
|
320
|
-
}, 5000)
|
|
321
59
|
```
|
|
322
60
|
|
|
323
|
-
##
|
|
324
|
-
|
|
325
|
-
### Poll Settings
|
|
326
|
-
|
|
327
|
-
Configure how the bot polls for updates:
|
|
328
|
-
|
|
329
|
-
```typescript
|
|
330
|
-
runTgChatBot({
|
|
331
|
-
bot_token: "YOUR_BOT_TOKEN",
|
|
332
|
-
mode: "single", // or "batch"
|
|
333
|
-
poll: {
|
|
334
|
-
log_level: "debug", // "info" | "debug"
|
|
335
|
-
on_error: "continue", // "stop" | "continue"
|
|
336
|
-
batch_size: 50, // 10-100
|
|
337
|
-
poll_timeout: 30, // 2-120 seconds
|
|
338
|
-
max_empty_responses: 5 // Stop after N empty responses
|
|
339
|
-
},
|
|
340
|
-
on_message: [/* ... */] // handlers at top level
|
|
341
|
-
})
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
**Options:**
|
|
345
|
-
|
|
346
|
-
- `log_level` (default: `"info"`): Logging verbosity
|
|
347
|
-
- `"info"` - Basic logging (new messages, errors)
|
|
348
|
-
- `"debug"` - Detailed logging (all updates, responses)
|
|
349
|
-
|
|
350
|
-
- `on_error` (default: `"stop"`): Error handling strategy
|
|
351
|
-
- `"stop"` - Stop bot on error
|
|
352
|
-
- `"continue"` - Continue polling after errors
|
|
353
|
-
|
|
354
|
-
- `batch_size` (default: `10`): Number of updates to fetch per poll (10-100)
|
|
355
|
-
|
|
356
|
-
- `poll_timeout` (default: `10`): Long polling timeout in seconds (2-120)
|
|
357
|
-
|
|
358
|
-
- `max_empty_responses` (default: `undefined`): Stop after N consecutive empty responses (useful for testing)
|
|
359
|
-
|
|
360
|
-
## API Reference
|
|
361
|
-
|
|
362
|
-
### `runTgChatBot(input)`
|
|
363
|
-
|
|
364
|
-
Starts the bot with long polling.
|
|
365
|
-
|
|
366
|
-
**Parameters:**
|
|
367
|
-
- `bot_token` (string, required): Bot token from @BotFather
|
|
368
|
-
- `mode` (`"single"` | `"batch"`, required): Processing mode
|
|
369
|
-
- `poll` (object, optional): Polling configuration
|
|
370
|
-
- `on_message`, `on_callback_query`, etc. (optional): Update handlers (for single mode)
|
|
371
|
-
- `on_batch` (required for batch mode): Batch handler function
|
|
372
|
-
|
|
373
|
-
**Returns:** `Promise<BotInstance>`
|
|
374
|
-
|
|
375
|
-
### `launchBot(input)`
|
|
376
|
-
|
|
377
|
-
Launches bot and returns a bot instance for advanced control.
|
|
378
|
-
|
|
379
|
-
**Returns:** `Micro<BotInstance>`
|
|
380
|
-
- `BotInstance.reload(mode)` - Hot reload handlers
|
|
381
|
-
- `BotInstance.fiber()` - Access underlying Effect fiber
|
|
382
|
-
|
|
383
|
-
### `defineBot(handlers)`
|
|
384
|
-
|
|
385
|
-
Helper to define bot handlers with type checking and validation.
|
|
386
|
-
|
|
387
|
-
**Parameters:**
|
|
388
|
-
- `handlers` (object): Handler functions for different update types
|
|
389
|
-
|
|
390
|
-
**Returns:** `BotUpdatesHandlers`
|
|
391
|
-
|
|
392
|
-
### `BotResponse.make(response)`
|
|
393
|
-
|
|
394
|
-
Creates a bot response.
|
|
395
|
-
|
|
396
|
-
**Parameters:**
|
|
397
|
-
- `response` (object): Response configuration with `type` and parameters
|
|
398
|
-
|
|
399
|
-
**Returns:** `BotResponse`
|
|
400
|
-
|
|
401
|
-
### `BotResponse.ignore`
|
|
402
|
-
|
|
403
|
-
Singleton instance for ignoring updates (no response).
|
|
404
|
-
|
|
405
|
-
## How It Works
|
|
406
|
-
|
|
407
|
-
### Pull Model Architecture
|
|
408
|
-
|
|
409
|
-
The Telegram bot API supports both **push** and **pull** notification models. This package uses the **pull** model for several key advantages:
|
|
410
|
-
|
|
411
|
-
- **Run bots anywhere without public URLs:** No need to expose public ports or configure webhooks. You can run bots locally, in a browser, or behind firewalls.
|
|
412
|
-
- **Leverage Telegram's infrastructure:** Telegram stores updates for 24 hours, giving you plenty of time to process them.
|
|
413
|
-
- **Simpler deployment:** No SSL certificates, no webhook configuration, no reverse proxies required.
|
|
414
|
-
|
|
415
|
-
### Architecture Diagram
|
|
416
|
-
|
|
417
|
-
```mermaid
|
|
418
|
-
graph TD
|
|
419
|
-
User[User] -->|Sends message| TgBot[Telegram Bot]
|
|
420
|
-
TgBot -->|Stores for 24h| Queue[Updates Queue<br/>api.telegram.org/bot/updates]
|
|
421
|
-
|
|
422
|
-
subgraph Your Code
|
|
423
|
-
Runner[Bot Runner<br/>@effect-ak/tg-bot]
|
|
424
|
-
Handler[Your Handler Function]
|
|
425
|
-
end
|
|
426
|
-
|
|
427
|
-
Runner -->|Long polling| Queue
|
|
428
|
-
Runner -->|Invokes with update| Handler
|
|
429
|
-
Handler -->|Returns BotResponse| Runner
|
|
430
|
-
Runner -->|Sends response| TgBot
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
**How it works:**
|
|
434
|
-
1. User sends a message to your bot
|
|
435
|
-
2. Telegram stores the update in a queue for 24 hours
|
|
436
|
-
3. Bot runner polls the queue using long polling
|
|
437
|
-
4. Runner invokes your handler function with the update
|
|
438
|
-
5. Handler returns a `BotResponse`
|
|
439
|
-
6. Runner sends the response back to Telegram
|
|
440
|
-
7. Runner tracks the last processed update ID to avoid duplicates
|
|
441
|
-
|
|
442
|
-
## Error Handling
|
|
443
|
-
|
|
444
|
-
The bot automatically handles errors at different levels:
|
|
445
|
-
|
|
446
|
-
### Update Handler Errors
|
|
447
|
-
|
|
448
|
-
If a handler throws an error, the bot:
|
|
449
|
-
1. Logs the error with update details
|
|
450
|
-
2. Sends an error message to the user (in single mode)
|
|
451
|
-
3. Continues processing other updates (if `on_error: "continue"`)
|
|
452
|
-
|
|
453
|
-
```typescript
|
|
454
|
-
on_message: [
|
|
455
|
-
{
|
|
456
|
-
match: ({ ctx }) => ctx.command === "/error",
|
|
457
|
-
handle: () => {
|
|
458
|
-
throw new Error("Something went wrong!")
|
|
459
|
-
// Bot will catch this and send error message to user
|
|
460
|
-
}
|
|
461
|
-
},
|
|
462
|
-
{
|
|
463
|
-
match: ({ update }) => !!update.text,
|
|
464
|
-
handle: ({ ctx }) => ctx.reply("OK")
|
|
465
|
-
}
|
|
466
|
-
]
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
### Batch Handler Errors
|
|
470
|
-
|
|
471
|
-
In batch mode, returning `false` stops the bot:
|
|
472
|
-
|
|
473
|
-
```typescript
|
|
474
|
-
on_batch: async (updates) => {
|
|
475
|
-
try {
|
|
476
|
-
// Process updates
|
|
477
|
-
return true // Continue
|
|
478
|
-
} catch (error) {
|
|
479
|
-
console.error(error)
|
|
480
|
-
return false // Stop bot
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
```
|
|
484
|
-
|
|
485
|
-
### Concurrent Processing
|
|
486
|
-
|
|
487
|
-
In single mode, up to 10 updates are processed concurrently. If some handlers fail, others continue processing.
|
|
488
|
-
|
|
489
|
-
## Playground
|
|
490
|
-
|
|
491
|
-
Develop and test your bot directly in the browser:
|
|
492
|
-
|
|
493
|
-
**[Chat Bot Playground](https://effect-ak.github.io/telegram-bot-playground/)**
|
|
494
|
-
|
|
495
|
-
No installation required - perfect for quick prototyping and learning!
|
|
61
|
+
## Features
|
|
496
62
|
|
|
497
|
-
|
|
63
|
+
- **Builder API** — fluent `createBot()` with typed helpers (command, text, photo, etc.)
|
|
64
|
+
- **Two Modes** — single (one-by-one) and batch processing
|
|
65
|
+
- **Polling & Webhooks** — long polling or webhook handler for serverless
|
|
66
|
+
- **Type-Safe Handlers** — all Telegram update types supported
|
|
67
|
+
- **Hot Reload** — update handlers without restarting
|
|
68
|
+
- **Guard Handlers** — match/handle pattern for routing updates
|
|
498
69
|
|
|
499
|
-
|
|
70
|
+
## Documentation
|
|
500
71
|
|
|
501
|
-
|
|
502
|
-
- **[@effect-ak/tg-bot-api](../api)** - TypeScript types for Telegram Bot API and Mini Apps
|
|
503
|
-
- **[@effect-ak/tg-bot-codegen](../codegen)** - Code generator that parses official documentation
|
|
72
|
+
Full documentation, examples, and configuration: **[tg-bot-sdk docs](https://github.com/kondaurovDev/tg-bot-sdk)**
|
|
504
73
|
|
|
505
74
|
## License
|
|
506
75
|
|
|
507
|
-
MIT
|
|
76
|
+
MIT
|