telekit 2.5.0b0__tar.gz → 2.5.0b2__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.5.0b0 → telekit-2.5.0b2}/PKG-INFO +22 -2
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/__init__.py +5 -1
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_buildtext/styles.py +2 -6
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_chain_base.py +0 -1
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_handler.py +10 -1
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_init.py +2 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_inline_buttons.py +97 -11
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_inline_keyboard.py +131 -9
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_version.py +1 -1
- telekit-2.5.0b2/telekit/chat.py +59 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/debug.py +1 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/inline_buttons.py +6 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/senders.py +20 -1
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/utils.py +23 -9
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit.egg-info/PKG-INFO +22 -2
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit.egg-info/SOURCES.txt +1 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/LICENSE +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/README.md +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/setup.cfg +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/setup.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_buildtext/__init__.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_buildtext/formatter.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_callback_query_handler.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_chain.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_chain_entry_logic.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_chain_inline_keyboards_logic.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_chapters/__init__.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_chapters/chapters.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_input_handler.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_logger.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_on.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_reply_keyboard.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_snapvault/__init__.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_snapvault/snapcode.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_snapvault/snapvault.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_state.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_telekit_dsl/__init__.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_telekit_dsl/mixin.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_telekit_dsl/parser/__init__.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_telekit_dsl/parser/builder.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_telekit_dsl/parser/canvas_parser.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_telekit_dsl/parser/lexer.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_telekit_dsl/parser/nodes.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_telekit_dsl/parser/parser.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_telekit_dsl/parser/token.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_telekit_dsl/telekit_dsl.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_telekit_dsl/telekit_orm.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_timeout.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_trait.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/_user.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/dices.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/__init__.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_handlers/__init__.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_handlers/calendar.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_handlers/complete_hotel.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_handlers/counter.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_handlers/dsl.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_handlers/entry.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_handlers/faq.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_handlers/hotel.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_handlers/on_text.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_handlers/pages.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_handlers/pyapi.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_handlers/qr.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_handlers/quiz.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_handlers/spells.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_handlers/start.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_handlers/text_document.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/example/example_server.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/parameters.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/reply_buttons.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/scheduler.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/server.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/styles.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/traits/__init__.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/traits/calendar_pick.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/traits/paginated_choice.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/traits/track_handoff_origin.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit/types.py +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit.egg-info/dependency_links.txt +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/telekit.egg-info/requires.txt +0 -0
- {telekit-2.5.0b0 → telekit-2.5.0b2}/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.5.
|
|
3
|
+
Version: 2.5.0b2
|
|
4
4
|
Summary: Declarative, developer-friendly library for building Telegram bots
|
|
5
5
|
Home-page: https://github.com/Romashkaa/telekit
|
|
6
6
|
Author: romashka
|
|
@@ -477,7 +477,27 @@ It tries to make Telegram bot development easier.
|
|
|
477
477
|
|
|
478
478
|
---
|
|
479
479
|
|
|
480
|
-
# Changes in version 2.5.
|
|
480
|
+
# Changes in version 2.5.0b2
|
|
481
481
|
|
|
482
482
|
### v2.5.0`b0`
|
|
483
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)
|
|
@@ -30,6 +30,7 @@ from ._user import User
|
|
|
30
30
|
from ._telekit_dsl.telekit_dsl import TelekitDSL
|
|
31
31
|
from ._telekit_dsl.mixin import DSLHandler, InstanceDSLHandler
|
|
32
32
|
from ._logger import enable_file_logging
|
|
33
|
+
from .chat import Chat
|
|
33
34
|
|
|
34
35
|
from . import senders
|
|
35
36
|
from . import types
|
|
@@ -41,6 +42,7 @@ from . import utils
|
|
|
41
42
|
from . import traits
|
|
42
43
|
from . import debug
|
|
43
44
|
from . import scheduler
|
|
45
|
+
from . import chat
|
|
44
46
|
|
|
45
47
|
Styles = styles.Styles
|
|
46
48
|
|
|
@@ -56,11 +58,13 @@ __all__ = [
|
|
|
56
58
|
"inline_buttons",
|
|
57
59
|
"dices",
|
|
58
60
|
"scheduler",
|
|
61
|
+
"chat",
|
|
59
62
|
|
|
60
63
|
"Styles",
|
|
61
64
|
"User",
|
|
62
65
|
|
|
63
|
-
"Server",
|
|
66
|
+
"Server",
|
|
67
|
+
"Chat",
|
|
64
68
|
"Chain",
|
|
65
69
|
"Trait",
|
|
66
70
|
"Handler",
|
|
@@ -484,13 +484,9 @@ class Mention(Link):
|
|
|
484
484
|
`Documentation <https://github.com/Romashkaa/telekit/blob/main/docs/tutorial2/6_styles.md>`_ · on GitHub
|
|
485
485
|
"""
|
|
486
486
|
|
|
487
|
-
def __init__(self, *content, user_id: int, escape: bool = True, sep: Union[str, "TextEntity", "Template"] = ""):
|
|
488
|
-
url: str =
|
|
487
|
+
def __init__(self, *content, user_id: int | str, escape: bool = True, sep: Union[str, "TextEntity", "Template"] = ""):
|
|
488
|
+
url: str = telekit.utils.make_mention(user_id)
|
|
489
489
|
super().__init__(*content, url=url, escape=escape, sep=sep)
|
|
490
|
-
|
|
491
|
-
@staticmethod
|
|
492
|
-
def gen_link(user_id: int) -> str:
|
|
493
|
-
return f"tg://user?id={user_id}"
|
|
494
490
|
|
|
495
491
|
|
|
496
492
|
class UserLink(Link):
|
|
@@ -27,8 +27,9 @@ library = logger.library
|
|
|
27
27
|
from ._chain import Chain
|
|
28
28
|
from ._callback_query_handler import CallbackQueryHandler
|
|
29
29
|
from ._user import User
|
|
30
|
+
from .chat import Chat
|
|
30
31
|
from ._on import On
|
|
31
|
-
from . import
|
|
32
|
+
from .debug import Debug
|
|
32
33
|
|
|
33
34
|
class Handler:
|
|
34
35
|
|
|
@@ -40,6 +41,7 @@ class Handler:
|
|
|
40
41
|
|
|
41
42
|
# Instance Attributes
|
|
42
43
|
user: User
|
|
44
|
+
chat: Chat
|
|
43
45
|
chain: Chain
|
|
44
46
|
message: Message
|
|
45
47
|
|
|
@@ -74,6 +76,12 @@ class Handler:
|
|
|
74
76
|
handler.on = On(handler, bot)
|
|
75
77
|
handler.init_handler()
|
|
76
78
|
|
|
79
|
+
if handler.__name__.startswith("_"):
|
|
80
|
+
continue
|
|
81
|
+
|
|
82
|
+
if handler.__name__ in cls.handlers_dict and Debug.duplicate_handler_warnings:
|
|
83
|
+
library.warning("Multiple handlers are named 'StartHandler'. Only the last registered handler is available through Handler.handlers_dict.")
|
|
84
|
+
|
|
77
85
|
cls.handlers_dict[handler.__name__] = handler
|
|
78
86
|
|
|
79
87
|
@classmethod
|
|
@@ -99,6 +107,7 @@ class Handler:
|
|
|
99
107
|
def __init__(self, message: Message):
|
|
100
108
|
self.message: Message = message
|
|
101
109
|
self.user = User(self.message)
|
|
110
|
+
self.chat = Chat(self.message.chat.id, self.message.message_thread_id)
|
|
102
111
|
self.new_chain()
|
|
103
112
|
|
|
104
113
|
def handle(self) -> Any:
|
|
@@ -25,6 +25,7 @@ from ._inline_buttons import InlineButton
|
|
|
25
25
|
from ._user import User
|
|
26
26
|
from .senders import BaseSender
|
|
27
27
|
from ._state import TelekitState
|
|
28
|
+
from .chat import Chat
|
|
28
29
|
|
|
29
30
|
import telebot
|
|
30
31
|
|
|
@@ -33,6 +34,7 @@ __all__ = ["init"]
|
|
|
33
34
|
def init(bot: telebot.TeleBot) -> None:
|
|
34
35
|
TelekitState._init(bot)
|
|
35
36
|
BaseSender._init(bot)
|
|
37
|
+
Chat._init(bot)
|
|
36
38
|
Handler._init(bot)
|
|
37
39
|
Chain._init(bot)
|
|
38
40
|
InputHandler._init(bot)
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
from typing import Any, Callable
|
|
21
21
|
from enum import Enum
|
|
22
22
|
|
|
23
|
-
# Third-party packages
|
|
24
23
|
import telebot.types
|
|
25
24
|
from telebot.types import InlineKeyboardButton, CallbackQuery
|
|
26
25
|
from telebot import TeleBot
|
|
27
|
-
from ._callback_query_handler import CallbackQueryHandler
|
|
28
26
|
|
|
27
|
+
import telekit
|
|
28
|
+
from ._callback_query_handler import CallbackQueryHandler
|
|
29
29
|
from ._state import TelekitState
|
|
30
30
|
|
|
31
31
|
__all__ = [
|
|
@@ -33,6 +33,9 @@ __all__ = [
|
|
|
33
33
|
|
|
34
34
|
"StaticButton",
|
|
35
35
|
"LinkButton",
|
|
36
|
+
"ContactButton",
|
|
37
|
+
"UserLinkButton",
|
|
38
|
+
"BotLinkButton",
|
|
36
39
|
"WebAppButton",
|
|
37
40
|
"SuggestButton",
|
|
38
41
|
"CopyTextButton",
|
|
@@ -57,6 +60,9 @@ class InlineButton:
|
|
|
57
60
|
"""
|
|
58
61
|
Base class for:
|
|
59
62
|
- `LinkButton`
|
|
63
|
+
- `ContactButton`
|
|
64
|
+
- `UserLinkButton`
|
|
65
|
+
- `BotLinkButton`
|
|
60
66
|
- `WebAppButton`
|
|
61
67
|
- `SuggestButton`
|
|
62
68
|
- `CopyTextButton`
|
|
@@ -79,6 +85,9 @@ class InlineButton:
|
|
|
79
85
|
|
|
80
86
|
Static: type["StaticButton"]
|
|
81
87
|
Link: type["LinkButton"]
|
|
88
|
+
Contact: type["ContactButton"]
|
|
89
|
+
UserLink: type["UserLinkButton"]
|
|
90
|
+
BotLink: type["BotLinkButton"]
|
|
82
91
|
WebApp: type["WebAppButton"]
|
|
83
92
|
Suggest: type["SuggestButton"]
|
|
84
93
|
CopyText: type["CopyTextButton"]
|
|
@@ -157,7 +166,7 @@ class LinkButton(InlineButton):
|
|
|
157
166
|
:param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
|
|
158
167
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
159
168
|
You can also pass these as string values: "danger", "success", "primary".
|
|
160
|
-
If omitted, an
|
|
169
|
+
If omitted, an client-specific default style is used.
|
|
161
170
|
:type style: `str`
|
|
162
171
|
|
|
163
172
|
:param kwargs: Additional keyword arguments passed directly to `InlineKeyboardButton`.
|
|
@@ -175,7 +184,81 @@ class LinkButton(InlineButton):
|
|
|
175
184
|
style=self._style,
|
|
176
185
|
**self._kwargs
|
|
177
186
|
)
|
|
178
|
-
|
|
187
|
+
|
|
188
|
+
class ContactButton(LinkButton):
|
|
189
|
+
"""
|
|
190
|
+
Inline keyboard button that mentions a user by their Telegram ID.
|
|
191
|
+
|
|
192
|
+
Generates a ``tg://user?id=<user_id>`` link via :func:`telekit.utils.make_mention`,
|
|
193
|
+
allowing you to mention a user without knowing their username —
|
|
194
|
+
subject to their privacy settings.
|
|
195
|
+
|
|
196
|
+
:param user_id: Telegram user ID to mention.
|
|
197
|
+
:type user_id: :class:`str` | :class:`int`
|
|
198
|
+
:param style: Visual style of the button. Accepts a :class:`~telekit.types.ButtonStyle`
|
|
199
|
+
enum value or its string equivalent: ``"danger"`` (red), ``"success"`` (green),
|
|
200
|
+
``"primary"`` (blue). Defaults to the client-specific style if omitted.
|
|
201
|
+
:type style: :class:`~telekit.types.ButtonStyle` | :class:`str` | ``None``
|
|
202
|
+
:param kwargs: Additional keyword arguments forwarded to
|
|
203
|
+
:class:`~telekit.types.InlineKeyboardButton`.
|
|
204
|
+
"""
|
|
205
|
+
def __init__(self, user_id: str | int, *, style: str | None | ButtonStyle = None, **kwargs):
|
|
206
|
+
super().__init__(
|
|
207
|
+
url=telekit.utils.make_mention(user_id),
|
|
208
|
+
style=style,
|
|
209
|
+
**kwargs
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
class UserLinkButton(LinkButton):
|
|
213
|
+
"""
|
|
214
|
+
Inline keyboard button that opens a Telegram profile by username.
|
|
215
|
+
|
|
216
|
+
Generates a ``https://t.me/<username>`` link via :func:`telekit.utils.make_user_link`.
|
|
217
|
+
Optionally pre-fills the message input with ``text``.
|
|
218
|
+
|
|
219
|
+
:param username: Telegram username, with or without a leading ``@``.
|
|
220
|
+
:type username: :class:`str`
|
|
221
|
+
:param text: Optional message text to pre-fill in the chat input.
|
|
222
|
+
:type text: :class:`str` | ``None``
|
|
223
|
+
:param style: Visual style of the button. Accepts a :class:`~telekit.types.ButtonStyle`
|
|
224
|
+
enum value or its string equivalent: ``"danger"`` (red), ``"success"`` (green),
|
|
225
|
+
``"primary"`` (blue). Defaults to the client-specific style if omitted.
|
|
226
|
+
:type style: :class:`~telekit.types.ButtonStyle` | :class:`str` | ``None``
|
|
227
|
+
:param kwargs: Additional keyword arguments forwarded to
|
|
228
|
+
:class:`~telekit.types.InlineKeyboardButton`.
|
|
229
|
+
"""
|
|
230
|
+
def __init__(self, username: str, text: str | None = None, *, style: str | None | ButtonStyle = None, **kwargs):
|
|
231
|
+
super().__init__(
|
|
232
|
+
url=telekit.utils.make_user_link(username, text),
|
|
233
|
+
style=style,
|
|
234
|
+
**kwargs
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
class BotLinkButton(LinkButton):
|
|
238
|
+
"""
|
|
239
|
+
Inline keyboard button that opens a Telegram bot by username.
|
|
240
|
+
|
|
241
|
+
Generates a ``https://t.me/<botname>`` link via :func:`telekit.utils.make_bot_link`.
|
|
242
|
+
Optionally appends a deep-link payload via ``?start=``.
|
|
243
|
+
|
|
244
|
+
:param botname: Bot username, with or without a leading ``@``.
|
|
245
|
+
:type botname: :class:`str`
|
|
246
|
+
:param start: Optional deep-link payload passed as ``?start=``.
|
|
247
|
+
:type start: :class:`str` | ``None``
|
|
248
|
+
:param style: Visual style of the button. Accepts a :class:`~telekit.types.ButtonStyle`
|
|
249
|
+
enum value or its string equivalent: ``"danger"`` (red), ``"success"`` (green),
|
|
250
|
+
``"primary"`` (blue). Defaults to the client-specific style if omitted.
|
|
251
|
+
:type style: :class:`~telekit.types.ButtonStyle` | :class:`str` | ``None``
|
|
252
|
+
:param kwargs: Additional keyword arguments forwarded to
|
|
253
|
+
:class:`~telekit.types.InlineKeyboardButton`.
|
|
254
|
+
"""
|
|
255
|
+
def __init__(self, botname: str, start: str | None = None, *, style: str | None | ButtonStyle = None, **kwargs):
|
|
256
|
+
super().__init__(
|
|
257
|
+
url=telekit.utils.make_bot_link(botname, start),
|
|
258
|
+
style=style,
|
|
259
|
+
**kwargs
|
|
260
|
+
)
|
|
261
|
+
|
|
179
262
|
class WebAppButton(InlineButton):
|
|
180
263
|
"""
|
|
181
264
|
This object represents an inline keyboard button that describes a Web App.
|
|
@@ -186,7 +269,7 @@ class WebAppButton(InlineButton):
|
|
|
186
269
|
:param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
|
|
187
270
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
188
271
|
You can also pass these as string values: "danger", "success", "primary".
|
|
189
|
-
If omitted, an
|
|
272
|
+
If omitted, an client-specific default style is used.
|
|
190
273
|
:type style: `str`
|
|
191
274
|
|
|
192
275
|
:param kwargs: Additional keyword arguments passed directly to `InlineKeyboardButton`.
|
|
@@ -215,7 +298,7 @@ class CopyTextButton(InlineButton):
|
|
|
215
298
|
:param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
|
|
216
299
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
217
300
|
You can also pass these as string values: "danger", "success", "primary".
|
|
218
|
-
If omitted, an
|
|
301
|
+
If omitted, an client-specific default style is used.
|
|
219
302
|
:type style: `str`
|
|
220
303
|
|
|
221
304
|
:param kwargs: Additional keyword arguments passed directly to `InlineKeyboardButton`.
|
|
@@ -255,7 +338,7 @@ class SuggestButton(InlineButton):
|
|
|
255
338
|
:param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
|
|
256
339
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
257
340
|
You can also pass these as string values: "danger", "success", "primary".
|
|
258
|
-
If omitted, an
|
|
341
|
+
If omitted, an client-specific default style is used.
|
|
259
342
|
:type style: `str`
|
|
260
343
|
|
|
261
344
|
:param kwargs: Additional keyword arguments passed directly to `InlineKeyboardButton`.
|
|
@@ -308,7 +391,7 @@ class CallbackButton(InlineButton):
|
|
|
308
391
|
:param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
|
|
309
392
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
310
393
|
You can also pass these as string values: "danger", "success", "primary".
|
|
311
|
-
If omitted, an
|
|
394
|
+
If omitted, an client-specific default style is used.
|
|
312
395
|
:type style: `str`
|
|
313
396
|
|
|
314
397
|
:param kwargs: Additional keyword arguments passed directly to `InlineKeyboardButton`.
|
|
@@ -501,7 +584,7 @@ class AlertButton(AnswerButton):
|
|
|
501
584
|
:param style: Style of the button. Must be one of `ButtonStyle.DANGER` (red),
|
|
502
585
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
503
586
|
You can also pass these as string values: "danger", "success", "primary".
|
|
504
|
-
If omitted, an
|
|
587
|
+
If omitted, an client-specific default style is used.
|
|
505
588
|
:type style: `str | ButtonStyle | None`
|
|
506
589
|
|
|
507
590
|
:param kwargs: Additional keyword arguments passed directly to `InlineKeyboardButton`.
|
|
@@ -551,7 +634,7 @@ class NotificationButton(AnswerButton):
|
|
|
551
634
|
:param style: Style of the button. Must be one of `ButtonStyle.DANGER` (red),
|
|
552
635
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
553
636
|
You can also pass these as string values: "danger", "success", "primary".
|
|
554
|
-
If omitted, an
|
|
637
|
+
If omitted, an client-specific default style is used.
|
|
555
638
|
:type style: `str | ButtonStyle | None`
|
|
556
639
|
|
|
557
640
|
:param kwargs: Additional keyword arguments passed directly to `InlineKeyboardButton`.
|
|
@@ -616,7 +699,7 @@ class InvokeButton(CallbackButton):
|
|
|
616
699
|
:param style: Style of the button. Must be one of `ButtonStyle.DANGER` (red),
|
|
617
700
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
618
701
|
You can also pass these as string values: "danger", "success", "primary".
|
|
619
|
-
If omitted, an
|
|
702
|
+
If omitted, an client-specific default style is used.
|
|
620
703
|
:type style: `str | ButtonStyle | None`
|
|
621
704
|
|
|
622
705
|
:param kwargs: Additional keyword arguments passed directly to `InlineKeyboardButton`.
|
|
@@ -712,6 +795,9 @@ class InvokeButton(CallbackButton):
|
|
|
712
795
|
)
|
|
713
796
|
|
|
714
797
|
InlineButton.Link = LinkButton
|
|
798
|
+
InlineButton.Contact = ContactButton
|
|
799
|
+
InlineButton.UserLink = UserLinkButton
|
|
800
|
+
InlineButton.BotLink = BotLinkButton
|
|
715
801
|
InlineButton.Static = StaticButton
|
|
716
802
|
InlineButton.WebApp = WebAppButton
|
|
717
803
|
InlineButton.Suggest = SuggestButton
|
|
@@ -167,7 +167,7 @@ class InlineKeyboard:
|
|
|
167
167
|
:param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
|
|
168
168
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
169
169
|
You can also pass these as string values: "danger", "success", "primary".
|
|
170
|
-
If omitted, an
|
|
170
|
+
If omitted, an client-specific default style is used.
|
|
171
171
|
:type style: `str`
|
|
172
172
|
|
|
173
173
|
:param when: If `False`, the button is not added.
|
|
@@ -210,7 +210,7 @@ class InlineKeyboard:
|
|
|
210
210
|
:param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
|
|
211
211
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
212
212
|
You can also pass these as string values: "danger", "success", "primary".
|
|
213
|
-
If omitted, an
|
|
213
|
+
If omitted, an client-specific default style is used.
|
|
214
214
|
:type style: `str`
|
|
215
215
|
|
|
216
216
|
:param when: If `False`, the button is not added.
|
|
@@ -225,6 +225,128 @@ class InlineKeyboard:
|
|
|
225
225
|
self._maybe_row()
|
|
226
226
|
return self
|
|
227
227
|
|
|
228
|
+
def add_contact(
|
|
229
|
+
self,
|
|
230
|
+
text: str,
|
|
231
|
+
user_id: str | int,
|
|
232
|
+
*,
|
|
233
|
+
style: Literal["danger", "success", "primary"] | None | ButtonStyle = None,
|
|
234
|
+
when: bool | int = True,
|
|
235
|
+
**kwargs
|
|
236
|
+
):
|
|
237
|
+
"""
|
|
238
|
+
Adds a button that mentions a Telegram user by their ID.
|
|
239
|
+
|
|
240
|
+
The button generates a ``tg://user?id=<user_id>`` link via
|
|
241
|
+
:class:`~telekit.types.ContactButton`, allowing you to mention a user
|
|
242
|
+
without knowing their username.
|
|
243
|
+
|
|
244
|
+
:param text: Label displayed on the button.
|
|
245
|
+
:type text: :class:`str`
|
|
246
|
+
:param user_id: Telegram user ID to mention.
|
|
247
|
+
:type user_id: :class:`str` | :class:`int`
|
|
248
|
+
:param style: Visual style of the button. Accepts a :class:`~telekit.types.ButtonStyle`
|
|
249
|
+
enum value or its string equivalent: ``"danger"`` (red), ``"success"`` (green),
|
|
250
|
+
``"primary"`` (blue). Defaults to the client-specific style if omitted.
|
|
251
|
+
:type style: :class:`~telekit.types.ButtonStyle` | :class:`str` | ``None``
|
|
252
|
+
:param when: If ``False`` (or any falsy value), the button is skipped and not added
|
|
253
|
+
to the keyboard. Useful for conditional layouts.
|
|
254
|
+
:type when: :class:`bool` | :class:`int`
|
|
255
|
+
:param kwargs: Additional keyword arguments forwarded to
|
|
256
|
+
:class:`~telekit.types.InlineKeyboardButton`.
|
|
257
|
+
:returns: The current builder instance, for method chaining.
|
|
258
|
+
:rtype: :class:`Self`
|
|
259
|
+
"""
|
|
260
|
+
if not when:
|
|
261
|
+
return self
|
|
262
|
+
|
|
263
|
+
self._current.append((text, ContactButton(user_id, style=style, **kwargs)))
|
|
264
|
+
self._maybe_row()
|
|
265
|
+
return self
|
|
266
|
+
|
|
267
|
+
def add_user_link(
|
|
268
|
+
self,
|
|
269
|
+
text: str,
|
|
270
|
+
username: str,
|
|
271
|
+
message: str | None = None,
|
|
272
|
+
*,
|
|
273
|
+
style: Literal["danger", "success", "primary"] | None | ButtonStyle = None,
|
|
274
|
+
when: bool | int = True,
|
|
275
|
+
**kwargs
|
|
276
|
+
):
|
|
277
|
+
"""
|
|
278
|
+
Adds a button that opens a Telegram user profile by username.
|
|
279
|
+
|
|
280
|
+
The button generates a ``https://t.me/<username>`` link via
|
|
281
|
+
:class:`~telekit.types.UserLinkButton`. Optionally pre-fills
|
|
282
|
+
the chat input with ``message``.
|
|
283
|
+
|
|
284
|
+
:param text: Label displayed on the button.
|
|
285
|
+
:type text: :class:`str`
|
|
286
|
+
:param username: Telegram username, with or without a leading ``@``.
|
|
287
|
+
:type username: :class:`str`
|
|
288
|
+
:param message: Optional message text to pre-fill in the chat input.
|
|
289
|
+
:type message: :class:`str` | ``None``
|
|
290
|
+
:param style: Visual style of the button. Accepts a :class:`~telekit.types.ButtonStyle`
|
|
291
|
+
enum value or its string equivalent: ``"danger"`` (red), ``"success"`` (green),
|
|
292
|
+
``"primary"`` (blue). Defaults to the app-specific style if omitted.
|
|
293
|
+
:type style: :class:`~telekit.types.ButtonStyle` | :class:`str` | ``None``
|
|
294
|
+
:param when: If ``False`` (or any falsy value), the button is skipped and not added
|
|
295
|
+
to the keyboard. Useful for conditional layouts.
|
|
296
|
+
:type when: :class:`bool` | :class:`int`
|
|
297
|
+
:param kwargs: Additional keyword arguments forwarded to
|
|
298
|
+
:class:`~telekit.types.InlineKeyboardButton`.
|
|
299
|
+
:returns: The current builder instance, for method chaining.
|
|
300
|
+
:rtype: :class:`Self`
|
|
301
|
+
"""
|
|
302
|
+
if not when:
|
|
303
|
+
return self
|
|
304
|
+
self._current.append((text, UserLinkButton(username, message, style=style, **kwargs)))
|
|
305
|
+
self._maybe_row()
|
|
306
|
+
return self
|
|
307
|
+
|
|
308
|
+
def add_bot_link(
|
|
309
|
+
self,
|
|
310
|
+
text: str,
|
|
311
|
+
botname: str,
|
|
312
|
+
start: str | None = None,
|
|
313
|
+
*,
|
|
314
|
+
style: Literal["danger", "success", "primary"] | None | ButtonStyle = None,
|
|
315
|
+
when: bool | int = True,
|
|
316
|
+
**kwargs
|
|
317
|
+
):
|
|
318
|
+
"""
|
|
319
|
+
Adds a button that opens a Telegram bot by username.
|
|
320
|
+
|
|
321
|
+
The button generates a ``https://t.me/<botname>`` link via
|
|
322
|
+
:class:`~telekit.types.BotLinkButton`. Optionally appends
|
|
323
|
+
a deep-link payload via ``?start=``.
|
|
324
|
+
|
|
325
|
+
:param text: Label displayed on the button.
|
|
326
|
+
:type text: :class:`str`
|
|
327
|
+
:param botname: Bot username, with or without a leading ``@``.
|
|
328
|
+
:type botname: :class:`str`
|
|
329
|
+
:param start: Optional deep-link payload passed as ``?start=``.
|
|
330
|
+
Useful for referral links or onboarding flows.
|
|
331
|
+
:type start: :class:`str` | ``None``
|
|
332
|
+
:param style: Visual style of the button. Accepts a :class:`~telekit.types.ButtonStyle`
|
|
333
|
+
enum value or its string equivalent: ``"danger"`` (red), ``"success"`` (green),
|
|
334
|
+
``"primary"`` (blue). Defaults to the app-specific style if omitted.
|
|
335
|
+
:type style: :class:`~telekit.types.ButtonStyle` | :class:`str` | ``None``
|
|
336
|
+
:param when: If ``False`` (or any falsy value), the button is skipped and not added
|
|
337
|
+
to the keyboard. Useful for conditional layouts.
|
|
338
|
+
:type when: :class:`bool` | :class:`int`
|
|
339
|
+
:param kwargs: Additional keyword arguments forwarded to
|
|
340
|
+
:class:`~telekit.types.InlineKeyboardButton`.
|
|
341
|
+
:returns: The current builder instance, for method chaining.
|
|
342
|
+
:rtype: :class:`Self`
|
|
343
|
+
"""
|
|
344
|
+
if not when:
|
|
345
|
+
return self
|
|
346
|
+
self._current.append((text, BotLinkButton(botname, start, style=style, **kwargs)))
|
|
347
|
+
self._maybe_row()
|
|
348
|
+
return self
|
|
349
|
+
|
|
228
350
|
def add_webapp(
|
|
229
351
|
self,
|
|
230
352
|
text: str,
|
|
@@ -246,7 +368,7 @@ class InlineKeyboard:
|
|
|
246
368
|
:param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
|
|
247
369
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
248
370
|
You can also pass these as string values: "danger", "success", "primary".
|
|
249
|
-
If omitted, an
|
|
371
|
+
If omitted, an client-specific default style is used.
|
|
250
372
|
:type style: `str`
|
|
251
373
|
|
|
252
374
|
:param when: If `False`, the button is not added.
|
|
@@ -283,7 +405,7 @@ class InlineKeyboard:
|
|
|
283
405
|
:param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
|
|
284
406
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
285
407
|
You can also pass these as string values: "danger", "success", "primary".
|
|
286
|
-
If omitted, an
|
|
408
|
+
If omitted, an client-specific default style is used.
|
|
287
409
|
:type style: `str`
|
|
288
410
|
|
|
289
411
|
:param strict: If `True`, raises an error when the suggestion exceeds Telegram's 64-byte limit.
|
|
@@ -323,7 +445,7 @@ class InlineKeyboard:
|
|
|
323
445
|
:param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
|
|
324
446
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
325
447
|
You can also pass these as string values: "danger", "success", "primary".
|
|
326
|
-
If omitted, an
|
|
448
|
+
If omitted, an client-specific default style is used.
|
|
327
449
|
:type style: `str`
|
|
328
450
|
|
|
329
451
|
:param strict: If `True`, raises an error when the text exceeds Telegram's 256-character limit.
|
|
@@ -358,7 +480,7 @@ class InlineKeyboard:
|
|
|
358
480
|
:param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
|
|
359
481
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
360
482
|
You can also pass these as string values: "danger", "success", "primary".
|
|
361
|
-
If omitted, an
|
|
483
|
+
If omitted, an client-specific default style is used.
|
|
362
484
|
:type style: `str`
|
|
363
485
|
|
|
364
486
|
:param when: If `False`, the button is not added.
|
|
@@ -398,7 +520,7 @@ class InlineKeyboard:
|
|
|
398
520
|
:param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
|
|
399
521
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
400
522
|
You can also pass these as string values: "danger", "success", "primary".
|
|
401
|
-
If omitted, an
|
|
523
|
+
If omitted, an client-specific default style is used.
|
|
402
524
|
:type style: `str`
|
|
403
525
|
|
|
404
526
|
:param when: If `False`, the button is not added.
|
|
@@ -438,7 +560,7 @@ class InlineKeyboard:
|
|
|
438
560
|
:param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
|
|
439
561
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
440
562
|
You can also pass these as string values: "danger", "success", "primary".
|
|
441
|
-
If omitted, an
|
|
563
|
+
If omitted, an client-specific default style is used.
|
|
442
564
|
:type style: `str`
|
|
443
565
|
|
|
444
566
|
:param when: If `False`, the button is not added.
|
|
@@ -495,7 +617,7 @@ class InlineKeyboard:
|
|
|
495
617
|
:param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
|
|
496
618
|
`*.SUCCESS` (green) or `*.PRIMARY` (blue).
|
|
497
619
|
You can also pass these as string values: "danger", "success", "primary".
|
|
498
|
-
If omitted, an
|
|
620
|
+
If omitted, an client-specific default style is used.
|
|
499
621
|
:type style: `str`
|
|
500
622
|
|
|
501
623
|
:param when: If `False`, the button is not added.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from telebot import TeleBot
|
|
4
|
+
from telebot.types import Message
|
|
5
|
+
|
|
6
|
+
import telekit
|
|
7
|
+
from telekit.styles import TextEntity, Escape, Raw, Group, Bold, Italic
|
|
8
|
+
from ._logger import _library
|
|
9
|
+
|
|
10
|
+
__all__ = ['Chat']
|
|
11
|
+
|
|
12
|
+
class Chat:
|
|
13
|
+
|
|
14
|
+
bot: TeleBot
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
def _init(cls, bot: TeleBot):
|
|
18
|
+
"""
|
|
19
|
+
Initializes the bot instance for the class.
|
|
20
|
+
"""
|
|
21
|
+
cls.bot = bot
|
|
22
|
+
|
|
23
|
+
def __init__(self, chat_id: int, thread_id: int | None = None, previous_user_message: Message | None = None) -> None:
|
|
24
|
+
self.id = chat_id
|
|
25
|
+
self.thread_id = thread_id
|
|
26
|
+
self.previous_user_message = previous_user_message
|
|
27
|
+
|
|
28
|
+
def _get_base_params(self) -> dict[str, Any]:
|
|
29
|
+
return {
|
|
30
|
+
"chat_id": self.id,
|
|
31
|
+
"parse_mode": "html",
|
|
32
|
+
"message_thread_id": self.thread_id
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
def answer(self, text: str | TextEntity):
|
|
36
|
+
"""
|
|
37
|
+
Sends a text message to the chat.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
Message | None: The sent message or None if sending failed.
|
|
41
|
+
"""
|
|
42
|
+
if not isinstance(text, TextEntity):
|
|
43
|
+
text = Escape(text)
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
return self.bot.send_message(
|
|
47
|
+
chat_id = self.id,
|
|
48
|
+
message_thread_id = self.thread_id,
|
|
49
|
+
text = text.html,
|
|
50
|
+
parse_mode = "html",
|
|
51
|
+
)
|
|
52
|
+
except Exception as exception:
|
|
53
|
+
text.debug("html")
|
|
54
|
+
_library.warning(f"^^^ [chat.answer]: Failed to answer (chat_id={self.id}; thread_id={self.thread_id}): {exception}")
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
@@ -22,6 +22,9 @@ from ._inline_buttons import (
|
|
|
22
22
|
StaticButton,
|
|
23
23
|
|
|
24
24
|
LinkButton,
|
|
25
|
+
ContactButton,
|
|
26
|
+
UserLinkButton,
|
|
27
|
+
BotLinkButton,
|
|
25
28
|
WebAppButton,
|
|
26
29
|
SuggestButton,
|
|
27
30
|
CopyTextButton,
|
|
@@ -41,6 +44,9 @@ __all__ = [
|
|
|
41
44
|
"StaticButton",
|
|
42
45
|
|
|
43
46
|
"LinkButton",
|
|
47
|
+
"ContactButton",
|
|
48
|
+
"UserLinkButton",
|
|
49
|
+
"BotLinkButton",
|
|
44
50
|
"WebAppButton",
|
|
45
51
|
"SuggestButton",
|
|
46
52
|
"CopyTextButton",
|
|
@@ -1208,10 +1208,29 @@ class BaseSender:
|
|
|
1208
1208
|
try:
|
|
1209
1209
|
configs = self._get_base_params()
|
|
1210
1210
|
configs["parse_mode"] = "HTML"
|
|
1211
|
-
return self.bot.send_message(text=f"
|
|
1211
|
+
return self.bot.send_message(text=f"{Bold(title).html}\n\n{Escape(message).html}", **configs)
|
|
1212
1212
|
except Exception as exception:
|
|
1213
1213
|
library.warning(f"Failed to send `error` message: {exception}")
|
|
1214
1214
|
return None
|
|
1215
|
+
|
|
1216
|
+
def send_message(self, title: str, message: str) -> Message | None:
|
|
1217
|
+
"""
|
|
1218
|
+
Sends a custom message with a title and detailed message.
|
|
1219
|
+
|
|
1220
|
+
Args:
|
|
1221
|
+
title (`str` | `TextEntity`): The title of the message.
|
|
1222
|
+
message (`str` | `TextEntity`): The message.
|
|
1223
|
+
|
|
1224
|
+
Returns:
|
|
1225
|
+
Message | None: The sent message or None if sending failed.
|
|
1226
|
+
"""
|
|
1227
|
+
try:
|
|
1228
|
+
configs = self._get_base_params()
|
|
1229
|
+
configs["parse_mode"] = "HTML"
|
|
1230
|
+
return self.bot.send_message(text=f"{Bold(title).html}\n\n{Escape(message).html}", **configs)
|
|
1231
|
+
except Exception as exception:
|
|
1232
|
+
library.warning(f"Failed to send message: {exception}")
|
|
1233
|
+
return None
|
|
1215
1234
|
|
|
1216
1235
|
def try_send(self) -> tuple[Message | None, Exception | None]:
|
|
1217
1236
|
"""
|
|
@@ -322,8 +322,20 @@ def compose_keyboard(
|
|
|
322
322
|
# Link Generating
|
|
323
323
|
# ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
|
|
324
324
|
|
|
325
|
-
def
|
|
326
|
-
"""
|
|
325
|
+
def make_mention(user_id: int | str) -> str:
|
|
326
|
+
"""
|
|
327
|
+
Creates a Telegram mention link by user ID.
|
|
328
|
+
|
|
329
|
+
Examples::
|
|
330
|
+
|
|
331
|
+
make_mention(123456789)
|
|
332
|
+
>>> 'tg://user?id=123456789'
|
|
333
|
+
"""
|
|
334
|
+
return f"tg://user?id={user_id}"
|
|
335
|
+
|
|
336
|
+
def make_bot_link(botname: str, start: str | None = None, escape: bool = True) -> str:
|
|
337
|
+
"""
|
|
338
|
+
Return a t.me link to a bot.
|
|
327
339
|
|
|
328
340
|
>>> make_bot_link("UserNameOfBot")
|
|
329
341
|
"https://t.me/UserNameOfBot"
|
|
@@ -341,11 +353,12 @@ def make_bot_link(botname: str, start: str | None = None) -> str:
|
|
|
341
353
|
botname = botname.lstrip("@")
|
|
342
354
|
if start is None:
|
|
343
355
|
return f"https://t.me/{botname}"
|
|
344
|
-
encoded_start = quote(start, safe="")
|
|
356
|
+
encoded_start = quote(start, safe="") if escape else start
|
|
345
357
|
return f"https://t.me/{botname}?start={encoded_start}"
|
|
346
358
|
|
|
347
|
-
def make_user_link(username: str, text: str | None = None) -> str:
|
|
348
|
-
"""
|
|
359
|
+
def make_user_link(username: str, text: str | None = None, escape: bool = True) -> str:
|
|
360
|
+
"""
|
|
361
|
+
Return a t.me link to a user.
|
|
349
362
|
|
|
350
363
|
>>> make_user_link("UserName")
|
|
351
364
|
"https://t.me/UserName"
|
|
@@ -363,7 +376,7 @@ def make_user_link(username: str, text: str | None = None) -> str:
|
|
|
363
376
|
username = username.lstrip("@")
|
|
364
377
|
if text is None:
|
|
365
378
|
return f"https://t.me/{username}"
|
|
366
|
-
encoded_text = quote(text, safe="")
|
|
379
|
+
encoded_text = quote(text, safe="") if escape else text
|
|
367
380
|
return f"https://t.me/{username}?text={encoded_text}"
|
|
368
381
|
|
|
369
382
|
def make_qrcode(
|
|
@@ -384,7 +397,8 @@ def make_qrcode(
|
|
|
384
397
|
caption_font_size: int | None = None,
|
|
385
398
|
caption_font_color: str | None = None,
|
|
386
399
|
) -> str:
|
|
387
|
-
"""
|
|
400
|
+
"""
|
|
401
|
+
Return a QuickChart URL that renders a QR code.
|
|
388
402
|
|
|
389
403
|
>>> make_qrcode("https://example.com")
|
|
390
404
|
'https://quickchart.io/qr?text=https%3A%2F%2Fexample.com'
|
|
@@ -427,9 +441,9 @@ def make_qrcode(
|
|
|
427
441
|
if margin is not None:
|
|
428
442
|
params["margin"] = margin
|
|
429
443
|
if dark is not None:
|
|
430
|
-
params["dark"] = dark
|
|
444
|
+
params["dark"] = dark.lstrip("#")
|
|
431
445
|
if light is not None:
|
|
432
|
-
params["light"] = light
|
|
446
|
+
params["light"] = light.lstrip("#")
|
|
433
447
|
if ec_level is not None:
|
|
434
448
|
params["ecLevel"] = ec_level
|
|
435
449
|
if format is not None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: telekit
|
|
3
|
-
Version: 2.5.
|
|
3
|
+
Version: 2.5.0b2
|
|
4
4
|
Summary: Declarative, developer-friendly library for building Telegram bots
|
|
5
5
|
Home-page: https://github.com/Romashkaa/telekit
|
|
6
6
|
Author: romashka
|
|
@@ -477,7 +477,27 @@ It tries to make Telegram bot development easier.
|
|
|
477
477
|
|
|
478
478
|
---
|
|
479
479
|
|
|
480
|
-
# Changes in version 2.5.
|
|
480
|
+
# Changes in version 2.5.0b2
|
|
481
481
|
|
|
482
482
|
### v2.5.0`b0`
|
|
483
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)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|