telegix 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,1534 @@
1
+ # โšก Telegix
2
+
3
+ > **lightweight Telegram Bot API framework for Node.js, Bun, Deno, and modern JavaScript runtimes.**
4
+
5
+ [![npm version](https://img.shields.io/npm/v/telegix.svg?style=flat-square)](https://www.npmjs.com/package/telegix)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](LICENSE)
7
+ [![Node.js: >=18](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg?style=flat-square)](https://nodejs.org)
8
+ [![Pure JS](https://img.shields.io/badge/Pure-JavaScript-yellow.svg?style=flat-square)](https://developer.mozilla.org/en-US/docs/Web/JavaScript)
9
+ [![Bot API: 10.3](https://img.shields.io/badge/Telegram_Bot_API-10.3-blue.svg?style=flat-square)](https://core.telegram.org/bots/api)
10
+
11
+ Telegix is a high-performance, developer-friendly Telegram Bot API library built with **100% Pure JavaScript and zero runtime dependencies** beyond native platform APIs (`fetch`, `FormData`, `Blob`). It provides full, first-class support for the latest [Telegram Bot API Specification](https://core.telegram.org/bots/api), including **Bot API 10.3**.
12
+
13
+ ---
14
+
15
+ ## ๐Ÿ“‘ Table of Contents
16
+
17
+ - [๐ŸŒŸ Key Highlights](#-key-highlights)
18
+ - [๐Ÿ“ฆ Installation](#-installation)
19
+ - [๐Ÿš€ Quick Start Guide](#-quick-start-guide)
20
+ - [ECMAScript Modules (ESM)](#ecmascript-modules-esm)
21
+ - [CommonJS (CJS)](#commonjs-cjs)
22
+ - [๐Ÿ›๏ธ Bot Core & Lifecycle](#๏ธ-bot-core--lifecycle)
23
+ - [Initialization & Configuration Options](#initialization--configuration-options)
24
+ - [Fetching Bot Info with getMe()](#fetching-bot-info-with-getme)
25
+ - [Long-Polling Mode](#long-polling-mode)
26
+ - [Webhook Mode (Node.js HTTP, Express, Fastify, Serverless)](#webhook-mode-nodejs-http-express-fastify-serverless)
27
+ - [Multi-Core Cluster Mode](#multi-core-cluster-mode)
28
+ - [Error Handling & bot.catch()](#error-handling--botcatch)
29
+ - [๐Ÿ› ๏ธ Context (`ctx`) Reference & Functions](#๏ธ-context-ctx-reference--functions)
30
+ - [Context Properties & Getters](#context-properties--getters)
31
+ - [Text & HTML / Markdown Replies](#text--html--markdown-replies)
32
+ - [Media Sending Functions (Photos, Audio, Videos, Documents, Albums)](#media-sending-functions-photos-audio-videos-documents-albums)
33
+ - [Interactive Messages (Polls, Locations, Venues, Contacts, Dice, Stickers, Games)](#interactive-messages-polls-locations-venues-contacts-dice-stickers-games)
34
+ - [Message Reactions & Chat Actions](#message-reactions--chat-actions)
35
+ - [Message Editing, Deleting, Forwarding, Copying, & Pinning](#message-editing-deleting-forwarding-copying--pinning)
36
+ - [Chat Administration & Member Moderation](#chat-administration--member-moderation)
37
+ - [Forum Supergroups & Topics Management](#forum-supergroups--topics-management)
38
+ - [Bot API 10.3 Methods (Rich Messages, Drafts, Ephemeral Messages, Managed Access)](#bot-api-103-methods-rich-messages-drafts-ephemeral-messages-managed-access)
39
+ - [๐ŸŽจ Rich Message & Layout Builder Suite (`RichMessage`)](#-rich-message--layout-builder-suite-richmessage)
40
+ - [Fluent Block Builder API](#fluent-block-builder-api)
41
+ - [Static Factory Methods](#static-factory-methods)
42
+ - [Complete Interactive Rich Card Example](#complete-interactive-rich-card-example)
43
+ - [๐Ÿšฆ Composer & Router Engine](#-composer--router-engine)
44
+ - [Event Filtering (`bot.on`)](#event-filtering-boton)
45
+ - [Slash Commands (`bot.command`)](#slash-commands-botcommand)
46
+ - [Text Pattern Matching (`bot.hears`)](#text-pattern-matching-bothears)
47
+ - [Button Callbacks (`bot.action`)](#button-callbacks-botaction)
48
+ - [Specialized Filters (Chat Types, Reactions, Boosts, Business, Forum)](#specialized-filters-chat-types-reactions-boosts-business-forum)
49
+ - [Control Flow (`filter`, `drop`, `branch`)](#control-flow-filter-drop-branch)
50
+ - [๐ŸŽ›๏ธ Fluent Keyboard & Markup Builder (`Markup`)](#๏ธ-fluent-keyboard--markup-builder-markup)
51
+ - [Custom Reply Keyboards](#custom-reply-keyboards)
52
+ - [Inline Keyboards](#inline-keyboards)
53
+ - [Complete Button Builder Reference](#complete-button-builder-reference)
54
+ - [Removing Keyboards & Force Reply](#removing-keyboards--force-reply)
55
+ - [๐Ÿ’ฌ Asynchronous Conversations & Wizard Scenes](#-asynchronous-conversations--wizard-scenes)
56
+ - [Interactive Inline Prompts (`await ctx.prompt`)](#interactive-inline-prompts-await-ctxprompt)
57
+ - [Multi-Step Wizard Scenes (`WizardScene` & `Stage`)](#multi-step-wizard-scenes-wizardscene--stage)
58
+ - [๐Ÿ’พ Session & State Persistence](#-session--state-persistence)
59
+ - [Memory Session Store](#memory-session-store)
60
+ - [File Session Store](#file-session-store)
61
+ - [Custom Store Integration (Redis, MongoDB, PostgreSQL)](#custom-store-integration-redis-mongodb-postgresql)
62
+ - [๐ŸŒ Internationalization & Localization (`I18n`)](#-internationalization--localization-i18n)
63
+ - [โœ’๏ธ Message Formatting (`fmt`, `html`, `mdv2`)](#๏ธ-message-formatting-fmt-html-mdv2)
64
+ - [XSS-Safe HTML Builder (`fmt` & `html`)](#xss-safe-html-builder-fmt--html)
65
+ - [MarkdownV2 Escaping Helpers (`mdv2`)](#markdownv2-escaping-helpers-mdv2)
66
+ - [๐Ÿ’ณ Payments, Invoices & Telegram Stars (`InvoiceBuilder`)](#-payments-invoices--telegram-stars-invoicebuilder)
67
+ - [๐Ÿ“ฑ Telegram Mini Apps / WebApps (`validateWebAppInitData`)](#-telegram-mini-apps--webapps-validatewebappinitdata)
68
+ - [๐Ÿค– Multi-Bot Process Manager (`TelegixManager`)](#-multi-bot-process-manager-telegixmanager)
69
+ - [โšก Advanced Built-in Middlewares](#-advanced-built-in-middlewares)
70
+ - [Rate Limiter Middleware (`rateLimit`)](#rate-limiter-middleware-ratelimit)
71
+ - [Media Group / Album Batching (`albumMiddleware`)](#media-group--album-batching-albummiddleware)
72
+ - [Inline Query Debounce & Cache (`inlineDebounceMiddleware`)](#inline-query-debounce--cache-inlinedebouncemiddleware)
73
+ - [Automatic Chat Action (`chatActionMiddleware`)](#automatic-chat-action-chatactionmiddleware)
74
+ - [Inline Query Pagination (`paginateInlineQuery`)](#inline-query-pagination-paginateinlinequery)
75
+ - [๐Ÿ“š Complete Telegram API Client Method Reference (`bot.telegram` / `bot.api`)](#-complete-telegram-api-client-method-reference-bottelegram--botapi)
76
+ - [๐ŸŸฆ TypeScript Support](#-typescript-support)
77
+ - [๐Ÿงช Running Tests](#-running-tests)
78
+ - [๐Ÿ“„ License](#-license)
79
+
80
+ ---
81
+
82
+ ## ๐ŸŒŸ Key Highlights
83
+
84
+ - **Pure JavaScript & Zero Runtime Dependencies**: Built entirely on native Web standards (`fetch`, `FormData`, `Blob`) with zero binary compilation and zero third-party packages.
85
+ - **Dual Module Architecture**: Full, native compatibility with modern **ESM (`import`)** and **CommonJS (`require`)**.
86
+ - **Complete Telegram Bot API 10.3 Compliance**: Built-in support for message drafts (`sendMessageDraft`, `sendRichMessageDraft`), ephemeral messages (`sendEphemeralMessage`), managed bot access settings (`getManagedBotAccessSettings`, `setManagedBotAccessSettings`), disabled buttons (`Markup.button.disabled`), and Telegram Stars (`XTR`).
87
+ - **Rich Message Builder Suite**: Fluent `RichMessage` API with structured blocks, headers, badges, quotes, code blocks, and automatic HTML fallback compilation.
88
+ - **Seamless Keyboard Normalization**: Pass `Markup.keyboard()` or `Markup.inlineKeyboard()` directly as the 2nd argument to `ctx.reply()` without manual JSON wrapping or extra payloads.
89
+ - **Asynchronous Inline Prompts**: Await user answers step-by-step with `const answer = await ctx.prompt('What is your name?')`.
90
+ - **Multi-Step Wizard Scenes**: Structured conversation flows with `WizardScene` and `Stage` for complex interactive state machines.
91
+ - **Pluggable Session Storage**: Includes `MemorySessionStore`, `FileSessionStore`, and custom adapter support for Redis, MongoDB, or SQL databases.
92
+ - **XSS-Safe Dynamic Formatting**: Tagged template literals with `fmt` and `html` prevent Telegram HTML parsing exceptions and script injection.
93
+ - **Multi-Bot Manager**: Run and orchestrate hundreds of bot tokens simultaneously inside a single Node.js process using `TelegixManager`.
94
+
95
+ ---
96
+
97
+ ## ๐Ÿ“ฆ Installation
98
+
99
+ Install Telegix using your preferred package manager:
100
+
101
+ ```bash
102
+ # Using npm
103
+ npm install telegix
104
+
105
+ # Using pnpm
106
+ pnpm add telegix
107
+
108
+ # Using yarn
109
+ yarn add telegix
110
+
111
+ # Using bun
112
+ bun add telegix
113
+ ```
114
+
115
+ ---
116
+
117
+ ## ๐Ÿš€ Quick Start Guide
118
+
119
+ ### ECMAScript Modules (ESM)
120
+
121
+ Create a file named `bot.mjs` (or set `"type": "module"` in your `package.json`):
122
+
123
+ ```javascript
124
+ import { Telegix, Markup, RichMessage, fmt, html } from 'telegix';
125
+
126
+ const bot = new Telegix(process.env.BOT_TOKEN || 'YOUR_TELEGRAM_BOT_TOKEN');
127
+
128
+ // 1. Slash Command: /start
129
+ bot.command('start', async (ctx) => {
130
+ const name = ctx.from?.first_name || 'there';
131
+ await ctx.reply(
132
+ fmt`Hello, <b>${name}</b>! Welcome to <b>Telegix</b> โšก`,
133
+ { parse_mode: 'HTML' }
134
+ );
135
+ });
136
+
137
+ // 2. Custom Reply Keyboard: /menu
138
+ bot.command('menu', async (ctx) => {
139
+ const replyKeyboard = Markup.keyboard([
140
+ ['โ˜• Coffee', '๐Ÿ• Pizza'],
141
+ ['๐Ÿ“Š Status', 'โš™๏ธ Settings'],
142
+ ]).resize();
143
+
144
+ await ctx.reply('Please choose an option from the keyboard below:', replyKeyboard);
145
+ });
146
+
147
+ // 3. Inline Keyboard & Disabled Button (Bot API 10.3)
148
+ bot.command('order', async (ctx) => {
149
+ const inlineMenu = Markup.inlineKeyboard([
150
+ [
151
+ Markup.button.callback('Margherita ($10)', 'pizza_margherita'),
152
+ Markup.button.callback('Pepperoni ($12)', 'pizza_pepperoni'),
153
+ ],
154
+ [
155
+ Markup.button.url('๐ŸŒ View Full Menu', 'https://example.com/menu'),
156
+ Markup.button.disabled('๐Ÿ”’ Truffle (Sold Out)'),
157
+ ],
158
+ ]);
159
+
160
+ await ctx.reply('Select your pizza:', inlineMenu);
161
+ });
162
+
163
+ // 4. Handle Inline Button Callbacks
164
+ bot.action(/^pizza_(.+)$/, async (ctx) => {
165
+ const selectedPizza = ctx.match[1];
166
+ await ctx.answerCallbackQuery(`Added ${selectedPizza} to your cart!`);
167
+ await ctx.editMessageText(
168
+ `โœ… You selected: <b>${selectedPizza.toUpperCase()}</b>\nThank you for ordering!`,
169
+ { parse_mode: 'HTML' }
170
+ );
171
+ });
172
+
173
+ // 5. Catch-All Text Messages with Reactions
174
+ bot.on('message:text', async (ctx) => {
175
+ await ctx.react('๐Ÿ‘');
176
+ await ctx.reply(`You said: "${ctx.text}"`);
177
+ });
178
+
179
+ // Launch the bot with Long-Polling
180
+ bot.launch().then(() => {
181
+ console.log('๐Ÿค– Bot is online and listening for updates!');
182
+ });
183
+ ```
184
+
185
+ ### CommonJS (CJS)
186
+
187
+ Create a file named `bot.js`:
188
+
189
+ ```javascript
190
+ const { Telegix, Markup } = require('telegix');
191
+
192
+ const bot = new Telegix(process.env.BOT_TOKEN || 'YOUR_TELEGRAM_BOT_TOKEN');
193
+
194
+ bot.command('start', (ctx) => ctx.reply('Hello from Telegix CommonJS!'));
195
+
196
+ bot.launch().then(() => {
197
+ console.log('๐Ÿค– Bot is online!');
198
+ });
199
+ ```
200
+
201
+ ---
202
+
203
+ ## ๐Ÿ›๏ธ Bot Core & Lifecycle
204
+
205
+ ### Initialization & Configuration Options
206
+
207
+ The `Telegix` constructor accepts the bot token as its first parameter and an optional configuration object:
208
+
209
+ ```javascript
210
+ import { Telegix } from 'telegix';
211
+
212
+ const bot = new Telegix('123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11', {
213
+ apiRoot: 'https://api.telegram.org', // Custom Bot API server URL (e.g. self-hosted server)
214
+ testEnv: false, // Connect to Telegram test environment
215
+ timeout: 60000, // Network HTTP request timeout in ms (default: 60000)
216
+ autoRetry: true, // Automatically retry after 429 Too Many Requests (default: true)
217
+ handlerTimeout: 90000, // Timeout in ms for update middleware execution
218
+ polling: {
219
+ timeout: 30, // Long-polling timeout in seconds (default: 30)
220
+ limit: 100, // Maximum updates to retrieve per polling request (default: 100)
221
+ allowedUpdates: [ // List of update types to receive
222
+ 'message',
223
+ 'edited_message',
224
+ 'channel_post',
225
+ 'edited_channel_post',
226
+ 'business_connection',
227
+ 'business_message',
228
+ 'edited_business_message',
229
+ 'deleted_business_messages',
230
+ 'message_reaction',
231
+ 'message_reaction_count',
232
+ 'inline_query',
233
+ 'chosen_inline_result',
234
+ 'callback_query',
235
+ 'shipping_query',
236
+ 'pre_checkout_query',
237
+ 'poll',
238
+ 'poll_answer',
239
+ 'my_chat_member',
240
+ 'chat_member',
241
+ 'chat_join_request',
242
+ 'chat_boost',
243
+ 'removed_chat_boost',
244
+ ],
245
+ },
246
+ });
247
+ ```
248
+
249
+ ### Fetching Bot Info with `getMe()`
250
+
251
+ `getMe()` retrieves basic information about the bot in the form of a Telegram `User` object. You can call it directly on `bot.telegram` or through the `ctx` context inside any update:
252
+
253
+ ```javascript
254
+ // 1. Direct fetch before or outside update handling:
255
+ const botInfo = await bot.telegram.getMe();
256
+ console.log(`Bot Account: @${botInfo.username} (ID: ${botInfo.id})`);
257
+ console.log(`Can join groups: ${botInfo.can_join_groups}`);
258
+ console.log(`Can read all group messages: ${botInfo.can_read_all_group_messages}`);
259
+ console.log(`Supports inline queries: ${botInfo.supports_inline_queries}`);
260
+
261
+ // 2. Fetch inside any middleware or command handler:
262
+ bot.command('whoami', async (ctx) => {
263
+ const me = await ctx.getMe();
264
+ await ctx.reply(
265
+ `๐Ÿค– <b>Bot Details:</b>\n` +
266
+ `โ€ข Name: ${me.first_name}\n` +
267
+ `โ€ข Username: @${me.username}\n` +
268
+ `โ€ข Bot ID: <code>${me.id}</code>`,
269
+ { parse_mode: 'HTML' }
270
+ );
271
+ });
272
+ ```
273
+
274
+ ### Long-Polling Mode
275
+
276
+ Start, monitor, and stop the long-polling lifecycle:
277
+
278
+ ```javascript
279
+ // Launch long-polling
280
+ await bot.launch({
281
+ dropPendingUpdates: true, // Drop updates accumulated while bot was offline
282
+ allowedUpdates: ['message', 'callback_query'],
283
+ });
284
+
285
+ // Manual polling controls
286
+ await bot.startPolling({ timeout: 30 });
287
+
288
+ // Gracefully stop the bot on process termination
289
+ process.once('SIGINT', () => bot.stop('SIGINT'));
290
+ process.once('SIGTERM', () => bot.stop('SIGTERM'));
291
+ ```
292
+
293
+ ### Webhook Mode (Node.js HTTP, Express, Fastify, Serverless)
294
+
295
+ Use `createWebhookCallback()` to create a request handler compatible with all standard Node.js server frameworks:
296
+
297
+ #### Native Node.js `http` / `https`
298
+ ```javascript
299
+ import http from 'node:http';
300
+ import { Telegix, createWebhookCallback } from 'telegix';
301
+
302
+ const bot = new Telegix(process.env.BOT_TOKEN);
303
+ const secretToken = 'my_super_secret_webhook_token';
304
+
305
+ // Set the webhook with Telegram
306
+ await bot.telegram.setWebhook('https://my-domain.com/webhook', {
307
+ secret_token: secretToken,
308
+ });
309
+
310
+ const server = http.createServer(
311
+ createWebhookCallback(bot, {
312
+ path: '/webhook',
313
+ secretToken: secretToken,
314
+ })
315
+ );
316
+
317
+ server.listen(3000, () => {
318
+ console.log('Webhook server running on port 3000');
319
+ });
320
+ ```
321
+
322
+ #### Express.js
323
+ ```javascript
324
+ import express from 'express';
325
+ import { Telegix, createWebhookCallback } from 'telegix';
326
+
327
+ const app = express();
328
+ const bot = new Telegix(process.env.BOT_TOKEN);
329
+
330
+ app.use(express.json());
331
+ app.post('/webhook', createWebhookCallback(bot, { secretToken: process.env.WEBHOOK_SECRET }));
332
+
333
+ app.listen(3000);
334
+ ```
335
+
336
+ ### Multi-Core Cluster Mode
337
+
338
+ Scale your bot horizontally across all CPU cores on a multi-core server:
339
+
340
+ ```javascript
341
+ import { Telegix } from 'telegix';
342
+
343
+ const bot = new Telegix(process.env.BOT_TOKEN);
344
+
345
+ // Spawn a worker for each CPU core automatically
346
+ if (bot.cluster()) {
347
+ // Primary process manages child worker lifecycles
348
+ } else {
349
+ // Worker process handles bot updates
350
+ bot.command('ping', (ctx) => ctx.reply(`Pong from worker ${process.pid}!`));
351
+ bot.launch();
352
+ }
353
+ ```
354
+
355
+ ### Error Handling & `bot.catch()`
356
+
357
+ Catch and handle uncaught errors gracefully across all middlewares:
358
+
359
+ ```javascript
360
+ import { TelegramError } from 'telegix';
361
+
362
+ bot.catch((err, ctx) => {
363
+ console.error(`Error occurred while handling update ${ctx.update.update_id}:`, err);
364
+
365
+ if (err instanceof TelegramError) {
366
+ console.error(`Telegram API Error [${err.errorCode}]: ${err.description}`);
367
+ if (err.parameters?.retry_after) {
368
+ console.warn(`Rate limit retry after: ${err.parameters.retry_after}s`);
369
+ }
370
+ }
371
+
372
+ // Attempt to notify user if possible
373
+ ctx.reply('โš ๏ธ An unexpected error occurred while processing your request.').catch(() => {});
374
+ });
375
+ ```
376
+
377
+ ---
378
+
379
+ ## ๐Ÿ› ๏ธ Context (`ctx`) Reference & Functions
380
+
381
+ Every middleware, command, and event handler receives a `Context` instance (`ctx`) encapsulating the current update and providing dozens of helper methods.
382
+
383
+ ### Context Properties & Getters
384
+
385
+ | Property / Getter | Type | Description |
386
+ |---|---|---|
387
+ | `ctx.update` | `object` | The raw Telegram Update object received from Telegram Bot API. |
388
+ | `ctx.updateType` | `string` | The primary update type (e.g., `'message'`, `'callback_query'`, `'chat_boost'`). |
389
+ | `ctx.updateSubtypes` | `string[]` | Subtype classifications (e.g., `['text']`, `['photo']`, `['pinned_message']`). |
390
+ | `ctx.botInfo` | `object` | The cached `User` object of this bot. |
391
+ | `ctx.telegram` / `ctx.api` | `Telegram` | The low-level Telegram API client instance. |
392
+ | `ctx.state` | `object` | Clean per-update state dictionary to share data between middlewares. |
393
+ | `ctx.session` | `object` | Persistent session object (when `session()` middleware is enabled). |
394
+ | `ctx.message` / `ctx.msg` | `object\|null` | Shortcut to incoming Message (or edited message, channel post, business message). |
395
+ | `ctx.chat` | `object\|null` | The `Chat` object associated with the current update. |
396
+ | `ctx.chatId` | `number\|string` | ID of the current chat. |
397
+ | `ctx.from` | `object\|null` | The `User` object of the sender. |
398
+ | `ctx.userId` | `number` | ID of the sender user. |
399
+ | `ctx.text` | `string\|null` | Text content of the current message. |
400
+ | `ctx.callbackQuery` | `object\|null` | CallbackQuery object if this update is a button callback. |
401
+ | `ctx.inlineQuery` | `object\|null` | InlineQuery object if this update is an inline query. |
402
+ | `ctx.match` | `RegExpMatchArray` | Regex match results when triggered via `bot.hears()` or `bot.action()`. |
403
+ | `ctx.payload` | `string` | Command arguments payload after a slash command (e.g. `/ban 123` -> `'123'`). |
404
+ | `ctx.isForum` | `boolean` | `true` if the current chat is a forum supergroup. |
405
+ | `ctx.topicId` | `number\|null` | Forum thread ID / Message Thread ID if inside a forum topic. |
406
+
407
+ ---
408
+
409
+ ### Text & HTML / Markdown Replies
410
+
411
+ ```javascript
412
+ // Plain text reply
413
+ await ctx.reply('Hello, World!');
414
+
415
+ // HTML formatted reply
416
+ await ctx.replyWithHTML('<b>Bold</b>, <i>Italic</i>, <code>Code</code>, <a href="https://telegix.dev">Link</a>');
417
+
418
+ // Markdown formatted reply
419
+ await ctx.replyWithMarkdown('*Bold text*, _Italic text_, `Code`');
420
+
421
+ // MarkdownV2 formatted reply
422
+ await ctx.replyWithMarkdownV2('*Bold* and _Italic_ and ||Spoiler||');
423
+
424
+ // Reply with additional options and keyboard
425
+ await ctx.reply('Choose an option:', {
426
+ parse_mode: 'HTML',
427
+ reply_to_message_id: ctx.message?.message_id,
428
+ reply_markup: Markup.inlineKeyboard([
429
+ [Markup.button.callback('Option 1', 'opt_1')],
430
+ ]),
431
+ });
432
+ ```
433
+
434
+ ---
435
+
436
+ ### Media Sending Functions (Photos, Audio, Videos, Documents, Albums)
437
+
438
+ ```javascript
439
+ // 1. Send Photo (by URL, File ID, Blob, or Buffer)
440
+ await ctx.replyWithPhoto('https://example.com/image.jpg', {
441
+ caption: '๐ŸŒ… Beautiful sunset in HTML: <b>Nature</b>',
442
+ parse_mode: 'HTML',
443
+ });
444
+
445
+ // 2. Send Audio File
446
+ await ctx.replyWithAudio('https://example.com/song.mp3', {
447
+ title: 'Track Title',
448
+ performer: 'Artist Name',
449
+ caption: '๐ŸŽต Enjoy the music!',
450
+ });
451
+
452
+ // 3. Send Document / File
453
+ await ctx.replyWithDocument('https://example.com/manual.pdf', {
454
+ caption: '๐Ÿ“„ User Manual PDF',
455
+ });
456
+
457
+ // 4. Send Video
458
+ await ctx.replyWithVideo('https://example.com/clip.mp4', {
459
+ caption: '๐ŸŽฌ Video Showcase',
460
+ supports_streaming: true,
461
+ });
462
+
463
+ // 5. Send Animation / GIF
464
+ await ctx.replyWithAnimation('https://example.com/cheers.gif');
465
+
466
+ // 6. Send Voice Note (.ogg audio)
467
+ await ctx.replyWithVoice('https://example.com/voice.ogg');
468
+
469
+ // 7. Send Video Note (Round video message)
470
+ await ctx.replyWithVideoNote('https://example.com/round_video.mp4');
471
+
472
+ // 8. Send Media Group / Photo Album
473
+ await ctx.replyWithMediaGroup([
474
+ { type: 'photo', media: 'https://example.com/photo1.jpg', caption: 'Photo 1' },
475
+ { type: 'photo', media: 'https://example.com/photo2.jpg' },
476
+ { type: 'video', media: 'https://example.com/video1.mp4' },
477
+ ]);
478
+ ```
479
+
480
+ ---
481
+
482
+ ### Interactive Messages (Polls, Locations, Venues, Contacts, Dice, Stickers, Games)
483
+
484
+ ```javascript
485
+ // 1. Send Location (Latitude, Longitude)
486
+ await ctx.replyWithLocation(37.7749, -122.4194);
487
+
488
+ // 2. Send Venue
489
+ await ctx.replyWithVenue(37.7749, -122.4194, 'San Francisco City Hall', '1 Dr Carlton B Goodlett Pl');
490
+
491
+ // 3. Send Contact Card
492
+ await ctx.replyWithContact('+1234567890', 'John', { last_name: 'Doe' });
493
+
494
+ // 4. Send Poll or Quiz
495
+ await ctx.replyWithPoll(
496
+ 'Which database do you prefer?',
497
+ ['PostgreSQL', 'Redis', 'MongoDB', 'SQLite'],
498
+ {
499
+ is_anonymous: false,
500
+ allows_multiple_answers: true,
501
+ }
502
+ );
503
+
504
+ // 5. Send Animated Dice (๐ŸŽฒ, ๐ŸŽฏ, ๐Ÿ€, โšฝ, ๐ŸŽฐ, ๐ŸŽณ)
505
+ await ctx.replyWithDice({ emoji: '๐ŸŽฏ' });
506
+
507
+ // 6. Send Sticker
508
+ await ctx.replyWithSticker('CAACAgIAAxkBAAE...');
509
+
510
+ // 7. Send Telegram Game
511
+ await ctx.replyWithGame('my_telegix_game');
512
+
513
+ // 8. Send Paid Media (Telegram Stars)
514
+ await ctx.replyWithPaidMedia(25, [
515
+ { type: 'photo', media: 'https://example.com/exclusive_art.jpg' }
516
+ ]);
517
+ ```
518
+
519
+ ---
520
+
521
+ ### Message Reactions & Chat Actions
522
+
523
+ ```javascript
524
+ // Add an emoji reaction to the current message
525
+ await ctx.react('โค๏ธ');
526
+ await ctx.react('๐Ÿ”ฅ');
527
+
528
+ // Send chat action indicators ('typing', 'upload_photo', 'record_video', 'upload_document', etc.)
529
+ await ctx.replyWithChatAction('typing');
530
+ await ctx.replyWithChatAction('upload_document');
531
+ ```
532
+
533
+ ---
534
+
535
+ ### Message Editing, Deleting, Forwarding, Copying, & Pinning
536
+
537
+ ```javascript
538
+ // 1. Edit current message text
539
+ await ctx.editMessageText('Updated text content', { parse_mode: 'HTML' });
540
+
541
+ // 2. Edit current message caption
542
+ await ctx.editMessageCaption('Updated media caption');
543
+
544
+ // 3. Edit current message reply markup
545
+ await ctx.editMessageReplyMarkup(
546
+ Markup.inlineKeyboard([[Markup.button.callback('New Option', 'opt_new')]])
547
+ );
548
+
549
+ // 4. Delete messages
550
+ await ctx.deleteMessage(); // Deletes current incoming message
551
+ await ctx.deleteMessage(targetMessageId);
552
+ await ctx.deleteMessages([msgId1, msgId2, msgId3]);
553
+
554
+ // 5. Forward or Copy messages to another chat
555
+ await ctx.forwardMessage(targetChatId);
556
+ await ctx.copyMessage(targetChatId);
557
+
558
+ // 6. Pin / Unpin messages
559
+ await ctx.pinChatMessage();
560
+ await ctx.unpinChatMessage();
561
+ await ctx.unpinAllChatMessages();
562
+
563
+ // 7. Answer Callback Query
564
+ await ctx.answerCallbackQuery('Action confirmed!', { show_alert: false });
565
+ ```
566
+
567
+ ---
568
+
569
+ ### Chat Administration & Member Moderation
570
+
571
+ ```javascript
572
+ // Get Chat Details & Administrators
573
+ const chat = await ctx.getChat();
574
+ const admins = await ctx.getChatAdministrators();
575
+
576
+ // Get Member Info & Total Member Count
577
+ const member = await ctx.getChatMember(targetUserId);
578
+ const count = await ctx.getChatMembersCount();
579
+
580
+ // Ban / Kick Member
581
+ await ctx.banChatMember(targetUserId, {
582
+ until_date: Math.floor(Date.now() / 1000) + 86400, // 24 hours ban
583
+ revoke_messages: true,
584
+ });
585
+
586
+ // Unban Member
587
+ await ctx.unbanChatMember(targetUserId, { only_if_banned: true });
588
+
589
+ // Restrict Permissions
590
+ await ctx.restrictChatMember(targetUserId, {
591
+ can_send_messages: false,
592
+ can_send_media_messages: false,
593
+ can_send_other_messages: false,
594
+ can_add_web_page_previews: false,
595
+ });
596
+
597
+ // Promote Member to Administrator
598
+ await ctx.promoteChatMember(targetUserId, {
599
+ can_change_info: true,
600
+ can_delete_messages: true,
601
+ can_invite_users: true,
602
+ can_pin_messages: true,
603
+ });
604
+
605
+ // Manage Chat Info
606
+ await ctx.setChatTitle('New Group Title');
607
+ await ctx.setChatDescription('Updated group description.');
608
+ await ctx.leaveChat();
609
+ ```
610
+
611
+ ---
612
+
613
+ ### Forum Supergroups & Topics Management
614
+
615
+ ```javascript
616
+ // Check if the current chat is a forum supergroup
617
+ if (ctx.isForum) {
618
+ console.log('Current forum thread ID:', ctx.topicId);
619
+ }
620
+
621
+ // Create a new topic in a forum supergroup
622
+ const topic = await ctx.createForumTopic('๐Ÿš€ Development Updates', {
623
+ icon_color: 0x6FB9F0,
624
+ icon_custom_emoji_id: '5312345678901234567',
625
+ });
626
+
627
+ // Edit, Close, Reopen, or Delete Topics
628
+ await ctx.editForumTopic(ctx.topicId, { name: '๐Ÿ“ Archived Updates' });
629
+ await ctx.closeForumTopic(ctx.topicId);
630
+ await ctx.reopenForumTopic(ctx.topicId);
631
+ await ctx.deleteForumTopic(ctx.topicId);
632
+ await ctx.unpinAllForumTopicMessages(ctx.topicId);
633
+ ```
634
+
635
+ ---
636
+
637
+ ### Bot API 10.3 Methods (Rich Messages, Drafts, Ephemeral Messages, Managed Access)
638
+
639
+ ```javascript
640
+ import { RichMessage, Markup } from 'telegix';
641
+
642
+ // 1. Send Rich Message (structured layout blocks with automatic fallback)
643
+ const card = RichMessage.card('โšก Server Health Check', 'All systems operational.')
644
+ .header('Cluster Status', '๐ŸŸข')
645
+ .badge('CPU Load', '14%')
646
+ .badge('Memory', '1.2 GB / 8.0 GB')
647
+ .list(['Node 1: Online', 'Node 2: Online', 'Node 3: Standby'])
648
+ .expandableQuote('Rich messages provide structured block layouts.')
649
+ .row(
650
+ Markup.button.callback('๐Ÿ”„ Refresh', 'refresh_stats'),
651
+ Markup.button.disabled('๐Ÿ”’ Advanced Tuning')
652
+ );
653
+
654
+ await ctx.replyWithRichMessage(card);
655
+
656
+ // 2. Edit existing message with Rich Message
657
+ await ctx.editRichMessageText(card);
658
+
659
+ // 3. Send Rich Message Draft
660
+ await ctx.sendRichMessageDraft(card);
661
+
662
+ // 4. Send Message Draft (Real-time draft displayed directly in user client)
663
+ await ctx.sendMessageDraft('Bot is currently preparing your report...');
664
+
665
+ // 5. Send Ephemeral Message (Message with automated lifetime)
666
+ await ctx.sendEphemeralMessage('This message will automatically vanish in 15 seconds.', 15);
667
+
668
+ // 6. Managed Bot Access Settings (Bot API 10.3)
669
+ const accessSettings = await ctx.getManagedBotAccessSettings(adminUserId);
670
+ await ctx.setManagedBotAccessSettings({ allow_admin_override: true }, adminUserId);
671
+
672
+ // 7. Get User Personal Chat Messages
673
+ const messages = await ctx.getUserPersonalChatMessages(targetUserId);
674
+ ```
675
+
676
+ ---
677
+
678
+ ## ๐ŸŽจ Rich Message & Layout Builder Suite (`RichMessage`)
679
+
680
+ The `RichMessage` class allows you to construct modern, structured card layouts, dashboards, and rich messages using a fluent chaining syntax.
681
+
682
+ ### Fluent Block Builder API
683
+
684
+ | Builder Method | Description |
685
+ |---|---|
686
+ | `.header(text, emoji?)` | Adds a prominent header block with an optional leading emoji. |
687
+ | `.paragraph(text)` | Adds a body paragraph block. |
688
+ | `.bold(text)` / `.italic(text)` | Adds bold or italic styled text blocks. |
689
+ | `.underline(text)` / `.strikethrough(text)` | Adds underlined or struck-through text blocks. |
690
+ | `.code(codeText, language?)` | Adds inline or syntax-highlighted multiline code blocks. |
691
+ | `.quote(text, expandable?)` | Adds a standard or expandable Telegram blockquote. |
692
+ | `.expandableQuote(text)` | Shortcut to add an expandable blockquote. |
693
+ | `.spoiler(text)` | Adds tap-to-reveal spoiler formatted text. |
694
+ | `.link(text, url)` | Adds a formatted hyperlink. |
695
+ | `.mention(text, userId)` | Adds an inline mention link for a Telegram user ID. |
696
+ | `.list(items, bullet?)` | Formats an array of strings into a bulleted list. |
697
+ | `.numberedList(items)` | Formats an array of strings into a numbered list (1., 2., 3.). |
698
+ | `.badge(label, value, icon?)` | Adds a key-value metric badge item. |
699
+ | `.divider()` | Inserts a clean visual separator line. |
700
+ | `.row(...buttons)` | Appends a row of inline keyboard buttons. |
701
+ | `.callback(text, data)` | Appends an inline callback query button. |
702
+ | `.url(text, url)` | Appends an external URL link button. |
703
+ | `.disabled(text)` | Appends a non-clickable disabled button (Bot API 10.3). |
704
+ | `.ephemeral(seconds)` | Sets message lifetime parameter for auto-expiration. |
705
+ | `.draftId(id?)` / `.asDraft()` | Configures the rich message as a real-time message draft. |
706
+ | `.compile()` / `.build()` | Compiles all blocks into a Telegram-ready payload object. |
707
+ | `.send(ctx)` | Sends the rich message using the active context. |
708
+ | `.edit(ctx)` | Edits an existing message with this rich message. |
709
+
710
+ ### Static Factory Methods
711
+
712
+ ```javascript
713
+ import { RichMessage } from 'telegix';
714
+
715
+ // Create a blank builder
716
+ const msg = RichMessage.create('Optional initial text');
717
+
718
+ // Create a pre-structured Card
719
+ const card = RichMessage.card('Card Title', 'Card Description', [
720
+ Markup.button.callback('Click Me', 'btn_1'),
721
+ ]);
722
+
723
+ // Create a Draft Message
724
+ const draft = RichMessage.draft('Drafting text...', 12345);
725
+
726
+ // Create an Ephemeral Message
727
+ const expiring = RichMessage.ephemeral('Expiring note', 30);
728
+ ```
729
+
730
+ ### Complete Interactive Rich Card Example
731
+
732
+ ```javascript
733
+ import { Telegix, Markup, RichMessage } from 'telegix';
734
+
735
+ const bot = new Telegix(process.env.BOT_TOKEN);
736
+
737
+ bot.command('dashboard', async (ctx) => {
738
+ const dashboard = RichMessage.card('โšก Infrastructure Dashboard', 'Live metrics from production cluster:')
739
+ .header('Cluster Status', '๐ŸŸข')
740
+ .badge('CPU Utilization', '28.4%', '๐Ÿ’ป')
741
+ .badge('RAM Usage', '3.8 GB / 16.0 GB', '๐Ÿง ')
742
+ .badge('Active Connections', '1,420', '๐ŸŒ')
743
+ .badge('Error Rate', '0.002%', '๐Ÿ›ก๏ธ')
744
+ .divider()
745
+ .header('Active Worker Nodes', '๐Ÿ–ฅ๏ธ')
746
+ .list([
747
+ 'worker-ap-southeast-1a: Healthy (0.12 load)',
748
+ 'worker-ap-southeast-1b: Healthy (0.15 load)',
749
+ 'worker-ap-southeast-1c: Standby',
750
+ ])
751
+ .divider()
752
+ .expandableQuote('Auto-scaling policy is currently enabled. Additional instances will spawn if CPU exceeds 75%.')
753
+ .code('curl -s https://api.cluster.internal/v1/health | jq', 'bash')
754
+ .row(
755
+ Markup.button.callback('๐Ÿ”„ Refresh Data', 'refresh_metrics'),
756
+ Markup.button.url('๐Ÿ“ˆ Grafana', 'https://grafana.example.com')
757
+ )
758
+ .row(
759
+ Markup.button.disabled('๐Ÿ”’ Deploy Patch (Admin Only)')
760
+ );
761
+
762
+ await ctx.replyWithRichMessage(dashboard);
763
+ });
764
+ ```
765
+
766
+ ---
767
+
768
+ ## ๐Ÿšฆ Composer & Router Engine
769
+
770
+ `Composer` powers the routing and middleware pipeline in Telegix.
771
+
772
+ ### Event Filtering (`bot.on`)
773
+
774
+ Filter and intercept incoming updates by type and subtype:
775
+
776
+ ```javascript
777
+ // Text messages
778
+ bot.on('message:text', async (ctx) => { ... });
779
+
780
+ // Photos, Audios, Documents, Videos
781
+ bot.on('message:photo', async (ctx) => { ... });
782
+ bot.on('message:audio', async (ctx) => { ... });
783
+ bot.on('message:document', async (ctx) => { ... });
784
+ bot.on('message:video', async (ctx) => { ... });
785
+
786
+ // Service messages
787
+ bot.on('message:new_chat_members', async (ctx) => { ... });
788
+ bot.on('message:left_chat_member', async (ctx) => { ... });
789
+ bot.on('message:pinned_message', async (ctx) => { ... });
790
+
791
+ // Channel Posts
792
+ bot.on('channel_post:text', async (ctx) => { ... });
793
+
794
+ // Inline Queries & Results
795
+ bot.on('inline_query', async (ctx) => { ... });
796
+ bot.on('chosen_inline_result', async (ctx) => { ... });
797
+
798
+ // Reactions & Boosts
799
+ bot.on('message_reaction', async (ctx) => { ... });
800
+ bot.on('chat_boost', async (ctx) => { ... });
801
+
802
+ // Listen to multiple event types at once
803
+ bot.on(['message:voice', 'message:video_note'], async (ctx) => { ... });
804
+ ```
805
+
806
+ ---
807
+
808
+ ### Slash Commands (`bot.command`)
809
+
810
+ Handles slash commands and parses command arguments into `ctx.payload`:
811
+
812
+ ```javascript
813
+ // Matches /start
814
+ bot.command('start', async (ctx) => {
815
+ await ctx.reply('Welcome!');
816
+ });
817
+
818
+ // Matches /ban <userId> <reason>
819
+ bot.command('ban', async (ctx) => {
820
+ const [targetId, ...reasonParts] = ctx.payload.split(' ');
821
+ const reason = reasonParts.join(' ');
822
+ await ctx.reply(`Banning user ${targetId} for reason: ${reason}`);
823
+ });
824
+
825
+ // Matches multiple commands simultaneously
826
+ bot.command(['help', 'info', 'guide'], async (ctx) => {
827
+ await ctx.reply('Help documentation...');
828
+ });
829
+ ```
830
+
831
+ ---
832
+
833
+ ### Text Pattern Matching (`bot.hears`)
834
+
835
+ Match message text or captions against static strings or Regular Expressions:
836
+
837
+ ```javascript
838
+ // Static string matching
839
+ bot.hears('hi', async (ctx) => ctx.reply('Hello there!'));
840
+
841
+ // Regular expression matching with capture groups
842
+ bot.hears(/^echo (.+)$/i, async (ctx) => {
843
+ const capturedText = ctx.match[1];
844
+ await ctx.reply(`Echo: ${capturedText}`);
845
+ });
846
+
847
+ // Match multiple phrases
848
+ bot.hears(['help', 'support', 'contact'], async (ctx) => {
849
+ await ctx.reply('Please email support@example.com for assistance.');
850
+ });
851
+ ```
852
+
853
+ ---
854
+
855
+ ### Button Callbacks (`bot.action`)
856
+
857
+ Handle inline button callback queries with exact strings or regex matching:
858
+
859
+ ```javascript
860
+ // Exact match
861
+ bot.action('confirm_delete', async (ctx) => {
862
+ await ctx.answerCallbackQuery('Item deleted!');
863
+ await ctx.deleteMessage();
864
+ });
865
+
866
+ // Regex match with parameter extraction
867
+ bot.action(/^user:(\d+):action:(ban|kick|warn)$/, async (ctx) => {
868
+ const userId = ctx.match[1];
869
+ const action = ctx.match[2];
870
+ await ctx.answerCallbackQuery(`Executed ${action} on user ${userId}`);
871
+ });
872
+ ```
873
+
874
+ ---
875
+
876
+ ### Specialized Filters (Chat Types, Reactions, Boosts, Business, Forum)
877
+
878
+ ```javascript
879
+ import { Composer } from 'telegix';
880
+
881
+ // Filter by Chat Type: 'private', 'group', 'supergroup', 'channel'
882
+ bot.use(Composer.chatType('private', async (ctx, next) => {
883
+ console.log('Update came from a private DM!');
884
+ return next();
885
+ }));
886
+
887
+ // Filter by Message Reactions
888
+ bot.use(Composer.reaction(async (ctx, next) => {
889
+ console.log('User reacted with:', ctx.messageReaction.new_reaction);
890
+ return next();
891
+ }));
892
+
893
+ // Filter by Telegram Business Connection
894
+ bot.use(Composer.business(async (ctx, next) => {
895
+ console.log('Business message received');
896
+ return next();
897
+ }));
898
+
899
+ // Filter Forum Supergroups
900
+ bot.use(Composer.forum(async (ctx, next) => {
901
+ console.log('Forum topic message received');
902
+ return next();
903
+ }));
904
+ ```
905
+
906
+ ---
907
+
908
+ ## ๐ŸŽ›๏ธ Fluent Keyboard & Markup Builder (`Markup`)
909
+
910
+ Construct reply and inline keyboards cleanly with `Markup`.
911
+
912
+ ### Custom Reply Keyboards
913
+
914
+ ```javascript
915
+ import { Markup } from 'telegix';
916
+
917
+ // Create a customized reply keyboard
918
+ const keyboard = Markup.keyboard([
919
+ ['๐Ÿ›’ Shop', '๐Ÿ“ฆ Orders'],
920
+ ['๐Ÿ“ž Support', 'โš™๏ธ Settings'],
921
+ ])
922
+ .resize() // Compact button sizes
923
+ .oneTime() // Hide keyboard after first selection
924
+ .placeholder('Select an option...')
925
+ .selective(); // Show only to specific mentioned users
926
+
927
+ await ctx.reply('Main Menu:', keyboard);
928
+ ```
929
+
930
+ ---
931
+
932
+ ### Inline Keyboards
933
+
934
+ ```javascript
935
+ const inline = Markup.inlineKeyboard([
936
+ [
937
+ Markup.button.callback('๐Ÿ‘ Like', 'action_like'),
938
+ Markup.button.callback('๐Ÿ‘Ž Dislike', 'action_dislike'),
939
+ ],
940
+ [
941
+ Markup.button.url('๐ŸŒ Visit Website', 'https://telegix.dev'),
942
+ Markup.button.copyText('๐Ÿ“‹ Copy Code', 'TELE-2026'),
943
+ ],
944
+ [
945
+ Markup.button.webApp('๐Ÿš€ Launch Mini App', 'https://miniapp.example.com'),
946
+ ],
947
+ ]);
948
+
949
+ await ctx.reply('Interactive Post:', inline);
950
+ ```
951
+
952
+ ---
953
+
954
+ ### Complete Button Builder Reference
955
+
956
+ | Button Builder Method | Description |
957
+ |---|---|
958
+ | `Markup.button.text(text)` | Standard reply keyboard text button. |
959
+ | `Markup.button.callback(text, data)` | Inline button triggering a callback query with `data`. |
960
+ | `Markup.button.url(text, url)` | Inline button opening an external URL. |
961
+ | `Markup.button.webApp(text, url)` | Button launching a Telegram Mini App. |
962
+ | `Markup.button.copyText(text, textToCopy)` | Inline button that copies `textToCopy` to the clipboard. |
963
+ | `Markup.button.disabled(text)` | Disabled, non-clickable button (**Bot API 10.3**). |
964
+ | `Markup.button.login(text, url, options?)` | Telegram Login URL authorization button. |
965
+ | `Markup.button.switchToChat(text, query)` | Inline button switching to chat with inline query. |
966
+ | `Markup.button.switchToCurrentChat(text, query)` | Inline button opening current chat with inline query. |
967
+ | `Markup.button.pay(text)` | Payment invoice button. |
968
+ | `Markup.button.contactRequest(text)` | Reply button requesting the user's phone number. |
969
+ | `Markup.button.locationRequest(text)` | Reply button requesting the user's GPS location. |
970
+ | `Markup.button.pollRequest(text, type?)` | Reply button requesting user to create a poll or quiz. |
971
+ | `Markup.button.userRequest(text, reqId, options?)` | Reply button requesting user selection. |
972
+ | `Markup.button.botRequest(text, reqId, options?)` | Reply button requesting bot selection. |
973
+ | `Markup.button.groupRequest(text, reqId, options?)` | Reply button requesting group chat selection. |
974
+ | `Markup.button.channelRequest(text, reqId, options?)` | Reply button requesting channel selection. |
975
+
976
+ ---
977
+
978
+ ### Removing Keyboards & Force Reply
979
+
980
+ ```javascript
981
+ // Remove custom reply keyboard
982
+ await ctx.reply('Keyboard removed.', Markup.removeKeyboard());
983
+
984
+ // Force user to reply to this message
985
+ await ctx.reply('Please enter your email address:', Markup.forceReply());
986
+ ```
987
+
988
+ ---
989
+
990
+ ## ๐Ÿ’ฌ Asynchronous Conversations & Wizard Scenes
991
+
992
+ ### Interactive Inline Prompts (`await ctx.prompt`)
993
+
994
+ Ask sequential questions and await answers asynchronously directly inside your code:
995
+
996
+ ```javascript
997
+ import { Telegix, promptMiddleware } from 'telegix';
998
+
999
+ const bot = new Telegix(process.env.BOT_TOKEN);
1000
+ bot.use(promptMiddleware());
1001
+
1002
+ bot.command('register', async (ctx) => {
1003
+ // Step 1: Ask Name
1004
+ const name = await ctx.prompt('What is your full name?');
1005
+
1006
+ // Step 2: Ask Age
1007
+ const age = await ctx.prompt(`Nice to meet you, ${name}! How old are you?`, {
1008
+ timeoutMs: 30000, // 30 seconds timeout
1009
+ });
1010
+
1011
+ // Step 3: Confirmation
1012
+ await ctx.reply(`๐ŸŽ‰ Registration complete!\nName: ${name}\nAge: ${age}`);
1013
+ });
1014
+ ```
1015
+
1016
+ ---
1017
+
1018
+ ### Multi-Step Wizard Scenes (`WizardScene` & `Stage`)
1019
+
1020
+ Build complex, multi-step conversation wizards with state tracking:
1021
+
1022
+ ```javascript
1023
+ import { Telegix, WizardScene, Stage, session, Markup } from 'telegix';
1024
+
1025
+ // 1. Define Wizard Scene
1026
+ const orderWizard = new WizardScene(
1027
+ 'pizza_order_wizard',
1028
+ // Step 1: Select Flavor
1029
+ async (ctx) => {
1030
+ await ctx.reply(
1031
+ '๐Ÿ• Step 1: Choose your pizza flavor:',
1032
+ Markup.keyboard([['Margherita', 'Pepperoni'], ['Hawaiian', 'BBQ Chicken']]).resize()
1033
+ );
1034
+ return ctx.wizard.next();
1035
+ },
1036
+ // Step 2: Select Size
1037
+ async (ctx) => {
1038
+ ctx.wizard.state.flavor = ctx.message.text;
1039
+ await ctx.reply(
1040
+ `Selected: ${ctx.wizard.state.flavor}\nStep 2: Choose size:`,
1041
+ Markup.keyboard([['Small', 'Medium', 'Large']]).resize()
1042
+ );
1043
+ return ctx.wizard.next();
1044
+ },
1045
+ // Step 3: Confirm & Finish
1046
+ async (ctx) => {
1047
+ ctx.wizard.state.size = ctx.message.text;
1048
+ await ctx.reply(
1049
+ `โœ… Order Summary:\nโ€ข Flavor: ${ctx.wizard.state.flavor}\nโ€ข Size: ${ctx.wizard.state.size}\nThank you!`,
1050
+ Markup.removeKeyboard()
1051
+ );
1052
+ return ctx.scene.leave();
1053
+ }
1054
+ );
1055
+
1056
+ // 2. Setup Stage
1057
+ const stage = new Stage([orderWizard]);
1058
+
1059
+ const bot = new Telegix(process.env.BOT_TOKEN);
1060
+ bot.use(session());
1061
+ bot.use(stage.middleware());
1062
+
1063
+ bot.command('order', (ctx) => ctx.scene.enter('pizza_order_wizard'));
1064
+ ```
1065
+
1066
+ ---
1067
+
1068
+ ## ๐Ÿ’พ Session & State Persistence
1069
+
1070
+ Store per-user or per-chat state that survives across multiple messages.
1071
+
1072
+ ### Memory Session Store
1073
+
1074
+ ```javascript
1075
+ import { Telegix, session, MemorySessionStore } from 'telegix';
1076
+
1077
+ const bot = new Telegix(process.env.BOT_TOKEN);
1078
+
1079
+ bot.use(session({
1080
+ store: new MemorySessionStore({ ttlMs: 86400000 }), // 24 hours TTL
1081
+ initial: () => ({ count: 0 }),
1082
+ }));
1083
+
1084
+ bot.command('counter', async (ctx) => {
1085
+ ctx.session.count += 1;
1086
+ await ctx.reply(`You have invoked this command ${ctx.session.count} times!`);
1087
+ });
1088
+ ```
1089
+
1090
+ ---
1091
+
1092
+ ### File Session Store
1093
+
1094
+ Persist user states to local disk JSON automatically:
1095
+
1096
+ ```javascript
1097
+ import { Telegix, session, FileSessionStore } from 'telegix';
1098
+
1099
+ bot.use(session({
1100
+ store: new FileSessionStore({ filePath: './data/sessions.json' }),
1101
+ initial: () => ({ favorites: [] }),
1102
+ }));
1103
+ ```
1104
+
1105
+ ---
1106
+
1107
+ ### Custom Store Integration (Redis, MongoDB, PostgreSQL)
1108
+
1109
+ Provide your own storage engine with `get`, `set`, and `delete` methods:
1110
+
1111
+ ```javascript
1112
+ import { session } from 'telegix';
1113
+ import Redis from 'ioredis';
1114
+
1115
+ const redis = new Redis();
1116
+
1117
+ const redisStore = {
1118
+ async get(key) {
1119
+ const data = await redis.get(`session:${key}`);
1120
+ return data ? JSON.parse(data) : undefined;
1121
+ },
1122
+ async set(key, value, ttlMs) {
1123
+ if (ttlMs) {
1124
+ await redis.set(`session:${key}`, JSON.stringify(value), 'PX', ttlMs);
1125
+ } else {
1126
+ await redis.set(`session:${key}`, JSON.stringify(value));
1127
+ }
1128
+ },
1129
+ async delete(key) {
1130
+ await redis.del(`session:${key}`);
1131
+ },
1132
+ };
1133
+
1134
+ bot.use(session({ store: redisStore }));
1135
+ ```
1136
+
1137
+ ---
1138
+
1139
+ ## ๐ŸŒ Internationalization & Localization (`I18n`)
1140
+
1141
+ Built-in internationalization supporting variable interpolation (`{{name}}`), nested paths (`menu.profile`), and pluralization rules:
1142
+
1143
+ ```javascript
1144
+ import { Telegix, I18n, session } from 'telegix';
1145
+
1146
+ const i18n = new I18n({
1147
+ defaultLocale: 'en',
1148
+ locales: {
1149
+ en: {
1150
+ welcome: 'Welcome, {{name}}!',
1151
+ menu: { profile: 'User Profile', settings: 'Settings' },
1152
+ items: {
1153
+ one: '1 item in cart',
1154
+ other: '{{count}} items in cart',
1155
+ },
1156
+ },
1157
+ es: {
1158
+ welcome: 'ยกBienvenido, {{name}}!',
1159
+ menu: { profile: 'Perfil de Usuario', settings: 'Ajustes' },
1160
+ items: {
1161
+ one: '1 artรญculo en el carrito',
1162
+ other: '{{count}} artรญculos en el carrito',
1163
+ },
1164
+ },
1165
+ },
1166
+ });
1167
+
1168
+ const bot = new Telegix(process.env.BOT_TOKEN);
1169
+ bot.use(session());
1170
+ bot.use(i18n.middleware());
1171
+
1172
+ bot.command('start', async (ctx) => {
1173
+ await ctx.reply(ctx.t('welcome', { name: ctx.from?.first_name }));
1174
+ await ctx.reply(ctx.t('menu.profile'));
1175
+ await ctx.reply(ctx.t('items', { count: 3 }));
1176
+ });
1177
+
1178
+ bot.command('set_spanish', async (ctx) => {
1179
+ ctx.i18n.setLocale('es');
1180
+ await ctx.reply(ctx.t('welcome', { name: ctx.from?.first_name }));
1181
+ });
1182
+ ```
1183
+
1184
+ ---
1185
+
1186
+ ## โœ’๏ธ Message Formatting (`fmt`, `html`, `mdv2`)
1187
+
1188
+ ### XSS-Safe HTML Builder (`fmt` & `html`)
1189
+
1190
+ Safely interpolate untrusted user input into HTML messages without escaping errors:
1191
+
1192
+ ```javascript
1193
+ import { fmt, html } from 'telegix';
1194
+
1195
+ bot.command('profile', async (ctx) => {
1196
+ const untrustedBio = '<script>alert("xss")</script> & <b>test</b>';
1197
+
1198
+ const message = fmt`
1199
+ <b>๐Ÿ‘ค User Profile</b>
1200
+ โ€ข Name: ${ctx.from?.first_name}
1201
+ โ€ข Bio: ${untrustedBio}
1202
+ โ€ข Status: ${html`<i>Verified Member</i>`}
1203
+ โ€ข Points: ${1500}
1204
+ ${fmt.link('Open Dashboard', 'https://example.com')}
1205
+ `;
1206
+
1207
+ await ctx.reply(message, { parse_mode: 'HTML' });
1208
+ });
1209
+ ```
1210
+
1211
+ ---
1212
+
1213
+ ### MarkdownV2 Escaping Helpers (`mdv2`)
1214
+
1215
+ ```javascript
1216
+ import { mdv2 } from 'telegix';
1217
+
1218
+ bot.command('md', async (ctx) => {
1219
+ const rawText = 'Price: $99.99 (Special Offer! *Limited*)';
1220
+ const boldEscaped = mdv2.bold(rawText);
1221
+
1222
+ await ctx.reply(boldEscaped, { parse_mode: 'MarkdownV2' });
1223
+ });
1224
+ ```
1225
+
1226
+ ---
1227
+
1228
+ ## ๐Ÿ’ณ Payments, Invoices & Telegram Stars (`InvoiceBuilder`)
1229
+
1230
+ Create and dispatch invoices for fiat currencies or **Telegram Stars (`XTR`)**:
1231
+
1232
+ ```javascript
1233
+ import { InvoiceBuilder, answerPreCheckoutQuery } from 'telegix';
1234
+
1235
+ bot.command('buy_stars', async (ctx) => {
1236
+ const invoice = new InvoiceBuilder(
1237
+ 'โญ 100 Telegram Stars Pass',
1238
+ 'Unlock 30 days of premium bot capabilities',
1239
+ 'order_stars_100',
1240
+ 'XTR' // Telegram Stars currency
1241
+ )
1242
+ .addPrice('Stars Membership', 100)
1243
+ .photo('https://example.com/stars_banner.png')
1244
+ .build();
1245
+
1246
+ await ctx.replyWithInvoice(
1247
+ invoice.title,
1248
+ invoice.description,
1249
+ invoice.payload,
1250
+ invoice.currency,
1251
+ invoice.prices,
1252
+ invoice
1253
+ );
1254
+ });
1255
+
1256
+ // Pre-checkout query validation
1257
+ bot.on('pre_checkout_query', async (ctx) => {
1258
+ await answerPreCheckoutQuery(ctx, true);
1259
+ });
1260
+
1261
+ // Successful payment notification
1262
+ bot.on('successful_payment', async (ctx) => {
1263
+ const payment = ctx.message.successful_payment;
1264
+ await ctx.reply(`๐ŸŽ‰ Payment confirmed! Received ${payment.total_amount} ${payment.currency}.`);
1265
+ });
1266
+ ```
1267
+
1268
+ ---
1269
+
1270
+ ## ๐Ÿ“ฑ Telegram Mini Apps / WebApps (`validateWebAppInitData`)
1271
+
1272
+ Cryptographically verify Mini App authentication payloads using HMAC-SHA256:
1273
+
1274
+ ```javascript
1275
+ import { validateWebAppInitData, parseWebAppInitData } from 'telegix';
1276
+
1277
+ // Inside your backend API route (e.g. Express / Fastify)
1278
+ app.post('/api/auth/validate', (req, res) => {
1279
+ const { initData } = req.body;
1280
+ const isValid = validateWebAppInitData(initData, process.env.BOT_TOKEN, 86400); // 24h expiration
1281
+
1282
+ if (!isValid) {
1283
+ return res.status(401).json({ error: 'Invalid Telegram WebApp session' });
1284
+ }
1285
+
1286
+ const parsed = parseWebAppInitData(initData);
1287
+ return res.json({ success: true, user: parsed.user });
1288
+ });
1289
+ ```
1290
+
1291
+ ---
1292
+
1293
+ ## ๐Ÿค– Multi-Bot Process Manager (`TelegixManager`)
1294
+
1295
+ Run, coordinate, and supervise multiple Telegram bots within a single Node.js process:
1296
+
1297
+ ```javascript
1298
+ import { TelegixManager } from 'telegix';
1299
+
1300
+ const manager = new TelegixManager();
1301
+
1302
+ // Register Bot 1
1303
+ const supportBot = manager.add('support_bot', process.env.SUPPORT_BOT_TOKEN);
1304
+ supportBot.command('start', (ctx) => ctx.reply('Support bot online!'));
1305
+
1306
+ // Register Bot 2
1307
+ const alertBot = manager.add('alerts_bot', process.env.ALERTS_BOT_TOKEN);
1308
+ alertBot.command('start', (ctx) => ctx.reply('Alerts bot online!'));
1309
+
1310
+ // Launch all registered bots concurrently
1311
+ await manager.launchAll();
1312
+ console.log(`Running ${manager.size} bots concurrently!`);
1313
+ ```
1314
+
1315
+ ---
1316
+
1317
+ ## โšก Advanced Built-in Middlewares
1318
+
1319
+ ### Rate Limiter Middleware (`rateLimit`)
1320
+
1321
+ ```javascript
1322
+ import { rateLimit } from 'telegix';
1323
+
1324
+ bot.use(
1325
+ rateLimit({
1326
+ windowMs: 5000, // 5 second rolling window
1327
+ limit: 3, // Max 3 messages per window
1328
+ handler: async (ctx) => {
1329
+ await ctx.reply('โš ๏ธ Rate limit exceeded! Please wait a moment before sending more messages.');
1330
+ },
1331
+ })
1332
+ );
1333
+ ```
1334
+
1335
+ ### Media Group / Album Batching (`albumMiddleware`)
1336
+
1337
+ Batches photos and documents sent together into a single `ctx.album` array:
1338
+
1339
+ ```javascript
1340
+ import { albumMiddleware } from 'telegix';
1341
+
1342
+ bot.use(albumMiddleware({ windowMs: 500 }));
1343
+
1344
+ bot.on('message:photo', async (ctx) => {
1345
+ if (ctx.album) {
1346
+ console.log(`Received photo album containing ${ctx.album.count} photos!`);
1347
+ for (const msg of ctx.album.messages) {
1348
+ console.log('File ID:', msg.photo[msg.photo.length - 1].file_id);
1349
+ }
1350
+ }
1351
+ });
1352
+ ```
1353
+
1354
+ ### Inline Query Debounce & Cache (`inlineDebounceMiddleware`)
1355
+
1356
+ ```javascript
1357
+ import { inlineDebounceMiddleware } from 'telegix';
1358
+
1359
+ bot.use(inlineDebounceMiddleware({ windowMs: 300, cacheTtlMs: 60000 }));
1360
+ ```
1361
+
1362
+ ### Automatic Chat Action (`chatActionMiddleware`)
1363
+
1364
+ Keeps the "typing" action active continuously during long asynchronous computations or AI streaming:
1365
+
1366
+ ```javascript
1367
+ import { chatActionMiddleware } from 'telegix';
1368
+
1369
+ bot.command('ai_summary', chatActionMiddleware('typing'), async (ctx) => {
1370
+ const result = await generateAiSummary(ctx.payload);
1371
+ await ctx.reply(result);
1372
+ });
1373
+ ```
1374
+
1375
+ ### Inline Query Pagination (`paginateInlineQuery`)
1376
+
1377
+ ```javascript
1378
+ import { InlineQueryResultBuilder, paginateInlineQuery } from 'telegix';
1379
+
1380
+ const inventory = [
1381
+ { id: '1', name: 'MacBook Pro', price: '$1999' },
1382
+ { id: '2', name: 'iPhone 16 Pro', price: '$999' },
1383
+ { id: '3', name: 'iPad Pro', price: '$799' },
1384
+ ];
1385
+
1386
+ bot.on('inline_query', async (ctx) => {
1387
+ await paginateInlineQuery(
1388
+ ctx,
1389
+ inventory,
1390
+ (item) =>
1391
+ InlineQueryResultBuilder.article(
1392
+ item.id,
1393
+ item.name,
1394
+ `<b>${item.name}</b>: ${item.price}`,
1395
+ { description: `Order ${item.name}` }
1396
+ ),
1397
+ { limit: 10 }
1398
+ );
1399
+ });
1400
+ ```
1401
+
1402
+ ---
1403
+
1404
+ ## ๐Ÿ“š Complete Telegram API Client Method Reference (`bot.telegram` / `bot.api`)
1405
+
1406
+ The `Telegram` client exposes every official method of the Telegram Bot API:
1407
+
1408
+ ### Account & Identity
1409
+ - `getMe()` โ€” Retrieve bot identity information.
1410
+ - `logOut()` / `close()` โ€” Log out from the cloud Bot API or close the local bot instance.
1411
+ - `getMyName(extra)` / `setMyName(name, extra)` โ€” Get or set bot name.
1412
+ - `getMyDescription(extra)` / `setMyDescription(description, extra)` โ€” Get or set bot description.
1413
+ - `getMyShortDescription(extra)` / `setMyShortDescription(shortDescription, extra)` โ€” Get or set short description.
1414
+ - `getMyCommands(extra)` / `setMyCommands(commands, extra)` / `deleteMyCommands(extra)` โ€” Manage bot command menu list.
1415
+ - `getMyDefaultAdministratorRights(extra)` / `setMyDefaultAdministratorRights(rights, extra)` โ€” Manage administrator rights.
1416
+ - `getChatMenuButton(extra)` / `setChatMenuButton(extra)` โ€” Manage the chat menu button.
1417
+
1418
+ ### Messages & Media Sending
1419
+ - `sendMessage(chatId, text, extra)`
1420
+ - `forwardMessage(chatId, fromChatId, messageId, extra)` / `forwardMessages(chatId, fromChatId, messageIds, extra)`
1421
+ - `copyMessage(chatId, fromChatId, messageId, extra)` / `copyMessages(chatId, fromChatId, messageIds, extra)`
1422
+ - `sendPhoto(chatId, photo, extra)`
1423
+ - `sendAudio(chatId, audio, extra)`
1424
+ - `sendDocument(chatId, document, extra)`
1425
+ - `sendVideo(chatId, video, extra)`
1426
+ - `sendAnimation(chatId, animation, extra)`
1427
+ - `sendVoice(chatId, voice, extra)`
1428
+ - `sendVideoNote(chatId, videoNote, extra)`
1429
+ - `sendPaidMedia(chatId, starCount, media, extra)`
1430
+ - `sendMediaGroup(chatId, media, extra)`
1431
+ - `sendLocation(chatId, latitude, longitude, extra)`
1432
+ - `sendVenue(chatId, latitude, longitude, title, address, extra)`
1433
+ - `sendContact(chatId, phoneNumber, firstName, extra)`
1434
+ - `sendPoll(chatId, question, options, extra)`
1435
+ - `sendDice(chatId, extra)`
1436
+ - `sendChatAction(chatId, action, extra)`
1437
+ - `setMessageReaction(chatId, messageId, reaction, extra)`
1438
+ - `sendSticker(chatId, sticker, extra)`
1439
+ - `sendGame(chatId, gameShortName, extra)`
1440
+ - `sendInvoice(chatId, title, description, payload, currency, prices, extra)`
1441
+ - `sendGift(userId, giftId, extra)`
1442
+ - `sendEphemeralMessage(chatId, text, ephemeralParameters, extra)`
1443
+ - `sendMessageDraft(chatId, text, extra)`
1444
+ - `sendRichMessage(chatId, richMessage, extra)`
1445
+ - `sendRichMessageDraft(chatId, draft, extra)`
1446
+
1447
+ ### Messages Editing & Deletion
1448
+ - `editMessageText(chatId, messageId, inlineMessageId, text, extra)`
1449
+ - `editMessageCaption(chatId, messageId, inlineMessageId, caption, extra)`
1450
+ - `editMessageMedia(chatId, messageId, inlineMessageId, media, extra)`
1451
+ - `editMessageReplyMarkup(chatId, messageId, inlineMessageId, replyMarkup, extra)`
1452
+ - `editRichMessageText(chatId, messageId, richMessage, extra)`
1453
+ - `editRichMessageCaption(chatId, messageId, caption, extra)`
1454
+ - `deleteMessage(chatId, messageId)`
1455
+ - `deleteMessages(chatId, messageIds)`
1456
+ - `editMessageLiveLocation(latitude, longitude, extra)` / `stopMessageLiveLocation(extra)`
1457
+ - `stopPoll(chatId, messageId, extra)`
1458
+
1459
+ ### Chat Moderation & Administration
1460
+ - `getChat(chatId)`
1461
+ - `getChatAdministrators(chatId)`
1462
+ - `getChatMemberCount(chatId)` / `getChatMembersCount(chatId)`
1463
+ - `getChatMember(chatId, userId)`
1464
+ - `banChatMember(chatId, userId, extra)`
1465
+ - `unbanChatMember(chatId, userId, extra)`
1466
+ - `restrictChatMember(chatId, userId, permissions, extra)`
1467
+ - `promoteChatMember(chatId, userId, rights)`
1468
+ - `setChatAdministratorCustomTitle(chatId, userId, customTitle)`
1469
+ - `setChatPermissions(chatId, permissions, extra)`
1470
+ - `setChatTitle(chatId, title)`
1471
+ - `setChatDescription(chatId, description)`
1472
+ - `setChatPhoto(chatId, photo)` / `deleteChatPhoto(chatId)`
1473
+ - `pinChatMessage(chatId, messageId, extra)` / `unpinChatMessage(chatId, messageId)` / `unpinAllChatMessages(chatId)`
1474
+ - `leaveChat(chatId)`
1475
+ - `exportChatInviteLink(chatId)`
1476
+ - `createChatInviteLink(chatId, extra)`
1477
+ - `editChatInviteLink(chatId, inviteLink, extra)`
1478
+ - `revokeChatInviteLink(chatId, inviteLink)`
1479
+ - `approveChatJoinRequest(chatId, userId)`
1480
+ - `declineChatJoinRequest(chatId, userId)`
1481
+ - `verifyUser(userId, customDescription)`
1482
+ - `verifyChat(chatId, customDescription)`
1483
+ - `removeUserVerification(userId)`
1484
+ - `removeChatVerification(chatId)`
1485
+ - `getUserChatBoosts(chatId, userId)`
1486
+ - `getBusinessConnection(businessConnectionId)`
1487
+
1488
+ ### Forum Topics Management
1489
+ - `createForumTopic(chatId, name, extra)`
1490
+ - `editForumTopic(chatId, messageThreadId, extra)`
1491
+ - `closeForumTopic(chatId, messageThreadId)`
1492
+ - `reopenForumTopic(chatId, messageThreadId)`
1493
+ - `deleteForumTopic(chatId, messageThreadId)`
1494
+ - `unpinAllForumTopicMessages(chatId, messageThreadId)`
1495
+ - `editGeneralForumTopic(chatId, name)`
1496
+ - `closeGeneralForumTopic(chatId)`
1497
+ - `reopenGeneralForumTopic(chatId)`
1498
+ - `hideGeneralForumTopic(chatId)`
1499
+ - `unhideGeneralForumTopic(chatId)`
1500
+
1501
+ ### Managed Bot Access Settings (Bot API 10.3)
1502
+ - `getManagedBotAccessSettings(userId, extra)`
1503
+ - `setManagedBotAccessSettings(userId, settings, extra)`
1504
+ - `getUserPersonalChatMessages(userId, extra)`
1505
+
1506
+ ---
1507
+
1508
+ ## ๐ŸŸฆ TypeScript Support
1509
+
1510
+ Telegix comes with zero-config TypeScript type declarations included in `index.d.ts`:
1511
+
1512
+ ```typescript
1513
+ import { Telegix, Context } from 'telegix';
1514
+
1515
+ interface SessionData {
1516
+ counter: number;
1517
+ selectedCity?: string;
1518
+ }
1519
+
1520
+ interface CustomContext extends Context {
1521
+ session: SessionData;
1522
+ }
1523
+
1524
+ const bot = new Telegix<CustomContext>(process.env.BOT_TOKEN!);
1525
+
1526
+ bot.command('count', async (ctx) => {
1527
+ ctx.session.counter = (ctx.session.counter || 0) + 1;
1528
+ await ctx.reply(`Count: ${ctx.session.counter}`);
1529
+ });
1530
+ ```
1531
+
1532
+ ---
1533
+
1534
+ ---