ultra-telegram-framework 1.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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +174 -0
  3. package/dist/adapters/gas.d.ts +10 -0
  4. package/dist/adapters/gas.js +90 -0
  5. package/dist/adapters/node.d.ts +52 -0
  6. package/dist/adapters/node.js +150 -0
  7. package/dist/adapters/web.d.ts +4 -0
  8. package/dist/adapters/web.js +90 -0
  9. package/dist/core/base-api.d.ts +40 -0
  10. package/dist/core/base-api.js +26 -0
  11. package/dist/core/bot.d.ts +1828 -0
  12. package/dist/core/bot.js +2753 -0
  13. package/dist/core/composer.d.ts +87 -0
  14. package/dist/core/composer.js +164 -0
  15. package/dist/core/context/base-context.d.ts +24 -0
  16. package/dist/core/context/base-context.js +56 -0
  17. package/dist/core/context/reply-context.d.ts +234 -0
  18. package/dist/core/context/reply-context.js +528 -0
  19. package/dist/core/context.d.ts +8 -0
  20. package/dist/core/context.js +34 -0
  21. package/dist/core/keyboard.d.ts +76 -0
  22. package/dist/core/keyboard.js +182 -0
  23. package/dist/core/menu.d.ts +58 -0
  24. package/dist/core/menu.js +87 -0
  25. package/dist/index.d.ts +18 -0
  26. package/dist/index.js +24 -0
  27. package/dist/scenes/scene-manager.d.ts +39 -0
  28. package/dist/scenes/scene-manager.js +65 -0
  29. package/dist/scenes/stage.d.ts +8 -0
  30. package/dist/scenes/stage.js +34 -0
  31. package/dist/scenes/wizard.d.ts +18 -0
  32. package/dist/scenes/wizard.js +32 -0
  33. package/dist/session/gas-cache-storage.d.ts +34 -0
  34. package/dist/session/gas-cache-storage.js +49 -0
  35. package/dist/session/gas-hybrid-storage.d.ts +27 -0
  36. package/dist/session/gas-hybrid-storage.js +49 -0
  37. package/dist/session/gas-storage.d.ts +24 -0
  38. package/dist/session/gas-storage.js +47 -0
  39. package/dist/session/index.d.ts +28 -0
  40. package/dist/session/index.js +43 -0
  41. package/dist/session/memory-storage.d.ts +28 -0
  42. package/dist/session/memory-storage.js +35 -0
  43. package/dist/session/storage.d.ts +18 -0
  44. package/dist/session/storage.js +2 -0
  45. package/dist/types/telegram.d.ts +7560 -0
  46. package/dist/types/telegram.js +4 -0
  47. package/package.json +42 -0
@@ -0,0 +1,528 @@
1
+ import { InlineKeyboard, ReplyKeyboard } from "../keyboard";
2
+ import { BaseContext } from "./base-context";
3
+ export class ReplyContext extends BaseContext {
4
+ async reply(text, options) {
5
+ const { chatId, messageId } = this.getRequiredIds("reply", false);
6
+ return this.api.sendMessage({
7
+ chat_id: chatId,
8
+ text,
9
+ reply_parameters: messageId ? { message_id: messageId } : undefined,
10
+ ...options,
11
+ });
12
+ }
13
+ /**
14
+ * Reply to the current message with a keyboard (Inline or Reply)
15
+ * @param text - message text
16
+ * @param keyboard - keyboard
17
+ * @param options - parameters object
18
+ * @returns `Promise<Message>`
19
+ */
20
+ async replyWithKeyboard(text, keyboard, options) {
21
+ const reply_markup = (keyboard instanceof InlineKeyboard || keyboard instanceof ReplyKeyboard)
22
+ ? keyboard.build()
23
+ : keyboard;
24
+ return this.reply(text, {
25
+ reply_markup: reply_markup,
26
+ ...options,
27
+ });
28
+ }
29
+ /**
30
+ * Quick reply with an Inline keyboard
31
+ * @param text - message text
32
+ * @param buttons - keyboard
33
+ * @param options - parameters object
34
+ * @returns `Promise<Message>`
35
+ */
36
+ async replyWithInlineKeyboard(text, buttons, options) {
37
+ const markup = buttons instanceof InlineKeyboard
38
+ ? buttons.build()
39
+ : { inline_keyboard: buttons };
40
+ return this.reply(text, {
41
+ reply_markup: markup,
42
+ ...options,
43
+ });
44
+ }
45
+ /**
46
+ * Reply to the current message with a photo
47
+ * @param photo URL of the image or `file_id`
48
+ * @param options Parameters object or just the notification text
49
+ * @returns `Promise<Message>`
50
+ */
51
+ async replyWithPhoto(photo, options) {
52
+ const { chatId, messageId } = this.getRequiredIds("replyWithPhoto", false);
53
+ return this.api.sendPhoto({
54
+ chat_id: chatId,
55
+ photo: photo,
56
+ reply_parameters: messageId ? { message_id: messageId } : undefined,
57
+ ...options,
58
+ });
59
+ }
60
+ /**
61
+ * Reply to the current message with a video file
62
+ * @param video URL of the video or `file_id`
63
+ * @param options Parameters object or just the notification text
64
+ * @returns `Promise<Message>`
65
+ */
66
+ async replyWithVideo(video, options) {
67
+ const { chatId, messageId } = this.getRequiredIds("replyWithVideo", false);
68
+ return this.api.sendVideo({
69
+ chat_id: chatId,
70
+ video: video,
71
+ reply_parameters: messageId ? { message_id: messageId } : undefined,
72
+ ...options,
73
+ });
74
+ }
75
+ /**
76
+ * Reply to the current message with a document (file)
77
+ * @param document URL of the file or `file_id`
78
+ * @param options Parameters object or just the notification text
79
+ * @returns `Promise<Message>`
80
+ */
81
+ async replyWithDocument(document, options) {
82
+ const { chatId, messageId } = this.getRequiredIds("replyWithDocument", false);
83
+ return this.api.sendDocument({
84
+ chat_id: chatId,
85
+ document: document,
86
+ reply_parameters: messageId ? { message_id: messageId } : undefined,
87
+ ...options,
88
+ });
89
+ }
90
+ /**
91
+ * Reply to the current message with a "live photo" (Live Photo)
92
+ * @param photo URL of the photo or `file_id`
93
+ * @param livePhoto URL of the "live photo" or `file_id`
94
+ * @param options Parameters object or just the notification text
95
+ * @returns `Promise<Message>`
96
+ */
97
+ async replyWithLivePhoto(photo, livePhoto, options) {
98
+ const { chatId, messageId } = this.getRequiredIds("replyWithLivePhoto", false);
99
+ return this.api.sendLivePhoto({
100
+ chat_id: chatId,
101
+ photo,
102
+ live_photo: livePhoto,
103
+ reply_parameters: messageId ? { message_id: messageId } : undefined,
104
+ ...options
105
+ });
106
+ }
107
+ /**
108
+ * Send a gift (Star Gift) to the current user
109
+ * @param giftId Gift ID
110
+ * @param options Parameters object
111
+ * @returns `Promise<boolean>`
112
+ */
113
+ async sendGift(giftId, options) {
114
+ var _a;
115
+ const fromId = (_a = this.from) === null || _a === void 0 ? void 0 : _a.id;
116
+ if (!fromId)
117
+ throw new Error("Cannot send gift: user_id not found.");
118
+ return this.api.sendGift({
119
+ user_id: fromId,
120
+ gift_id: giftId,
121
+ ...options
122
+ });
123
+ }
124
+ /**
125
+ * Remove loading indicator from an inline button
126
+ * @param params Parameters object or just the notification text
127
+ * @returns `Promise<boolean>`
128
+ */
129
+ async answerCbQuery(params) {
130
+ var _a;
131
+ // 1. Отримуємо ID виключно з контексту, бо ми заборонили передавати його в params
132
+ const cbId = (_a = this.callbackQuery) === null || _a === void 0 ? void 0 : _a.id;
133
+ if (!cbId) {
134
+ throw new Error("Cannot perform answerCbQuery: callback_query_id not found.");
135
+ }
136
+ // 2. If a string is passed, it is shorthand for { text: "..." }
137
+ if (typeof params === "string") {
138
+ return this.api.answerCallbackQuery({
139
+ callback_query_id: cbId,
140
+ text: params,
141
+ });
142
+ }
143
+ // 3. If an object is passed, use it, adding/overriding the ID
144
+ return this.api.answerCallbackQuery({
145
+ ...params,
146
+ callback_query_id: cbId,
147
+ });
148
+ }
149
+ /**
150
+ * React to the current message
151
+ * @param reactions Array of reactions (e.g.: `[{ type: "emoji", emoji: "👍" }]`)
152
+ * @returns `Promise<boolean>`
153
+ */
154
+ async react(reactions) {
155
+ const { chatId, messageId } = this.getRequiredIds("react", true);
156
+ return this.api.setMessageReaction({
157
+ chat_id: chatId,
158
+ message_id: messageId,
159
+ reaction: reactions,
160
+ });
161
+ }
162
+ /**
163
+ * Send chat action status to the current chat (e.g., "typing", "upload_photo")
164
+ * @param action Action status (e.g., "typing", "upload_photo")
165
+ * @returns `Promise<boolean>`
166
+ */
167
+ async replyWithChatAction(action) {
168
+ const { chatId } = this.getRequiredIds("replyWithChatAction", false);
169
+ return this.api.sendChatAction({
170
+ chat_id: chatId,
171
+ action: action,
172
+ });
173
+ }
174
+ /**
175
+ * Delete the current message
176
+ * @returns `Promise<boolean>`
177
+ */
178
+ async deleteMessage() {
179
+ const { chatId, messageId } = this.getRequiredIds("deleteMessage", true);
180
+ return this.api.deleteMessage({
181
+ chat_id: chatId,
182
+ message_id: messageId,
183
+ });
184
+ }
185
+ /**
186
+ * Edit the text of the current message
187
+ * @param text Message text
188
+ * @param options Additional parameters
189
+ * @returns `Promise<Message | boolean>`
190
+ */
191
+ async editMessage(text, options) {
192
+ const { chatId, messageId } = this.getRequiredIds("editMessage");
193
+ return this.api.editMessageText({
194
+ chat_id: chatId,
195
+ message_id: messageId,
196
+ text,
197
+ ...options,
198
+ });
199
+ }
200
+ /**
201
+ * Forward the current message to another chat
202
+ * @param toChatId ID of the chat where the message is forwarded
203
+ * @returns `Promise<Message>`
204
+ */
205
+ async forwardTo(toChatId) {
206
+ const { chatId, messageId } = this.getRequiredIds("forwardTo", true);
207
+ return this.api.forwardMessage({
208
+ chat_id: toChatId,
209
+ from_chat_id: chatId,
210
+ message_id: messageId,
211
+ });
212
+ }
213
+ /**
214
+ * Copy the current message to another chat
215
+ * @param toChatId ID of the chat where the message is copied
216
+ * @returns `Promise<MessageId>`
217
+ */
218
+ async copyTo(toChatId) {
219
+ const { chatId, messageId } = this.getRequiredIds("copyTo", true);
220
+ return this.api.copyMessage({
221
+ chat_id: toChatId,
222
+ from_chat_id: chatId,
223
+ message_id: messageId,
224
+ });
225
+ }
226
+ /**
227
+ * Returns command arguments (everything that follows the command name).
228
+ * Example: for the message "/start ref_123", it will return "ref_123".
229
+ * If it is just "/start", it will return an empty string.
230
+ * @returns `string`
231
+ */
232
+ get payload() {
233
+ const txt = this.text;
234
+ if (!txt || !txt.startsWith('/'))
235
+ return '';
236
+ const parts = txt.split(/\s+/); // Split by spaces (one or more)
237
+ if (parts.length <= 1)
238
+ return '';
239
+ return parts.slice(1).join(' ').trim();
240
+ }
241
+ /**
242
+ * ID of the user who initiated the event
243
+ * @returns `number | undefined`
244
+ */
245
+ get senderId() {
246
+ var _a;
247
+ return (_a = this.from) === null || _a === void 0 ? void 0 : _a.id;
248
+ }
249
+ /**
250
+ * Change only the inline keyboard of the current message
251
+ * @param replyMarkup - keyboard
252
+ * @returns `Promise<Message | boolean>`
253
+ */
254
+ async editReplyMarkup(replyMarkup) {
255
+ const { chatId, messageId } = this.getRequiredIds("editReplyMarkup", true);
256
+ return this.api.editMessageReplyMarkup({
257
+ chat_id: chatId,
258
+ message_id: messageId,
259
+ reply_markup: replyMarkup, // If undefined is passed, the keyboard will disappear
260
+ });
261
+ }
262
+ /**
263
+ * Change the caption of the current media file (photo/video)
264
+ * @param caption - caption
265
+ * @param options - parameters object
266
+ * @returns `Promise<Message | boolean>`
267
+ */
268
+ async editCaption(caption, options) {
269
+ const { chatId, messageId } = this.getRequiredIds("editCaption", true);
270
+ return this.api.editMessageCaption({
271
+ chat_id: chatId,
272
+ message_id: messageId,
273
+ caption: caption,
274
+ ...options,
275
+ });
276
+ }
277
+ /**
278
+ * Get the list of administrators of the current chat
279
+ * @returns `Promise<ChatMember[]>`
280
+ */
281
+ async getAdministrators() {
282
+ const { chatId } = this.getRequiredIds("getAdministrators", false);
283
+ return this.api.getChatAdministrators({ chat_id: chatId });
284
+ }
285
+ /**
286
+ * Get information about a specific member in the current chat
287
+ * @param userId User ID
288
+ * @returns `Promise<ChatMember>`
289
+ */
290
+ async getMember(userId) {
291
+ const { chatId } = this.getRequiredIds("getMember", false);
292
+ return this.api.getChatMember({ chat_id: chatId, user_id: userId });
293
+ }
294
+ /**
295
+ * Leave the current chat (group/channel)
296
+ * @returns `Promise<boolean>`
297
+ */
298
+ async leaveChat() {
299
+ const { chatId } = this.getRequiredIds("leaveChat", false);
300
+ return this.api.leaveChat({ chat_id: chatId });
301
+ }
302
+ // --- PAYMENTS ---
303
+ /**
304
+ * Send an invoice to the current chat
305
+ * @param params Parameters object
306
+ * @returns `Promise<Message>`
307
+ */
308
+ async replyWithInvoice(params) {
309
+ const { chatId } = this.getRequiredIds("replyWithInvoice", false);
310
+ return this.api.sendInvoice({
311
+ chat_id: chatId,
312
+ ...params,
313
+ });
314
+ }
315
+ /**
316
+ * Answer a shipping query (Shipping Query)
317
+ * @param ok Is everything okay
318
+ * @param options Additional parameters
319
+ * @returns `Promise<boolean>`
320
+ */
321
+ async answerShippingQuery(ok, options) {
322
+ var _a;
323
+ const queryId = (_a = this.update.shipping_query) === null || _a === void 0 ? void 0 : _a.id;
324
+ if (!queryId)
325
+ throw new Error("Cannot answer Shipping Query: id not found.");
326
+ return this.api.answerShippingQuery({
327
+ shipping_query_id: queryId,
328
+ ok,
329
+ ...options,
330
+ });
331
+ }
332
+ /**
333
+ * Answer a pre-checkout query (Pre-checkout Query)
334
+ * @param ok Is everything okay
335
+ * @param errorMessage Error message
336
+ * @returns `Promise<boolean>`
337
+ */
338
+ async answerPreCheckoutQuery(ok, errorMessage) {
339
+ var _a;
340
+ const queryId = (_a = this.update.pre_checkout_query) === null || _a === void 0 ? void 0 : _a.id;
341
+ if (!queryId)
342
+ throw new Error("Cannot answer Pre-checkout Query: id not found.");
343
+ return this.api.answerPreCheckoutQuery({
344
+ pre_checkout_query_id: queryId,
345
+ ok,
346
+ error_message: errorMessage,
347
+ });
348
+ }
349
+ // --- GAMES ---
350
+ /**
351
+ * Send a game to the current chat
352
+ * @param gameShortName - short name of the game
353
+ * @param options - parameters object
354
+ * @returns `Promise<Message>`
355
+ */
356
+ async replyWithGame(gameShortName, options) {
357
+ const { chatId } = this.getRequiredIds("replyWithGame", false);
358
+ return this.api.sendGame({
359
+ chat_id: chatId,
360
+ game_short_name: gameShortName,
361
+ ...options,
362
+ });
363
+ }
364
+ /**
365
+ * Set a high score for a player in the game
366
+ * @param score - game score
367
+ * @param options - parameters object
368
+ * @returns `Promise<Message | boolean>`
369
+ */
370
+ async setGameScore(score, options) {
371
+ var _a, _b;
372
+ const fromId = (_a = this.from) === null || _a === void 0 ? void 0 : _a.id;
373
+ if (!fromId)
374
+ throw new Error("Cannot set game score: user_id not found.");
375
+ // Priority is given to inline_message_id, if it exists
376
+ const inlineId = (_b = this.callbackQuery) === null || _b === void 0 ? void 0 : _b.inline_message_id;
377
+ const { chatId, messageId } = inlineId ? { chatId: undefined, messageId: undefined } : this.getRequiredIds("setGameScore", true);
378
+ return this.api.setGameScore({
379
+ user_id: fromId,
380
+ score,
381
+ chat_id: chatId,
382
+ message_id: messageId,
383
+ inline_message_id: inlineId,
384
+ ...options,
385
+ });
386
+ }
387
+ /**
388
+ * Get high scores table for the game
389
+ * @returns `Promise<GameHighScore[]>`
390
+ */
391
+ async getGameHighScores() {
392
+ var _a, _b;
393
+ const fromId = (_a = this.from) === null || _a === void 0 ? void 0 : _a.id;
394
+ if (!fromId)
395
+ throw new Error("Cannot get game high scores: user_id not found.");
396
+ const inlineId = (_b = this.callbackQuery) === null || _b === void 0 ? void 0 : _b.inline_message_id;
397
+ const { chatId, messageId } = inlineId ? { chatId: undefined, messageId: undefined } : this.getRequiredIds("getGameHighScores", true);
398
+ return this.api.getGameHighScores({
399
+ user_id: fromId,
400
+ chat_id: chatId,
401
+ message_id: messageId,
402
+ inline_message_id: inlineId,
403
+ });
404
+ }
405
+ /**
406
+ * Answer a guest query (Guest Mode)
407
+ * @param result - query result
408
+ * @param options - parameters object
409
+ * @returns `Promise<SentGuestMessage>`
410
+ */
411
+ async answerGuest(result, options) {
412
+ var _a;
413
+ const msg = this.message;
414
+ const queryId = ((_a = this.update.guest_message) === null || _a === void 0 ? void 0 : _a.guest_query_id) || (msg === null || msg === void 0 ? void 0 : msg.guest_query_id);
415
+ if (!queryId)
416
+ throw new Error("Missing guest_query_id");
417
+ return this.api.answerGuestQuery({
418
+ guest_query_id: queryId,
419
+ result: result,
420
+ ...options
421
+ });
422
+ }
423
+ /**
424
+ * Delete reaction on the current message.
425
+ * By default, deletes the reaction of the user who initiated the event.
426
+ * @param options - parameters object
427
+ * @returns `Promise<boolean>`
428
+ */
429
+ async deleteReaction(options) {
430
+ var _a;
431
+ const { chatId, messageId } = this.getRequiredIds("deleteReaction", true);
432
+ // If the developer did not pass a specific user_id or actor_chat_id,
433
+ // by default we substitute the ID of the current user
434
+ const defaultOptions = (!(options === null || options === void 0 ? void 0 : options.user_id) && !(options === null || options === void 0 ? void 0 : options.actor_chat_id))
435
+ ? { user_id: (_a = this.from) === null || _a === void 0 ? void 0 : _a.id }
436
+ : {};
437
+ return this.api.deleteMessageReaction({
438
+ chat_id: chatId,
439
+ message_id: messageId,
440
+ ...defaultOptions,
441
+ ...options
442
+ });
443
+ }
444
+ /**
445
+ * Delete all reactions of a specific user in the current chat (up to 10,000).
446
+ * By default, deletes the reactions of the user who initiated the event.
447
+ * @param options - parameters object
448
+ * @returns `Promise<boolean>`
449
+ */
450
+ async deleteAllReactions(options) {
451
+ var _a;
452
+ const { chatId } = this.getRequiredIds("deleteAllReactions", false);
453
+ const defaultOptions = (!(options === null || options === void 0 ? void 0 : options.user_id) && !(options === null || options === void 0 ? void 0 : options.actor_chat_id))
454
+ ? { user_id: (_a = this.from) === null || _a === void 0 ? void 0 : _a.id }
455
+ : {};
456
+ return this.api.deleteAllMessageReactions({
457
+ chat_id: chatId,
458
+ ...defaultOptions,
459
+ ...options
460
+ });
461
+ }
462
+ /**
463
+ * Send a poll or quiz (Poll / Quiz) to the current chat.
464
+ * Supports new API 10.0 features: media, explanation_media, 1 answer option.
465
+ * @param question - poll text
466
+ * @param pollOptions - answer options
467
+ * @param options - parameters object
468
+ * @returns `Promise<Message>`
469
+ */
470
+ async replyWithPoll(question, pollOptions, options) {
471
+ const { chatId, messageId } = this.getRequiredIds("replyWithPoll", false);
472
+ const formattedOptions = pollOptions.map(option => typeof option === "string" ? { text: option } : option);
473
+ return this.api.sendPoll({
474
+ chat_id: chatId,
475
+ question: question,
476
+ options: formattedOptions,
477
+ reply_parameters: messageId ? { message_id: messageId } : undefined,
478
+ ...options,
479
+ });
480
+ }
481
+ /**
482
+ * Streaming a temporary message (Draft) for generating responses (e.g., AI).
483
+ * This ephemeral message lives for 30 seconds. After completion, it is mandatory to call a regular reply().
484
+ * @param draftId - unique stream identifier (must be > 0). Identical IDs animate changes.
485
+ * @param options - parameters object
486
+ * @returns `Promise<boolean>`
487
+ */
488
+ async replyWithDraft(draftId, options) {
489
+ const { chatId } = this.getRequiredIds("replyWithDraft", false);
490
+ return this.api.sendMessageDraft({
491
+ chat_id: chatId,
492
+ draft_id: draftId,
493
+ ...options,
494
+ });
495
+ }
496
+ /**
497
+ * Send a group of media files (album).
498
+ * Supports photos, videos, audio, documents, and new Live Photos (API 10.0).
499
+ * @param media - array of media files
500
+ * @param options - parameters object
501
+ * @returns `Promise<Message[]>`
502
+ */
503
+ async replyWithMediaGroup(media, options) {
504
+ const { chatId, messageId } = this.getRequiredIds("replyWithMediaGroup", false);
505
+ return this.api.sendMediaGroup({
506
+ chat_id: chatId,
507
+ media,
508
+ reply_parameters: messageId ? { message_id: messageId } : undefined,
509
+ ...options,
510
+ });
511
+ }
512
+ /**
513
+ * Send paid media, for viewing which the user must pay with Telegram Stars.
514
+ * @param starCount - number of stars the user must pay
515
+ * @param media - array of media files
516
+ * @param options - parameters object
517
+ * @returns `Promise<Message>`
518
+ */
519
+ async replyWithPaidMedia(starCount, media, options) {
520
+ const { chatId } = this.getRequiredIds("replyWithPaidMedia", false);
521
+ return this.api.sendPaidMedia({
522
+ chat_id: chatId,
523
+ star_count: starCount,
524
+ media,
525
+ ...options,
526
+ });
527
+ }
528
+ }
@@ -0,0 +1,8 @@
1
+ import { TelegramBotApi, Update } from "../types/telegram";
2
+ import { ReplyContext } from "./context/reply-context";
3
+ export declare class Context extends ReplyContext {
4
+ constructor(update: Update, api: TelegramBotApi);
5
+ get from(): import("../types/telegram").User | undefined;
6
+ get text(): string | undefined;
7
+ get payload(): string;
8
+ }
@@ -0,0 +1,34 @@
1
+ import { ReplyContext } from "./context/reply-context";
2
+ export class Context extends ReplyContext {
3
+ constructor(update, api) {
4
+ // Передаємо дані в BaseContext
5
+ super(update, api);
6
+ }
7
+ // Залишаємо специфічні геттери тут
8
+ get from() {
9
+ var _a, _b;
10
+ const msg = this.message;
11
+ if (msg && "from" in msg)
12
+ return msg.from;
13
+ return ((_a = this.callbackQuery) === null || _a === void 0 ? void 0 : _a.from) || ((_b = this.update.inline_query) === null || _b === void 0 ? void 0 : _b.from);
14
+ }
15
+ get text() {
16
+ const msg = this.message;
17
+ if (!msg)
18
+ return undefined;
19
+ if ("text" in msg)
20
+ return msg.text;
21
+ if ("caption" in msg)
22
+ return msg.caption;
23
+ return undefined;
24
+ }
25
+ get payload() {
26
+ const txt = this.text;
27
+ if (!txt || !txt.startsWith('/'))
28
+ return '';
29
+ const parts = txt.split(/\s+/);
30
+ if (parts.length <= 1)
31
+ return '';
32
+ return parts.slice(1).join(' ').trim();
33
+ }
34
+ }
@@ -0,0 +1,76 @@
1
+ import { KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply, InlineKeyboardButton, InlineKeyboardMarkup, LoginUrl, SwitchInlineQueryChosenChat, CopyTextButton, CallbackGame, KeyboardButtonRequestUsers, KeyboardButtonRequestChat, KeyboardButtonPollType, KeyboardButtonRequestManagedBot } from '../types/telegram';
2
+ /**
3
+ * Base interface for any button (so TypeScript knows about common fields)
4
+ */
5
+ export interface CommonButton {
6
+ text: string;
7
+ icon_custom_emoji_id?: string;
8
+ style?: string;
9
+ }
10
+ /**
11
+ * Abstract class containing common logic for all keyboard types.
12
+ * T is the button type (InlineKeyboardButton or KeyboardButton).
13
+ */
14
+ export declare abstract class BaseKeyboard<T extends CommonButton> {
15
+ protected matrix: T[][];
16
+ /** Starts a new row */
17
+ row(): this;
18
+ /**
19
+ * Adds a custom emoji to the LAST added button.
20
+ * @param emojiId Unique emoji ID (available for Premium bots)
21
+ */
22
+ customEmoji(emojiId: string): this;
23
+ /**
24
+ * Sets the style for the LAST added button.
25
+ * @param style 'danger' (red) | 'success' (green) | 'primary' (blue)
26
+ */
27
+ style(style: 'danger' | 'success' | 'primary'): this;
28
+ protected addButton(button: T): this;
29
+ protected getLastButton(): T | undefined;
30
+ }
31
+ export declare class InlineKeyboard extends BaseKeyboard<InlineKeyboardButton> {
32
+ text(text: string, callback_data: string): this;
33
+ url(text: string, url: string): this;
34
+ webApp(text: string, webAppUrl: string): this;
35
+ loginUrl(text: string, login_url: LoginUrl): this;
36
+ switchInlineQuery(text: string, query?: string): this;
37
+ switchInlineCurrentChat(text: string, query?: string): this;
38
+ switchInlineChosenChat(text: string, chosen_chat: SwitchInlineQueryChosenChat): this;
39
+ copyText(text: string, copy_text: CopyTextButton): this;
40
+ game(text: string, callback_game?: CallbackGame): this;
41
+ pay(text: string): this;
42
+ /**
43
+ * Special button for switching between InlineMenu pages
44
+ * @param text Button text
45
+ * @param menuId Menu ID
46
+ * @param pageId ID of the page to navigate to
47
+ */
48
+ menu(text: string, menuId: string, pageId: string): this;
49
+ /** Builds the final object (uses this.matrix from the base class) */
50
+ build(): InlineKeyboardMarkup;
51
+ /** Allows automatic serialization of the object to JSON */
52
+ toJSON(): InlineKeyboardMarkup;
53
+ }
54
+ export declare class ReplyKeyboard extends BaseKeyboard<KeyboardButton> {
55
+ private options;
56
+ /** Adds a regular text button */
57
+ text(text: string): this;
58
+ requestContact(text: string): this;
59
+ requestLocation(text: string): this;
60
+ requestUsers(text: string, request_users: KeyboardButtonRequestUsers): this;
61
+ requestChat(text: string, request_chat: KeyboardButtonRequestChat): this;
62
+ requestPoll(text: string, request_poll?: KeyboardButtonPollType): this;
63
+ requestManagedBot(text: string, request_managed_bot: KeyboardButtonRequestManagedBot): this;
64
+ webApp(text: string, webAppUrl: string): this;
65
+ persistent(is_persistent?: boolean): this;
66
+ selective(is_selective?: boolean): this;
67
+ resized(is_resized?: boolean): this;
68
+ oneTime(is_one_time?: boolean): this;
69
+ placeholder(text: string): this;
70
+ /** Builds the final object (uses this.matrix from the base class) */
71
+ build(): ReplyKeyboardMarkup;
72
+ /** Allows automatic serialization of the object to JSON */
73
+ toJSON(): ReplyKeyboardMarkup;
74
+ static remove(selective?: boolean): ReplyKeyboardRemove;
75
+ static forceReply(selective?: boolean, placeholder?: string): ForceReply;
76
+ }