grambot 1.0.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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +126 -0
  3. package/dist/action/action.d.ts +17 -0
  4. package/dist/action/action.d.ts.map +1 -0
  5. package/dist/action/action.js +59 -0
  6. package/dist/action/action.js.map +1 -0
  7. package/dist/conversation/conversation.d.ts +15 -0
  8. package/dist/conversation/conversation.d.ts.map +1 -0
  9. package/dist/conversation/conversation.js +346 -0
  10. package/dist/conversation/conversation.js.map +1 -0
  11. package/dist/engine/engine.d.ts +24 -0
  12. package/dist/engine/engine.d.ts.map +1 -0
  13. package/dist/engine/engine.js +847 -0
  14. package/dist/engine/engine.js.map +1 -0
  15. package/dist/grambot.d.ts +142 -0
  16. package/dist/grambot.d.ts.map +1 -0
  17. package/dist/grambot.js +204 -0
  18. package/dist/grambot.js.map +1 -0
  19. package/dist/index.d.ts +31 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +28 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/menu/button.d.ts +99 -0
  24. package/dist/menu/button.d.ts.map +1 -0
  25. package/dist/menu/button.js +157 -0
  26. package/dist/menu/button.js.map +1 -0
  27. package/dist/menu/layout.d.ts +86 -0
  28. package/dist/menu/layout.d.ts.map +1 -0
  29. package/dist/menu/layout.js +90 -0
  30. package/dist/menu/layout.js.map +1 -0
  31. package/dist/menu/list.d.ts +43 -0
  32. package/dist/menu/list.d.ts.map +1 -0
  33. package/dist/menu/list.js +60 -0
  34. package/dist/menu/list.js.map +1 -0
  35. package/dist/menu/menu.d.ts +29 -0
  36. package/dist/menu/menu.d.ts.map +1 -0
  37. package/dist/menu/menu.js +73 -0
  38. package/dist/menu/menu.js.map +1 -0
  39. package/dist/telebot.d.ts +142 -0
  40. package/dist/telebot.d.ts.map +1 -0
  41. package/dist/telebot.js +204 -0
  42. package/dist/telebot.js.map +1 -0
  43. package/dist/types.d.ts +322 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +2 -0
  46. package/dist/types.js.map +1 -0
  47. package/dist/ui/ui.d.ts +12 -0
  48. package/dist/ui/ui.d.ts.map +1 -0
  49. package/dist/ui/ui.js +39 -0
  50. package/dist/ui/ui.js.map +1 -0
  51. package/package.json +55 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dortanes
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,126 @@
1
+ <table>
2
+ <tr>
3
+ <td>
4
+
5
+ ## Grambot
6
+
7
+ [![NPM Version](https://img.shields.io/npm/v/grambot)](https://www.npmjs.com/package/grambot) [![License](https://img.shields.io/npm/l/grambot)](LICENSE)
8
+
9
+ </td>
10
+ </tr>
11
+ </table>
12
+
13
+ A declarative framework for building menu-driven Telegram bots. No boilerplate — just menus, buttons, and conversations.
14
+
15
+ [Install](#-install) • [Quick Start](#-quick-start) • [Documentation](#-documentation) • [Releases](https://github.com/dortanes/grambot/releases)
16
+
17
+ ---
18
+
19
+ ## 📦 Install
20
+
21
+ ```bash
22
+ npm install grambot grammy
23
+ ```
24
+
25
+ ## 🚀 Quick Start
26
+
27
+ ```typescript
28
+ import { Grambot } from "grambot";
29
+
30
+ const greetAction = Grambot.action(async ({ conversation }) => {
31
+ const name = await conversation.ask("What is your name?");
32
+ await conversation.say(`Hello, ${name}!`);
33
+ });
34
+
35
+ const mainMenu = Grambot.menu((layout) => {
36
+ layout.text("Welcome! Choose an option:");
37
+ layout.button("👋 Say Hello").primary().action(greetAction);
38
+ layout.button("🌐 Website").url("https://github.com/dortanes/grambot");
39
+ });
40
+
41
+ const bot = Grambot.create({
42
+ token: process.env.BOT_TOKEN!,
43
+ menu: mainMenu,
44
+ });
45
+
46
+ bot.start();
47
+ ```
48
+
49
+ ## ✨ Features
50
+
51
+ | | Feature | Description |
52
+ | --- | ----------------------- | -------------------------------------------------------- |
53
+ | 🏗️ | **Declarative Menus** | Define layouts with a fluent builder API |
54
+ | 🔄 | **Auto Navigation** | Nested menus with built-in "Back" buttons |
55
+ | 💬 | **Conversations** | Collect input with `ask()` and `form()` |
56
+ | 📝 | **Single-Message Flow** | Edits one message for a clean chat history |
57
+ | 🎨 | **Button Styling** | Colors (danger, success, primary) and custom emoji icons |
58
+ | 🛡️ | **Error Handling** | Built-in error boundary — no crashes |
59
+ | 🌐 | **i18n Support** | Localization hooks for all internal strings |
60
+ | 🔡 | **Type-Safe** | Full TypeScript with JSDoc |
61
+
62
+ ## 🎨 Button Styling
63
+
64
+ Color your buttons and add custom emoji icons (Bot API 9.4+):
65
+
66
+ ```typescript
67
+ layout.button("Delete").danger(); // 🔴 Red
68
+ layout.button("Confirm").success(); // 🟢 Green
69
+ layout.button("Highlight").primary(); // 🔵 Blue
70
+
71
+ layout.button("VIP").icon("custom_emoji_id");
72
+ ```
73
+
74
+ ## ⚙️ Configuration
75
+
76
+ ```typescript
77
+ const bot = Grambot.create({
78
+ token: "BOT_TOKEN",
79
+ menu: mainMenu,
80
+
81
+ // Resolve user data from DB on every update
82
+ resolveUser: async (ctx) => {
83
+ return await db.users.find(ctx.from.id);
84
+ },
85
+
86
+ // Localize internal strings
87
+ translator: (key, ctx) => i18n.t(ctx.from.language_code, key),
88
+
89
+ // Custom error handler (default: console.error)
90
+ onError: (error, ctx) => {
91
+ logger.error("Bot error", { error, chatId: ctx.chat?.id });
92
+ },
93
+ });
94
+ ```
95
+
96
+ ## 📖 Documentation
97
+
98
+ | Guide | Description |
99
+ | ------------------------------------------------ | ------------------------------------------- |
100
+ | [Menus and Navigation](docs/menus.md) | Layouts, rows, buttons, styling, pagination |
101
+ | [Conversations and Forms](docs/conversations.md) | User input, validation, multi-step forms |
102
+ | [Actions and Triggers](docs/actions.md) | Commands, regex, inline handlers |
103
+ | [State Management](docs/state.md) | Sessions, storage adapters, user resolution |
104
+ | [Advanced Patterns](docs/advanced.md) | i18n, webhooks, manual rendering |
105
+
106
+ ## Development
107
+
108
+ ```bash
109
+ git clone https://github.com/dortanes/grambot.git
110
+ cd grambot
111
+
112
+ npm install
113
+
114
+ npm run build
115
+
116
+ BOT_TOKEN=your_token npm run start:example
117
+ ```
118
+
119
+ ## License
120
+
121
+ [MIT](LICENSE)
122
+
123
+ <p align="center" style="margin-top: 40px">
124
+ Made with ❤️ by <a href="https://github.com/dortanes">dortanes</a><br/>
125
+ (pls star this repo if you find it useful)
126
+ </p>
@@ -0,0 +1,17 @@
1
+ import type { ActionRef, ActionHandler } from "../types.js";
2
+ /**
3
+ * Returns all actions created via createAction().
4
+ * @internal
5
+ */
6
+ export declare function getGlobalActions(): ActionRef<any>[];
7
+ /**
8
+ * Creates a typed action reference.
9
+ *
10
+ * Use `Grambot.action<PayloadType>(handler)` to define reusable handlers
11
+ * that can be attached to buttons.
12
+ *
13
+ * @param handler - The function that handles the action logic.
14
+ * @returns An {@link ActionRef} object.
15
+ */
16
+ export declare function createAction<P = undefined>(handler: ActionHandler<P>): ActionRef<P>;
17
+ //# sourceMappingURL=action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../src/action/action.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI5D;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAEnD;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,SAAS,EACxC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GACxB,SAAS,CAAC,CAAC,CAAC,CAqCd"}
@@ -0,0 +1,59 @@
1
+ import { randomUUID } from "node:crypto";
2
+ const globalActions = new Set();
3
+ /**
4
+ * Returns all actions created via createAction().
5
+ * @internal
6
+ */
7
+ export function getGlobalActions() {
8
+ return Array.from(globalActions);
9
+ }
10
+ /**
11
+ * Creates a typed action reference.
12
+ *
13
+ * Use `Grambot.action<PayloadType>(handler)` to define reusable handlers
14
+ * that can be attached to buttons.
15
+ *
16
+ * @param handler - The function that handles the action logic.
17
+ * @returns An {@link ActionRef} object.
18
+ */
19
+ export function createAction(handler) {
20
+ const ref = {
21
+ __Grambot_action: true,
22
+ id: `a${randomUUID().slice(0, 6)}`,
23
+ handler,
24
+ triggers: {},
25
+ /**
26
+ * Set a command trigger for this action.
27
+ * @param name - The command name (e.g., "help").
28
+ */
29
+ command(name) {
30
+ if (!this.triggers)
31
+ this.triggers = {};
32
+ this.triggers.commands = [...(this.triggers.commands || []), name];
33
+ return this;
34
+ },
35
+ /**
36
+ * Set a word/phrase trigger for this action.
37
+ * @param text - The exact text to match.
38
+ */
39
+ word(text) {
40
+ if (!this.triggers)
41
+ this.triggers = {};
42
+ this.triggers.words = [...(this.triggers.words || []), text];
43
+ return this;
44
+ },
45
+ /**
46
+ * Set a regex trigger for this action.
47
+ * @param pattern - The regular expression to match.
48
+ */
49
+ regexp(pattern) {
50
+ if (!this.triggers)
51
+ this.triggers = {};
52
+ this.triggers.regexps = [...(this.triggers.regexps || []), pattern];
53
+ return this;
54
+ },
55
+ };
56
+ globalActions.add(ref);
57
+ return ref;
58
+ }
59
+ //# sourceMappingURL=action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.js","sourceRoot":"","sources":["../../src/action/action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;AAEhD;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAyB;IAEzB,MAAM,GAAG,GAAiB;QACxB,gBAAgB,EAAE,IAAI;QACtB,EAAE,EAAE,IAAI,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;QAClC,OAAO;QACP,QAAQ,EAAE,EAAE;QACZ;;;WAGG;QACH,OAAO,CAAC,IAAY;YAClB,IAAI,CAAC,IAAI,CAAC,QAAQ;gBAAE,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;YACvC,IAAI,CAAC,QAAQ,CAAC,QAAQ,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;YACnE,OAAO,IAAI,CAAC;QACd,CAAC;QACD;;;WAGG;QACH,IAAI,CAAC,IAAY;YACf,IAAI,CAAC,IAAI,CAAC,QAAQ;gBAAE,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;YACvC,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;YAC7D,OAAO,IAAI,CAAC;QACd,CAAC;QACD;;;WAGG;QACH,MAAM,CAAC,OAAe;YACpB,IAAI,CAAC,IAAI,CAAC,QAAQ;gBAAE,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;YACvC,IAAI,CAAC,QAAQ,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;YACpE,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;IAEF,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { GrambotContext, GrambotConversation, ConversationHelper, Translator } from "../types.js";
2
+ /**
3
+ * Creates a ConversationHelper bound to a Grammy Conversation instance.
4
+ *
5
+ * This is the runtime adapter providing `ask()` and `form()` helpers.
6
+ * It manages message editing, input validation, and cancellation.
7
+ *
8
+ * @param conversation - The grammy conversation instance.
9
+ * @param ctx - The initial Grambot context.
10
+ * @param translator - Optional function for localizing internal strings.
11
+ * @returns A {@link ConversationHelper} object.
12
+ * @internal
13
+ */
14
+ export declare function createConversationHelper(conversation: GrambotConversation, ctx: GrambotContext, translator?: Translator, navigate?: (menu?: any) => Promise<void>): ConversationHelper;
15
+ //# sourceMappingURL=conversation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/conversation/conversation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAOlB,UAAU,EAMX,MAAM,aAAa,CAAC;AAoFrB;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,mBAAmB,EACjC,GAAG,EAAE,cAAc,EACnB,UAAU,CAAC,EAAE,UAAU,EACvB,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,GACvC,kBAAkB,CA+RpB"}
@@ -0,0 +1,346 @@
1
+ import { InlineKeyboard } from "grammy";
2
+ // ─── Ask keyboard builder (for button-based ask) ──────────────────────────────
3
+ /**
4
+ * Internal implementation of the button in an `ask` prompt.
5
+ * @internal
6
+ */
7
+ class AskKeyboardButtonImpl {
8
+ text;
9
+ _id;
10
+ _url;
11
+ _action;
12
+ _menu;
13
+ _payload;
14
+ _forceRow = false;
15
+ constructor(text) {
16
+ this.text = text;
17
+ }
18
+ /** Set the button ID (stored in callback data) */
19
+ id(value) {
20
+ this._id = value;
21
+ return this;
22
+ }
23
+ url(value) {
24
+ this._url = value;
25
+ return this;
26
+ }
27
+ action(handler) {
28
+ this._action = handler;
29
+ return this;
30
+ }
31
+ menu(ref) {
32
+ this._menu = ref;
33
+ return this;
34
+ }
35
+ navigate(ref) {
36
+ this._menu = ref;
37
+ return this;
38
+ }
39
+ payload(data) {
40
+ this._payload = data;
41
+ return this;
42
+ }
43
+ row() {
44
+ this._forceRow = true;
45
+ return this;
46
+ }
47
+ }
48
+ /**
49
+ * Internal implementation of the keyboard builder in an `ask` prompt.
50
+ * @internal
51
+ */
52
+ class AskKeyboardImpl {
53
+ buttons = [];
54
+ _maxPerRow;
55
+ /** Add a button to the prompt keyboard */
56
+ button(text) {
57
+ const btn = new AskKeyboardButtonImpl(text);
58
+ this.buttons.push(btn);
59
+ return btn;
60
+ }
61
+ /** Set maximum number of buttons per row */
62
+ maxPerRow(count) {
63
+ this._maxPerRow = count;
64
+ }
65
+ }
66
+ /** @internal */
67
+ function isFunction(value) {
68
+ return typeof value === "function";
69
+ }
70
+ /**
71
+ * Creates a ConversationHelper bound to a Grammy Conversation instance.
72
+ *
73
+ * This is the runtime adapter providing `ask()` and `form()` helpers.
74
+ * It manages message editing, input validation, and cancellation.
75
+ *
76
+ * @param conversation - The grammy conversation instance.
77
+ * @param ctx - The initial Grambot context.
78
+ * @param translator - Optional function for localizing internal strings.
79
+ * @returns A {@link ConversationHelper} object.
80
+ * @internal
81
+ */
82
+ export function createConversationHelper(conversation, ctx, translator, navigate) {
83
+ const tr = (key, defaultText, options) => translator ? translator(key, ctx, options) : defaultText;
84
+ // Track the last bot message ID to edit it
85
+ let lastMessageId = conversation.session?.__Grambot_last_msg_id ?? ctx.callbackQuery?.message?.message_id;
86
+ const chatId = ctx.chat?.id;
87
+ /**
88
+ * Helper to edit the previous prompt or send a new message.
89
+ * Manages the "single message" conversation flow.
90
+ */
91
+ async function editOrReply(text, keyboard, parseMode) {
92
+ if (lastMessageId && chatId) {
93
+ try {
94
+ await ctx.api.editMessageText(chatId, lastMessageId, text, { reply_markup: keyboard, parse_mode: parseMode });
95
+ return;
96
+ }
97
+ catch (e) {
98
+ // If message is not modified, we are fine
99
+ if (e.description?.includes("message is not modified")) {
100
+ return;
101
+ }
102
+ // If edit fails (e.g., transition from photo to text), we try to delete and send new
103
+ try {
104
+ await ctx.api.deleteMessage(chatId, lastMessageId);
105
+ }
106
+ catch { }
107
+ }
108
+ }
109
+ const msg = await ctx.reply(text, { reply_markup: keyboard, parse_mode: parseMode });
110
+ lastMessageId = msg.message_id;
111
+ const conv = conversation;
112
+ if (!conv.session)
113
+ conv.session = {};
114
+ conv.session.__Grambot_last_msg_id = lastMessageId;
115
+ }
116
+ /**
117
+ * Universal `ask` helper.
118
+ * - If a builder function is passed, displays a keyboard of choices.
119
+ * - Otherwise, waits for text/number/photo input.
120
+ */
121
+ async function ask(question, optionsOrBuilder, maybeBuilder) {
122
+ // Normalize arguments
123
+ let opts = {};
124
+ let builder;
125
+ if (isFunction(optionsOrBuilder)) {
126
+ builder = optionsOrBuilder;
127
+ }
128
+ else if (optionsOrBuilder) {
129
+ opts = optionsOrBuilder;
130
+ builder = maybeBuilder;
131
+ }
132
+ const translatedQuestion = tr(question, question, opts.replace);
133
+ // Branch 1: inline-keyboard selection
134
+ if (builder) {
135
+ const kb = new AskKeyboardImpl();
136
+ builder(kb);
137
+ const inlineKb = new InlineKeyboard();
138
+ let currentInRow = 0;
139
+ for (const btn of kb.buttons) {
140
+ if (btn._forceRow || (kb._maxPerRow && currentInRow >= kb._maxPerRow)) {
141
+ inlineKb.row();
142
+ currentInRow = 0;
143
+ }
144
+ const btnId = btn._id ?? btn.text;
145
+ const btnLabel = tr(btn.text, btn.text, opts.replace);
146
+ inlineKb.text(btnLabel, `ask:${btnId}`);
147
+ currentInRow++;
148
+ }
149
+ const cancelText = tr("Grambot.cancel", "🚫 Cancel");
150
+ inlineKb.row().text(cancelText, "ask:__cancel__");
151
+ await editOrReply(translatedQuestion, inlineKb, opts.parseMode);
152
+ const cbCtx = await conversation.waitForCallbackQuery(/^ask:/, {
153
+ otherwise: async (c) => {
154
+ try {
155
+ await c.deleteMessage();
156
+ }
157
+ catch { }
158
+ await c.answerCallbackQuery(tr("Grambot.conversation.use_buttons", "Please use the buttons above."));
159
+ },
160
+ });
161
+ await cbCtx.answerCallbackQuery();
162
+ const data = cbCtx.callbackQuery.data.replace(/^ask:/, "");
163
+ if (data === "__cancel__") {
164
+ await navigateTo();
165
+ return undefined;
166
+ }
167
+ return data;
168
+ }
169
+ // Branch 2: text / number / photo input
170
+ const fieldType = opts.type ?? "text";
171
+ const cancelText = tr("Grambot.cancel", "🚫 Cancel");
172
+ const cancelKb = new InlineKeyboard().text(cancelText, "cancel_conversation");
173
+ let currentPrompt = translatedQuestion;
174
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
175
+ let isError = false;
176
+ // Loop until valid input
177
+ // eslint-disable-next-line no-constant-condition
178
+ while (true) {
179
+ await editOrReply(currentPrompt, cancelKb, opts.parseMode);
180
+ if (fieldType === "photo") {
181
+ const updateCtx = await conversation.waitFor(["message:photo", "callback_query:data"]);
182
+ if (updateCtx.callbackQuery?.data === "cancel_conversation") {
183
+ await updateCtx.answerCallbackQuery();
184
+ await navigateTo();
185
+ return undefined;
186
+ }
187
+ if (!updateCtx.message?.photo) {
188
+ try {
189
+ await updateCtx.deleteMessage();
190
+ }
191
+ catch { }
192
+ const err = opts.errorMessage ? tr(opts.errorMessage, opts.errorMessage, opts.replace) : tr("Grambot.conversation.photo_error", "Please send a photo.");
193
+ currentPrompt = `${err}\n\n${translatedQuestion}`;
194
+ isError = true;
195
+ continue;
196
+ }
197
+ try {
198
+ await updateCtx.deleteMessage();
199
+ }
200
+ catch { }
201
+ const photos = updateCtx.message.photo;
202
+ if (photos && photos.length > 0) {
203
+ const val = photos[photos.length - 1].file_id;
204
+ if (opts.validate && !(await opts.validate(val))) {
205
+ const err = opts.errorMessage ? tr(opts.errorMessage, opts.errorMessage, opts.replace) : tr("Grambot.conversation.invalid_error", "Invalid input. Try again.");
206
+ currentPrompt = `${err}\n\n${translatedQuestion}`;
207
+ isError = true;
208
+ continue;
209
+ }
210
+ return val;
211
+ }
212
+ }
213
+ // text / number
214
+ const updateCtx = await conversation.waitFor(["message:text", "callback_query:data"]);
215
+ if (updateCtx.callbackQuery?.data === "cancel_conversation") {
216
+ await updateCtx.answerCallbackQuery();
217
+ await navigateTo();
218
+ return undefined;
219
+ }
220
+ if (!updateCtx.message?.text) {
221
+ try {
222
+ await updateCtx.deleteMessage();
223
+ }
224
+ catch { }
225
+ const err = opts.errorMessage ? tr(opts.errorMessage, opts.errorMessage, opts.replace) : tr("Grambot.conversation.text_error", "Please send a text message.");
226
+ currentPrompt = `${err}\n\n${translatedQuestion}`;
227
+ isError = true;
228
+ continue;
229
+ }
230
+ try {
231
+ await updateCtx.deleteMessage();
232
+ }
233
+ catch { }
234
+ const raw = updateCtx.message.text;
235
+ if (fieldType === "number") {
236
+ const n = Number(raw);
237
+ if (Number.isNaN(n)) {
238
+ const err = opts.errorMessage ? tr(opts.errorMessage, opts.errorMessage, opts.replace) : tr("Grambot.conversation.number_error", "Please send a valid number.");
239
+ currentPrompt = `${err}\n\n${translatedQuestion}`;
240
+ isError = true;
241
+ continue;
242
+ }
243
+ if (opts.validate && !(await opts.validate(n))) {
244
+ const err = opts.errorMessage ? tr(opts.errorMessage, opts.errorMessage, opts.replace) : tr("Grambot.conversation.invalid_error", "Invalid input. Try again.");
245
+ currentPrompt = `${err}\n\n${translatedQuestion}`;
246
+ isError = true;
247
+ continue;
248
+ }
249
+ return n;
250
+ }
251
+ if (opts.validate && !(await opts.validate(raw))) {
252
+ const err = opts.errorMessage ? tr(opts.errorMessage, opts.errorMessage, opts.replace) : tr("Grambot.conversation.invalid_error", "Invalid input. Try again.");
253
+ currentPrompt = `${err}\n\n${translatedQuestion}`;
254
+ isError = true;
255
+ continue;
256
+ }
257
+ return raw;
258
+ }
259
+ }
260
+ /**
261
+ * Collected a multi-field form.
262
+ */
263
+ async function form(fields) {
264
+ const result = {};
265
+ for (const field of fields) {
266
+ const val = await ask(field.question, {
267
+ type: field.type,
268
+ });
269
+ if (val === undefined)
270
+ return undefined;
271
+ result[field.name] = val;
272
+ }
273
+ return result;
274
+ }
275
+ async function say(text, optionsOrBuilder, maybeBuilder) {
276
+ let opts = {};
277
+ let builder;
278
+ if (isFunction(optionsOrBuilder)) {
279
+ builder = optionsOrBuilder;
280
+ }
281
+ else if (optionsOrBuilder) {
282
+ opts = optionsOrBuilder;
283
+ builder = maybeBuilder;
284
+ }
285
+ const translated = tr(text, text, opts.replace);
286
+ let kb;
287
+ if (builder) {
288
+ const askKb = new AskKeyboardImpl();
289
+ builder(askKb);
290
+ kb = new InlineKeyboard();
291
+ let currentInRow = 0;
292
+ for (const btn of askKb.buttons) {
293
+ if (btn._forceRow || (askKb._maxPerRow && currentInRow >= askKb._maxPerRow)) {
294
+ kb.row();
295
+ currentInRow = 0;
296
+ }
297
+ const label = tr(btn.text, btn.text, opts.replace);
298
+ if (btn._url) {
299
+ kb.url(label, btn._url);
300
+ }
301
+ else if (btn._menu) {
302
+ kb.text(label, `n:${btn._menu.id}`);
303
+ }
304
+ else if (btn._action) {
305
+ if (typeof btn._action === "function") {
306
+ // In say(), inline functions don't have a stable way to be triggered
307
+ // because there's no loop.
308
+ kb.text(label, `ask_fn_say:${btn._id ?? btn.text}`);
309
+ }
310
+ else {
311
+ const p = btn._payload;
312
+ const pStr = p && Object.keys(p).length === 1 && "id" in p ? String(p.id) : (p ? JSON.stringify(p) : "");
313
+ kb.text(label, `a:${btn._action.id}/:${pStr}`);
314
+ }
315
+ }
316
+ else {
317
+ kb.text(label, `ask:${btn._id ?? btn.text}`);
318
+ }
319
+ currentInRow++;
320
+ }
321
+ }
322
+ await editOrReply(translated, kb, opts.parseMode);
323
+ }
324
+ async function deletePrompt() {
325
+ if (lastMessageId && chatId) {
326
+ try {
327
+ await ctx.api.deleteMessage(chatId, lastMessageId);
328
+ }
329
+ catch (e) {
330
+ // ignore errors if already deleted
331
+ }
332
+ lastMessageId = undefined;
333
+ const conv = conversation;
334
+ if (conv.session) {
335
+ conv.session.__Grambot_last_msg_id = undefined;
336
+ }
337
+ }
338
+ }
339
+ async function navigateTo(menu) {
340
+ if (navigate) {
341
+ await navigate(menu);
342
+ }
343
+ }
344
+ return { ask, form, say, delete: deletePrompt, navigate: navigateTo };
345
+ }
346
+ //# sourceMappingURL=conversation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation.js","sourceRoot":"","sources":["../../src/conversation/conversation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { Bot } from "grammy";
2
+ import type { GrambotContext, GrambotConfig, MenuRef, Translator } from "../types.js";
3
+ /**
4
+ * Installs the Grambot engine onto a Grammy bot.
5
+ *
6
+ * - Registers session and conversation plugins.
7
+ * - Resolves and registers all menus and actions.
8
+ * - Sets up text and callback query handlers.
9
+ *
10
+ * @param bot - The grammy bot instance.
11
+ * @param rootRef - The root menu of the bot.
12
+ * @param config - Framework configuration.
13
+ */
14
+ export declare function installMenu(bot: Bot<GrambotContext>, rootRef: MenuRef, config: GrambotConfig): Promise<void>;
15
+ /**
16
+ * Sends a specific menu to a chat programmatically.
17
+ *
18
+ * @param bot - The grammy bot instance.
19
+ * @param chatId - Target chat ID.
20
+ * @param menuRef - The menu to send.
21
+ * @param ctx - Current Grambot context.
22
+ */
23
+ export declare function sendMenu(bot: Bot<GrambotContext>, chatId: number, menuRef: MenuRef, ctx: GrambotContext, translator?: Translator): Promise<void>;
24
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAA2B,MAAM,QAAQ,CAAC;AAEtD,OAAO,KAAK,EAEV,cAAc,EAEd,aAAa,EACb,OAAO,EAMP,UAAU,EACX,MAAM,aAAa,CAAC;AAkVrB;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,GAAG,CAAC,cAAc,CAAC,EACxB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CAgnBf;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,GAAG,CAAC,cAAc,CAAC,EACxB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,cAAc,EACnB,UAAU,CAAC,EAAE,UAAU,GACtB,OAAO,CAAC,IAAI,CAAC,CASf"}