telekit 2.4.0b0__tar.gz → 2.5.0__tar.gz
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.
- {telekit-2.4.0b0 → telekit-2.5.0}/PKG-INFO +122 -96
- {telekit-2.4.0b0 → telekit-2.5.0}/README.md +82 -26
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/__init__.py +14 -1
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_buildtext/formatter.py +101 -17
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_buildtext/styles.py +77 -60
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_chain_base.py +0 -1
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_chain_entry_logic.py +4 -4
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_chain_inline_keyboards_logic.py +69 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_handler.py +10 -1
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_init.py +2 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_inline_buttons.py +99 -11
- telekit-2.5.0/telekit/_inline_keyboard.py +719 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_input_handler.py +3 -2
- telekit-2.5.0/telekit/_reply_keyboard.py +521 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_telekit_dsl/mixin.py +1 -1
- telekit-2.5.0/telekit/_text_builder.py +529 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_version.py +1 -1
- telekit-2.5.0/telekit/chat.py +101 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/debug.py +1 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/example_handlers/__init__.py +2 -0
- telekit-2.5.0/telekit/example/example_handlers/article.py +66 -0
- telekit-2.5.0/telekit/example/example_handlers/counter.py +84 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/example_handlers/on_text.py +20 -15
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/example_handlers/start.py +4 -2
- telekit-2.5.0/telekit/example/example_handlers/style.py +73 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/example_handlers/text_document.py +1 -1
- telekit-2.5.0/telekit/html_text.py +812 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/inline_buttons.py +10 -0
- telekit-2.5.0/telekit/reply_buttons.py +254 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/senders.py +43 -9
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/traits/__init__.py +1 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/traits/calendar_pick.py +180 -195
- telekit-2.5.0/telekit/traits/paginated_text.py +378 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/types.py +45 -10
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/utils.py +45 -9
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit.egg-info/PKG-INFO +122 -96
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit.egg-info/SOURCES.txt +9 -0
- telekit-2.4.0b0/telekit/example/example_handlers/counter.py +0 -46
- {telekit-2.4.0b0 → telekit-2.5.0}/LICENSE +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/setup.cfg +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/setup.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_buildtext/__init__.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_callback_query_handler.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_chain.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_chapters/__init__.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_chapters/chapters.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_logger.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_on.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_snapvault/__init__.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_snapvault/snapcode.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_snapvault/snapvault.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_state.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_telekit_dsl/__init__.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_telekit_dsl/parser/__init__.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_telekit_dsl/parser/builder.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_telekit_dsl/parser/canvas_parser.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_telekit_dsl/parser/lexer.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_telekit_dsl/parser/nodes.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_telekit_dsl/parser/parser.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_telekit_dsl/parser/token.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_telekit_dsl/telekit_dsl.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_telekit_dsl/telekit_orm.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_timeout.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_trait.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/_user.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/dices.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/__init__.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/example_handlers/calendar.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/example_handlers/complete_hotel.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/example_handlers/dsl.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/example_handlers/entry.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/example_handlers/faq.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/example_handlers/hotel.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/example_handlers/pages.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/example_handlers/pyapi.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/example_handlers/qr.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/example_handlers/quiz.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/example_handlers/spells.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/example/example_server.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/parameters.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/scheduler.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/server.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/styles.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/traits/paginated_choice.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit/traits/track_handoff_origin.py +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit.egg-info/dependency_links.txt +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit.egg-info/requires.txt +0 -0
- {telekit-2.4.0b0 → telekit-2.5.0}/telekit.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: telekit
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.0
|
|
4
4
|
Summary: Declarative, developer-friendly library for building Telegram bots
|
|
5
5
|
Home-page: https://github.com/Romashkaa/telekit
|
|
6
6
|
Author: romashka
|
|
@@ -75,7 +75,7 @@ Telekit comes with a [built-in DSL](https://github.com/Romashkaa/telekit/blob/ma
|
|
|
75
75
|
}
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
> See the [full example](https://github.com/Romashkaa/telekit/blob/main/docs/examples/
|
|
78
|
+
> See the [full example](https://github.com/Romashkaa/telekit/blob/main/docs/examples/complete_hotel.md)
|
|
79
79
|
|
|
80
80
|
Even in its beta stage, Telekit accelerates bot development, offering typed **command parameters**, **text styling** via `Bold()`, `Italic()`, a built-in declarative **calendar picker**, emoji **game results** for `🎲 🎯 🏀 ⚽ 🎳 🎰`, and much more out of the box. Its declarative design makes bots easier to read, maintain, and extend.
|
|
81
81
|
|
|
@@ -133,36 +133,91 @@ The `handle` method sends a message and registers `handle_name` as the next step
|
|
|
133
133
|
|
|
134
134
|
### Inline Keyboards
|
|
135
135
|
|
|
136
|
-
|
|
136
|
+
The fastest way to add buttons to a message. Pass a plain `dict` where each key is the button label and each value is the callback to invoke when pressed:
|
|
137
137
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
self.
|
|
142
|
-
|
|
143
|
-
choices={
|
|
144
|
-
"Option 1": "Value 1",
|
|
145
|
-
"Option 2": "Value 2",
|
|
146
|
-
"Option 3": [3, "Yes, it's an array"],
|
|
138
|
+
```python
|
|
139
|
+
self.chain.set_inline_keyboard(
|
|
140
|
+
{
|
|
141
|
+
"✏️ Change": self.change_name,
|
|
142
|
+
"❌ Delete": self.delete,
|
|
147
143
|
}
|
|
148
144
|
)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`row_width` controls how many buttons appear per row:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
self.chain.set_inline_keyboard(
|
|
151
|
+
{
|
|
152
|
+
"One": self.one,
|
|
153
|
+
"Two": self.two,
|
|
154
|
+
"Three": self.three,
|
|
155
|
+
"Four": self.four,
|
|
156
|
+
"Five": self.five,
|
|
157
|
+
},
|
|
158
|
+
row_width=(3, 2) # first row: 3 buttons, second row: 2
|
|
159
|
+
)
|
|
160
|
+
```
|
|
149
161
|
|
|
150
|
-
|
|
151
|
-
|
|
162
|
+
```
|
|
163
|
+
╭──────────┬──────────┬──────────╮
|
|
164
|
+
│ One │ Two │ Three │
|
|
165
|
+
├──────────┴──┬───────┴──────────┤
|
|
166
|
+
│ Four │ Five │
|
|
167
|
+
╰─────────────┴──────────────────╯
|
|
152
168
|
```
|
|
153
169
|
|
|
154
|
-
|
|
170
|
+
**Need more control?**
|
|
155
171
|
|
|
156
|
-
|
|
172
|
+
When you need precise row layout or conditional buttons, use `InlineKeyboard` — a fluent builder that composes keyboards step by step:
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
self.chain.set_keyboard(
|
|
176
|
+
InlineKeyboard()
|
|
177
|
+
.add_callback("-", self.decrement, style="danger")
|
|
178
|
+
.add_callback("+", self.increment, style="success")
|
|
179
|
+
.row()
|
|
180
|
+
.add_callback("↺ Reset", self.reset)
|
|
181
|
+
)
|
|
182
|
+
```
|
|
157
183
|
|
|
158
|
-
```py
|
|
159
|
-
self.chain.set_inline_keyboard({
|
|
160
|
-
"« Back": self.display_previous_page,
|
|
161
|
-
"Next »": self.display_next_page,
|
|
162
|
-
})
|
|
163
184
|
```
|
|
185
|
+
╭──────────┬──────────╮
|
|
186
|
+
│ - │ + │
|
|
187
|
+
├──────────┴──────────┤
|
|
188
|
+
│ ↺ Reset │
|
|
189
|
+
╰─────────────────────╯
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
> `InlineKeyboard` is built by chaining method calls. Just call `.row()` to start a new row.
|
|
193
|
+
|
|
194
|
+
**Not just callback buttons**
|
|
164
195
|
|
|
165
|
-
|
|
196
|
+
| **Method** | **Description** |
|
|
197
|
+
| --------------------- | ---------------------------------------------------------------- |
|
|
198
|
+
| `add_callback(...)` | Button that fires a callback function. |
|
|
199
|
+
| `add_link(...)` | Button that opens a URL. |
|
|
200
|
+
| `add_copy(...)` | Button that copies text to the clipboard. |
|
|
201
|
+
| `add_alert(...)` | Button that shows a popup alert dialog. |
|
|
202
|
+
| `add_notification(...)` | Button that shows a brief top-of-chat notification. |
|
|
203
|
+
| `add_static(...)` | Decorative button with no action. |
|
|
204
|
+
| `add_webapp(...)` | Button that opens a Telegram Mini App. |
|
|
205
|
+
| `add_suggest(...)` | Button that simulates the user sending a message. |
|
|
206
|
+
|
|
207
|
+
### Reply Keyboards
|
|
208
|
+
|
|
209
|
+
Unlike inline keyboards, reply keyboards replace the user's system keyboard with buttons shown at the bottom of the chat. Tapping a button either sends its text as a regular message or triggers a system action, such as sharing a phone number or location.
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
self.chain.set_keyboard(
|
|
213
|
+
ReplyKeyboard(one_time_keyboard=True)
|
|
214
|
+
.add_text("Hello!")
|
|
215
|
+
.add_text("Hi")
|
|
216
|
+
.row()
|
|
217
|
+
.add_contact("📱 Share phone")
|
|
218
|
+
.add_location("📍 Share location")
|
|
219
|
+
)
|
|
220
|
+
```
|
|
166
221
|
|
|
167
222
|
### Command Parameters
|
|
168
223
|
|
|
@@ -186,7 +241,7 @@ class GreetHandler(telekit.Handler):
|
|
|
186
241
|
|
|
187
242
|
Now `/greet 64 "Alice Reingold"` or `/greet 128 Dracula` are parsed automatically.
|
|
188
243
|
|
|
189
|
-
> [!
|
|
244
|
+
> [!NOTE]
|
|
190
245
|
> If arguments are invalid or missing, you simply receive `None` and decide how to respond.
|
|
191
246
|
|
|
192
247
|
### Dialogue
|
|
@@ -242,7 +297,7 @@ self.chain.sender.send_chat_action(ChatAction.TYPING) # Send chat action. Use en
|
|
|
242
297
|
```
|
|
243
298
|
|
|
244
299
|
> [!NOTE]
|
|
245
|
-
> Telekit automatically decides whether to use
|
|
300
|
+
> Telekit automatically decides whether to use `bot.send_message` or `bot.send_photo` based on the content
|
|
246
301
|
|
|
247
302
|
### Styles
|
|
248
303
|
|
|
@@ -288,7 +343,7 @@ If you prefer not to write dialog logic in Python, you can use the built-in DSL
|
|
|
288
343
|
```py
|
|
289
344
|
import telekit
|
|
290
345
|
|
|
291
|
-
class QuizHandler(telekit.
|
|
346
|
+
class QuizHandler(telekit.DSLHandler):
|
|
292
347
|
@classmethod
|
|
293
348
|
def init_handler(cls) -> None:
|
|
294
349
|
cls.analyze_string(script)
|
|
@@ -338,7 +393,7 @@ telekit.Server(BOT_TOKEN).polling()
|
|
|
338
393
|
- Jinja template engine
|
|
339
394
|
|
|
340
395
|
<details>
|
|
341
|
-
<summary
|
|
396
|
+
<summary>🎆 Click to see what you can do with the DSL</summary>
|
|
342
397
|
<table>
|
|
343
398
|
<tr>
|
|
344
399
|
<td><img src="./docs/images/telekit_example_7.jpg" alt="Telekit Example 7" width="300"></td>
|
|
@@ -351,7 +406,8 @@ telekit.Server(BOT_TOKEN).polling()
|
|
|
351
406
|
</table>
|
|
352
407
|
</details>
|
|
353
408
|
|
|
354
|
-
|
|
409
|
+
> [!TIP]
|
|
410
|
+
> You can find a [full quiz example](https://github.com/Romashkaa/telekit/blob/main/docs/examples/complete_hotel.md) and [DSL reference](https://github.com/Romashkaa/telekit/blob/main/docs/tutorial/11_telekit_dsl.md) in the repository.
|
|
355
411
|
|
|
356
412
|
### Traits
|
|
357
413
|
|
|
@@ -421,72 +477,42 @@ It tries to make Telegram bot development easier.
|
|
|
421
477
|
|
|
422
478
|
---
|
|
423
479
|
|
|
424
|
-
# Changes in version 2.
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
`RESTRICTED` class attribute. Set `DEFAULT_TIMEOUT` to control the fallback timeout,
|
|
464
|
-
and `DEFAULT_CONFIG` to provide a safe base config.
|
|
465
|
-
|
|
466
|
-
```python
|
|
467
|
-
class SafeDSL(telekit.InstanceDSLHandler):
|
|
468
|
-
RESTRICTED: list[RestrictedToken] = ["hook", "jinja", "redirect", "handoff", "config"]
|
|
469
|
-
DEFAULT_TIMEOUT = 120
|
|
470
|
-
DEFAULT_CONFIG = {"template": "vars"}
|
|
471
|
-
```
|
|
472
|
-
|
|
473
|
-
| **Token** | **Effect** |
|
|
474
|
-
| -------------- | ----------------------------------------------------------------------------------------------- |
|
|
475
|
-
| `"handoff"` | Disables `handoff` button type (cross-handler transitions). |
|
|
476
|
-
| `"redirect"` | Disables `redirect` button type (simulated user messages). |
|
|
477
|
-
| `"hook"` | Removes all `on_enter`, `on_enter_once`, `on_exit`, `on_timeout` hooks. |
|
|
478
|
-
| `"jinja"` | Forces template engine to `"vars"`; Jinja is never executed. |
|
|
479
|
-
| `"timeout"` | Ignores per-script `timeout_time`; uses `DEFAULT_TIMEOUT` only. |
|
|
480
|
-
| `"config"` | Replaces script config with `DEFAULT_CONFIG`; `vars_*` keys are preserved unless `"vars"` is also set. |
|
|
481
|
-
| `"vars"` | Removes all `vars_*` keys and disables `{{variable}}` substitution. |
|
|
482
|
-
| `"images"` | Strips `image` field from every scene. |
|
|
483
|
-
| `"links"` | Disables `link` button type (external URLs). |
|
|
484
|
-
| `"suggest"` | Disables `suggest` button type (pre-filled entry suggestions). |
|
|
485
|
-
| `"entry"` | Disables entry handlers (free-text input routing). |
|
|
486
|
-
| `"next"` | Disables `next` magic scene navigation. |
|
|
487
|
-
| `"back"` | Disables `back` magic scene navigation. |
|
|
488
|
-
|
|
489
|
-
## Others
|
|
490
|
-
|
|
491
|
-
- Enhanced `Debug` class with callback query tracing functionality.
|
|
492
|
-
- Refactored `BaseSender` to use `send_or_handle_error`.
|
|
480
|
+
# Changes in version 2.5.0
|
|
481
|
+
|
|
482
|
+
### v2.5.0`b0`
|
|
483
|
+
- Added support for t-strings (PEP 750, Python 3.14+) in `TextEntity`.
|
|
484
|
+
|
|
485
|
+
### v2.5.0`b1`
|
|
486
|
+
- Added `Sender.send_message` method.
|
|
487
|
+
- Added `utils.make_mention` utility for generating `tg://user?id=` mention links.
|
|
488
|
+
- Added new inline button types to `inline_buttons`:
|
|
489
|
+
- `ContactButton` — mentions a user by Telegram ID via `tg://user?id=`.
|
|
490
|
+
- `UserLinkButton` — opens a user profile by username; supports pre-filled message text.
|
|
491
|
+
- `BotLinkButton` — opens a bot by username; supports deep-link `?start=` payload.
|
|
492
|
+
- Added new methods to `InlineKeyboard`:
|
|
493
|
+
- `add_contact` — adds a `ContactButton`.
|
|
494
|
+
- `add_user_link` — adds a `UserLinkButton`.
|
|
495
|
+
- `add_bot_link` — adds a `BotLinkButton`.
|
|
496
|
+
|
|
497
|
+
### v2.5.0`b2`
|
|
498
|
+
- Added the `escape` parameter to `telekit.utils.*`:
|
|
499
|
+
- `make_user_link`
|
|
500
|
+
- `make_bot_link`
|
|
501
|
+
- `Handler.handlers_dict` now excludes private handlers (classes whose names start with `_`).
|
|
502
|
+
- Added `Debug.duplicate_handler_warnings` to warn about duplicate handler names during initialization.
|
|
503
|
+
- Added `Handler.chat` object (BETA)
|
|
504
|
+
|
|
505
|
+
### v2.5.0`b3`
|
|
506
|
+
- Added `utils.Markers` class
|
|
507
|
+
- Added `HTMLText` class for handling Telegram HTML strings with tag-aware indexing and slicing.
|
|
508
|
+
- Added `PaginatedText` trait for displaying long HTML text in a paginated format, supporting navigation and smart splitting.
|
|
509
|
+
- Added `__radd__` to `TextEntity`: `"Regular" + Bold(" and Bold")`
|
|
510
|
+
- Added `__mul__` to `TextEntity`: `Bold("Text") * 3`
|
|
511
|
+
- Added `enabled=` parameter to `TextEntity`: `Bold("bold text", enabled=is_text_bold)`
|
|
512
|
+
- Added `TextBuilder` class – a fluent message composition API mirroring `InlineKeyboard`'s builder pattern
|
|
513
|
+
- Added styles to `telekit.types`
|
|
514
|
+
- Added `utils.CyclicList`
|
|
515
|
+
- Fixed `_answer_callback_query` to always call `bot.answer_callback_query()`, even without a popup text
|
|
516
|
+
|
|
517
|
+
### v2.5.0`rc2`
|
|
518
|
+
- Refactor `CalendarPick` trait to use `set_keyboard`
|
|
@@ -39,7 +39,7 @@ Telekit comes with a [built-in DSL](https://github.com/Romashkaa/telekit/blob/ma
|
|
|
39
39
|
}
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
> See the [full example](https://github.com/Romashkaa/telekit/blob/main/docs/examples/
|
|
42
|
+
> See the [full example](https://github.com/Romashkaa/telekit/blob/main/docs/examples/complete_hotel.md)
|
|
43
43
|
|
|
44
44
|
Even in its beta stage, Telekit accelerates bot development, offering typed **command parameters**, **text styling** via `Bold()`, `Italic()`, a built-in declarative **calendar picker**, emoji **game results** for `🎲 🎯 🏀 ⚽ 🎳 🎰`, and much more out of the box. Its declarative design makes bots easier to read, maintain, and extend.
|
|
45
45
|
|
|
@@ -97,36 +97,91 @@ The `handle` method sends a message and registers `handle_name` as the next step
|
|
|
97
97
|
|
|
98
98
|
### Inline Keyboards
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
The fastest way to add buttons to a message. Pass a plain `dict` where each key is the button label and each value is the callback to invoke when pressed:
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
self.
|
|
106
|
-
|
|
107
|
-
choices={
|
|
108
|
-
"Option 1": "Value 1",
|
|
109
|
-
"Option 2": "Value 2",
|
|
110
|
-
"Option 3": [3, "Yes, it's an array"],
|
|
102
|
+
```python
|
|
103
|
+
self.chain.set_inline_keyboard(
|
|
104
|
+
{
|
|
105
|
+
"✏️ Change": self.change_name,
|
|
106
|
+
"❌ Delete": self.delete,
|
|
111
107
|
}
|
|
112
108
|
)
|
|
109
|
+
```
|
|
113
110
|
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
`row_width` controls how many buttons appear per row:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
self.chain.set_inline_keyboard(
|
|
115
|
+
{
|
|
116
|
+
"One": self.one,
|
|
117
|
+
"Two": self.two,
|
|
118
|
+
"Three": self.three,
|
|
119
|
+
"Four": self.four,
|
|
120
|
+
"Five": self.five,
|
|
121
|
+
},
|
|
122
|
+
row_width=(3, 2) # first row: 3 buttons, second row: 2
|
|
123
|
+
)
|
|
116
124
|
```
|
|
117
125
|
|
|
118
|
-
|
|
126
|
+
```
|
|
127
|
+
╭──────────┬──────────┬──────────╮
|
|
128
|
+
│ One │ Two │ Three │
|
|
129
|
+
├──────────┴──┬───────┴──────────┤
|
|
130
|
+
│ Four │ Five │
|
|
131
|
+
╰─────────────┴──────────────────╯
|
|
132
|
+
```
|
|
119
133
|
|
|
120
|
-
**
|
|
134
|
+
**Need more control?**
|
|
121
135
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
136
|
+
When you need precise row layout or conditional buttons, use `InlineKeyboard` — a fluent builder that composes keyboards step by step:
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
self.chain.set_keyboard(
|
|
140
|
+
InlineKeyboard()
|
|
141
|
+
.add_callback("-", self.decrement, style="danger")
|
|
142
|
+
.add_callback("+", self.increment, style="success")
|
|
143
|
+
.row()
|
|
144
|
+
.add_callback("↺ Reset", self.reset)
|
|
145
|
+
)
|
|
127
146
|
```
|
|
128
147
|
|
|
129
|
-
|
|
148
|
+
```
|
|
149
|
+
╭──────────┬──────────╮
|
|
150
|
+
│ - │ + │
|
|
151
|
+
├──────────┴──────────┤
|
|
152
|
+
│ ↺ Reset │
|
|
153
|
+
╰─────────────────────╯
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
> `InlineKeyboard` is built by chaining method calls. Just call `.row()` to start a new row.
|
|
157
|
+
|
|
158
|
+
**Not just callback buttons**
|
|
159
|
+
|
|
160
|
+
| **Method** | **Description** |
|
|
161
|
+
| --------------------- | ---------------------------------------------------------------- |
|
|
162
|
+
| `add_callback(...)` | Button that fires a callback function. |
|
|
163
|
+
| `add_link(...)` | Button that opens a URL. |
|
|
164
|
+
| `add_copy(...)` | Button that copies text to the clipboard. |
|
|
165
|
+
| `add_alert(...)` | Button that shows a popup alert dialog. |
|
|
166
|
+
| `add_notification(...)` | Button that shows a brief top-of-chat notification. |
|
|
167
|
+
| `add_static(...)` | Decorative button with no action. |
|
|
168
|
+
| `add_webapp(...)` | Button that opens a Telegram Mini App. |
|
|
169
|
+
| `add_suggest(...)` | Button that simulates the user sending a message. |
|
|
170
|
+
|
|
171
|
+
### Reply Keyboards
|
|
172
|
+
|
|
173
|
+
Unlike inline keyboards, reply keyboards replace the user's system keyboard with buttons shown at the bottom of the chat. Tapping a button either sends its text as a regular message or triggers a system action, such as sharing a phone number or location.
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
self.chain.set_keyboard(
|
|
177
|
+
ReplyKeyboard(one_time_keyboard=True)
|
|
178
|
+
.add_text("Hello!")
|
|
179
|
+
.add_text("Hi")
|
|
180
|
+
.row()
|
|
181
|
+
.add_contact("📱 Share phone")
|
|
182
|
+
.add_location("📍 Share location")
|
|
183
|
+
)
|
|
184
|
+
```
|
|
130
185
|
|
|
131
186
|
### Command Parameters
|
|
132
187
|
|
|
@@ -150,7 +205,7 @@ class GreetHandler(telekit.Handler):
|
|
|
150
205
|
|
|
151
206
|
Now `/greet 64 "Alice Reingold"` or `/greet 128 Dracula` are parsed automatically.
|
|
152
207
|
|
|
153
|
-
> [!
|
|
208
|
+
> [!NOTE]
|
|
154
209
|
> If arguments are invalid or missing, you simply receive `None` and decide how to respond.
|
|
155
210
|
|
|
156
211
|
### Dialogue
|
|
@@ -206,7 +261,7 @@ self.chain.sender.send_chat_action(ChatAction.TYPING) # Send chat action. Use en
|
|
|
206
261
|
```
|
|
207
262
|
|
|
208
263
|
> [!NOTE]
|
|
209
|
-
> Telekit automatically decides whether to use
|
|
264
|
+
> Telekit automatically decides whether to use `bot.send_message` or `bot.send_photo` based on the content
|
|
210
265
|
|
|
211
266
|
### Styles
|
|
212
267
|
|
|
@@ -252,7 +307,7 @@ If you prefer not to write dialog logic in Python, you can use the built-in DSL
|
|
|
252
307
|
```py
|
|
253
308
|
import telekit
|
|
254
309
|
|
|
255
|
-
class QuizHandler(telekit.
|
|
310
|
+
class QuizHandler(telekit.DSLHandler):
|
|
256
311
|
@classmethod
|
|
257
312
|
def init_handler(cls) -> None:
|
|
258
313
|
cls.analyze_string(script)
|
|
@@ -302,7 +357,7 @@ telekit.Server(BOT_TOKEN).polling()
|
|
|
302
357
|
- Jinja template engine
|
|
303
358
|
|
|
304
359
|
<details>
|
|
305
|
-
<summary
|
|
360
|
+
<summary>🎆 Click to see what you can do with the DSL</summary>
|
|
306
361
|
<table>
|
|
307
362
|
<tr>
|
|
308
363
|
<td><img src="./docs/images/telekit_example_7.jpg" alt="Telekit Example 7" width="300"></td>
|
|
@@ -315,7 +370,8 @@ telekit.Server(BOT_TOKEN).polling()
|
|
|
315
370
|
</table>
|
|
316
371
|
</details>
|
|
317
372
|
|
|
318
|
-
|
|
373
|
+
> [!TIP]
|
|
374
|
+
> You can find a [full quiz example](https://github.com/Romashkaa/telekit/blob/main/docs/examples/complete_hotel.md) and [DSL reference](https://github.com/Romashkaa/telekit/blob/main/docs/tutorial/11_telekit_dsl.md) in the repository.
|
|
319
375
|
|
|
320
376
|
### Traits
|
|
321
377
|
|
|
@@ -22,12 +22,16 @@ from ._trait import Trait
|
|
|
22
22
|
from ._chain import Chain
|
|
23
23
|
from ._callback_query_handler import CallbackQueryHandler
|
|
24
24
|
from .server import Server, example
|
|
25
|
+
from ._inline_keyboard import InlineKeyboard
|
|
26
|
+
from ._reply_keyboard import ReplyKeyboard
|
|
27
|
+
from ._text_builder import TextBuilder
|
|
25
28
|
from ._snapvault import Vault
|
|
26
29
|
from ._chapters import chapters
|
|
27
30
|
from ._user import User
|
|
28
31
|
from ._telekit_dsl.telekit_dsl import TelekitDSL
|
|
29
32
|
from ._telekit_dsl.mixin import DSLHandler, InstanceDSLHandler
|
|
30
33
|
from ._logger import enable_file_logging
|
|
34
|
+
from .chat import Chat
|
|
31
35
|
|
|
32
36
|
from . import senders
|
|
33
37
|
from . import types
|
|
@@ -39,6 +43,8 @@ from . import utils
|
|
|
39
43
|
from . import traits
|
|
40
44
|
from . import debug
|
|
41
45
|
from . import scheduler
|
|
46
|
+
from . import chat
|
|
47
|
+
from . import html_text
|
|
42
48
|
|
|
43
49
|
Styles = styles.Styles
|
|
44
50
|
|
|
@@ -54,16 +60,23 @@ __all__ = [
|
|
|
54
60
|
"inline_buttons",
|
|
55
61
|
"dices",
|
|
56
62
|
"scheduler",
|
|
63
|
+
"chat",
|
|
64
|
+
"html_text",
|
|
57
65
|
|
|
58
66
|
"Styles",
|
|
59
67
|
"User",
|
|
60
68
|
|
|
61
|
-
"Server",
|
|
69
|
+
"Server",
|
|
70
|
+
"Chat",
|
|
62
71
|
"Chain",
|
|
63
72
|
"Trait",
|
|
64
73
|
"Handler",
|
|
65
74
|
"CallbackQueryHandler",
|
|
66
75
|
|
|
76
|
+
"InlineKeyboard",
|
|
77
|
+
"ReplyKeyboard",
|
|
78
|
+
"TextBuilder",
|
|
79
|
+
|
|
67
80
|
"TelekitDSL",
|
|
68
81
|
"DSLHandler",
|
|
69
82
|
"InstanceDSLHandler",
|