telegrinder 0.3.4__py3-none-any.whl → 0.4.0__py3-none-any.whl

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.

Potentially problematic release.


This version of telegrinder might be problematic. Click here for more details.

Files changed (192) hide show
  1. telegrinder/__init__.py +148 -149
  2. telegrinder/api/__init__.py +9 -8
  3. telegrinder/api/api.py +101 -93
  4. telegrinder/api/error.py +20 -16
  5. telegrinder/api/response.py +20 -20
  6. telegrinder/api/token.py +36 -36
  7. telegrinder/bot/__init__.py +72 -66
  8. telegrinder/bot/bot.py +83 -76
  9. telegrinder/bot/cute_types/__init__.py +19 -17
  10. telegrinder/bot/cute_types/base.py +184 -258
  11. telegrinder/bot/cute_types/callback_query.py +400 -385
  12. telegrinder/bot/cute_types/chat_join_request.py +62 -61
  13. telegrinder/bot/cute_types/chat_member_updated.py +157 -160
  14. telegrinder/bot/cute_types/inline_query.py +44 -43
  15. telegrinder/bot/cute_types/message.py +2590 -2637
  16. telegrinder/bot/cute_types/pre_checkout_query.py +42 -0
  17. telegrinder/bot/cute_types/update.py +112 -104
  18. telegrinder/bot/cute_types/utils.py +62 -95
  19. telegrinder/bot/dispatch/__init__.py +59 -55
  20. telegrinder/bot/dispatch/abc.py +76 -77
  21. telegrinder/bot/dispatch/context.py +96 -98
  22. telegrinder/bot/dispatch/dispatch.py +254 -202
  23. telegrinder/bot/dispatch/handler/__init__.py +13 -13
  24. telegrinder/bot/dispatch/handler/abc.py +23 -24
  25. telegrinder/bot/dispatch/handler/audio_reply.py +44 -44
  26. telegrinder/bot/dispatch/handler/base.py +57 -57
  27. telegrinder/bot/dispatch/handler/document_reply.py +44 -44
  28. telegrinder/bot/dispatch/handler/func.py +129 -135
  29. telegrinder/bot/dispatch/handler/media_group_reply.py +44 -43
  30. telegrinder/bot/dispatch/handler/message_reply.py +36 -36
  31. telegrinder/bot/dispatch/handler/photo_reply.py +44 -44
  32. telegrinder/bot/dispatch/handler/sticker_reply.py +37 -37
  33. telegrinder/bot/dispatch/handler/video_reply.py +44 -44
  34. telegrinder/bot/dispatch/middleware/__init__.py +3 -3
  35. telegrinder/bot/dispatch/middleware/abc.py +97 -22
  36. telegrinder/bot/dispatch/middleware/global_middleware.py +70 -0
  37. telegrinder/bot/dispatch/process.py +151 -157
  38. telegrinder/bot/dispatch/return_manager/__init__.py +15 -13
  39. telegrinder/bot/dispatch/return_manager/abc.py +104 -108
  40. telegrinder/bot/dispatch/return_manager/callback_query.py +20 -20
  41. telegrinder/bot/dispatch/return_manager/inline_query.py +15 -15
  42. telegrinder/bot/dispatch/return_manager/message.py +36 -36
  43. telegrinder/bot/dispatch/return_manager/pre_checkout_query.py +20 -0
  44. telegrinder/bot/dispatch/view/__init__.py +15 -13
  45. telegrinder/bot/dispatch/view/abc.py +45 -41
  46. telegrinder/bot/dispatch/view/base.py +231 -200
  47. telegrinder/bot/dispatch/view/box.py +140 -129
  48. telegrinder/bot/dispatch/view/callback_query.py +16 -17
  49. telegrinder/bot/dispatch/view/chat_join_request.py +11 -16
  50. telegrinder/bot/dispatch/view/chat_member.py +37 -39
  51. telegrinder/bot/dispatch/view/inline_query.py +16 -17
  52. telegrinder/bot/dispatch/view/message.py +43 -44
  53. telegrinder/bot/dispatch/view/pre_checkout_query.py +16 -0
  54. telegrinder/bot/dispatch/view/raw.py +116 -114
  55. telegrinder/bot/dispatch/waiter_machine/__init__.py +17 -17
  56. telegrinder/bot/dispatch/waiter_machine/actions.py +14 -13
  57. telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +8 -8
  58. telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +55 -55
  59. telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +59 -57
  60. telegrinder/bot/dispatch/waiter_machine/hasher/message.py +51 -51
  61. telegrinder/bot/dispatch/waiter_machine/hasher/state.py +20 -19
  62. telegrinder/bot/dispatch/waiter_machine/machine.py +251 -172
  63. telegrinder/bot/dispatch/waiter_machine/middleware.py +94 -89
  64. telegrinder/bot/dispatch/waiter_machine/short_state.py +57 -68
  65. telegrinder/bot/polling/__init__.py +4 -4
  66. telegrinder/bot/polling/abc.py +25 -25
  67. telegrinder/bot/polling/polling.py +139 -131
  68. telegrinder/bot/rules/__init__.py +85 -62
  69. telegrinder/bot/rules/abc.py +213 -206
  70. telegrinder/bot/rules/callback_data.py +122 -163
  71. telegrinder/bot/rules/chat_join.py +45 -43
  72. telegrinder/bot/rules/command.py +126 -126
  73. telegrinder/bot/rules/enum_text.py +33 -36
  74. telegrinder/bot/rules/func.py +28 -26
  75. telegrinder/bot/rules/fuzzy.py +24 -24
  76. telegrinder/bot/rules/id.py +24 -0
  77. telegrinder/bot/rules/inline.py +58 -56
  78. telegrinder/bot/rules/integer.py +21 -20
  79. telegrinder/bot/rules/is_from.py +127 -127
  80. telegrinder/bot/rules/logic.py +18 -0
  81. telegrinder/bot/rules/markup.py +42 -43
  82. telegrinder/bot/rules/mention.py +14 -14
  83. telegrinder/bot/rules/message.py +15 -17
  84. telegrinder/bot/rules/message_entities.py +33 -35
  85. telegrinder/bot/rules/node.py +33 -27
  86. telegrinder/bot/rules/payload.py +81 -0
  87. telegrinder/bot/rules/payment_invoice.py +29 -0
  88. telegrinder/bot/rules/regex.py +36 -37
  89. telegrinder/bot/rules/rule_enum.py +72 -72
  90. telegrinder/bot/rules/start.py +42 -42
  91. telegrinder/bot/rules/state.py +35 -37
  92. telegrinder/bot/rules/text.py +38 -33
  93. telegrinder/bot/rules/update.py +15 -15
  94. telegrinder/bot/scenario/__init__.py +5 -5
  95. telegrinder/bot/scenario/abc.py +17 -19
  96. telegrinder/bot/scenario/checkbox.py +174 -176
  97. telegrinder/bot/scenario/choice.py +48 -51
  98. telegrinder/client/__init__.py +12 -4
  99. telegrinder/client/abc.py +100 -75
  100. telegrinder/client/aiohttp.py +134 -130
  101. telegrinder/client/form_data.py +31 -0
  102. telegrinder/client/sonic.py +212 -0
  103. telegrinder/model.py +208 -315
  104. telegrinder/modules.py +239 -237
  105. telegrinder/msgspec_json.py +14 -14
  106. telegrinder/msgspec_utils.py +478 -410
  107. telegrinder/node/__init__.py +86 -25
  108. telegrinder/node/attachment.py +163 -87
  109. telegrinder/node/base.py +288 -160
  110. telegrinder/node/callback_query.py +54 -53
  111. telegrinder/node/command.py +34 -33
  112. telegrinder/node/composer.py +163 -198
  113. telegrinder/node/container.py +33 -27
  114. telegrinder/node/either.py +82 -0
  115. telegrinder/node/event.py +54 -65
  116. telegrinder/node/file.py +51 -0
  117. telegrinder/node/me.py +15 -16
  118. telegrinder/node/payload.py +78 -0
  119. telegrinder/node/polymorphic.py +67 -48
  120. telegrinder/node/rule.py +72 -76
  121. telegrinder/node/scope.py +36 -38
  122. telegrinder/node/source.py +87 -71
  123. telegrinder/node/text.py +53 -41
  124. telegrinder/node/tools/__init__.py +3 -3
  125. telegrinder/node/tools/generator.py +36 -40
  126. telegrinder/py.typed +0 -0
  127. telegrinder/rules.py +1 -62
  128. telegrinder/tools/__init__.py +152 -93
  129. telegrinder/tools/adapter/__init__.py +19 -0
  130. telegrinder/tools/adapter/abc.py +49 -0
  131. telegrinder/tools/adapter/dataclass.py +56 -0
  132. telegrinder/{bot/rules → tools}/adapter/errors.py +5 -5
  133. telegrinder/{bot/rules → tools}/adapter/event.py +63 -65
  134. telegrinder/{bot/rules → tools}/adapter/node.py +46 -48
  135. telegrinder/{bot/rules → tools}/adapter/raw_event.py +27 -27
  136. telegrinder/{bot/rules → tools}/adapter/raw_update.py +30 -30
  137. telegrinder/tools/buttons.py +106 -80
  138. telegrinder/tools/callback_data_serilization/__init__.py +5 -0
  139. telegrinder/tools/callback_data_serilization/abc.py +51 -0
  140. telegrinder/tools/callback_data_serilization/json_ser.py +60 -0
  141. telegrinder/tools/callback_data_serilization/msgpack_ser.py +172 -0
  142. telegrinder/tools/error_handler/__init__.py +7 -7
  143. telegrinder/tools/error_handler/abc.py +30 -33
  144. telegrinder/tools/error_handler/error.py +9 -9
  145. telegrinder/tools/error_handler/error_handler.py +179 -193
  146. telegrinder/tools/formatting/__init__.py +83 -63
  147. telegrinder/tools/formatting/deep_links.py +541 -0
  148. telegrinder/tools/formatting/{html.py → html_formatter.py} +266 -294
  149. telegrinder/tools/formatting/spec_html_formats.py +71 -117
  150. telegrinder/tools/functional.py +8 -12
  151. telegrinder/tools/global_context/__init__.py +7 -7
  152. telegrinder/tools/global_context/abc.py +63 -63
  153. telegrinder/tools/global_context/global_context.py +387 -412
  154. telegrinder/tools/global_context/telegrinder_ctx.py +27 -27
  155. telegrinder/tools/i18n/__init__.py +7 -7
  156. telegrinder/tools/i18n/abc.py +30 -30
  157. telegrinder/tools/i18n/middleware/__init__.py +3 -3
  158. telegrinder/tools/i18n/middleware/abc.py +22 -25
  159. telegrinder/tools/i18n/simple.py +43 -43
  160. telegrinder/tools/input_file_directory.py +30 -0
  161. telegrinder/tools/keyboard.py +128 -128
  162. telegrinder/tools/lifespan.py +105 -0
  163. telegrinder/tools/limited_dict.py +32 -37
  164. telegrinder/tools/loop_wrapper/__init__.py +4 -4
  165. telegrinder/tools/loop_wrapper/abc.py +20 -15
  166. telegrinder/tools/loop_wrapper/loop_wrapper.py +169 -224
  167. telegrinder/tools/magic.py +307 -157
  168. telegrinder/tools/parse_mode.py +6 -6
  169. telegrinder/tools/state_storage/__init__.py +4 -4
  170. telegrinder/tools/state_storage/abc.py +31 -35
  171. telegrinder/tools/state_storage/memory.py +25 -25
  172. telegrinder/tools/strings.py +13 -0
  173. telegrinder/types/__init__.py +268 -260
  174. telegrinder/types/enums.py +711 -701
  175. telegrinder/types/input_file.py +51 -0
  176. telegrinder/types/methods.py +5055 -4633
  177. telegrinder/types/objects.py +7058 -6950
  178. telegrinder/verification_utils.py +30 -32
  179. {telegrinder-0.3.4.dist-info → telegrinder-0.4.0.dist-info}/LICENSE +22 -22
  180. telegrinder-0.4.0.dist-info/METADATA +144 -0
  181. telegrinder-0.4.0.dist-info/RECORD +182 -0
  182. {telegrinder-0.3.4.dist-info → telegrinder-0.4.0.dist-info}/WHEEL +1 -1
  183. telegrinder/bot/rules/adapter/__init__.py +0 -17
  184. telegrinder/bot/rules/adapter/abc.py +0 -31
  185. telegrinder/node/message.py +0 -14
  186. telegrinder/node/update.py +0 -15
  187. telegrinder/tools/formatting/links.py +0 -38
  188. telegrinder/tools/kb_set/__init__.py +0 -4
  189. telegrinder/tools/kb_set/base.py +0 -15
  190. telegrinder/tools/kb_set/yaml.py +0 -63
  191. telegrinder-0.3.4.dist-info/METADATA +0 -110
  192. telegrinder-0.3.4.dist-info/RECORD +0 -165
@@ -1,385 +1,400 @@
1
- import typing
2
- from contextlib import suppress
3
-
4
- import msgspec
5
- from fntypes.co import Nothing, Result, Some, Variative, unwrapping
6
-
7
- from telegrinder.api import API, APIError
8
- from telegrinder.bot.cute_types.base import BaseCute, compose_method_params, shortcut
9
- from telegrinder.bot.cute_types.message import MediaType, MessageCute, ReplyMarkup, execute_method_edit
10
- from telegrinder.model import From, field, get_params
11
- from telegrinder.msgspec_utils import Option, decoder
12
- from telegrinder.types.objects import *
13
-
14
-
15
- class CallbackQueryCute(BaseCute[CallbackQuery], CallbackQuery, kw_only=True):
16
- api: API
17
-
18
- message: Option[Variative[MessageCute, InaccessibleMessage]] = field(
19
- default=Nothing(),
20
- converter=From[MessageCute | InaccessibleMessage | None],
21
- )
22
- """Optional. Message sent by the bot with the callback button that originated
23
- the query."""
24
-
25
- @property
26
- def from_user(self) -> User:
27
- return self.from_
28
-
29
- @property
30
- def chat_id(self) -> Option[int]:
31
- """Optional. Message from chat ID. This will be present if the message is sent
32
- by the bot with the callback button that originated the query."""
33
-
34
- return self.message.map(lambda m: m.v.chat.id)
35
-
36
- @property
37
- def is_topic_message(self) -> Option[bool]:
38
- """Optional. True, if the message is a topic message with a name,
39
- color and icon. This will be present if the message is sent
40
- by the bot with the callback button that originated the query."""
41
-
42
- return self.message.map(
43
- lambda m: m.only().map(lambda m: m.is_topic_message.unwrap_or(False)).unwrap_or(False),
44
- )
45
-
46
- @property
47
- @unwrapping
48
- def message_thread_id(self) -> Option[int]:
49
- """Optional. Unique identifier of the target message thread (for forum supergroups only).
50
- This will be present if the message is sent
51
- by the bot with the callback button that originated the query."""
52
-
53
- return self.message.unwrap().only().map(lambda m: m.message_thread_id.unwrap()).cast(Some, Nothing)
54
-
55
- @property
56
- def message_id(self) -> Option[int]:
57
- """Optional. Unique message identifier inside this chat. This will be present
58
- if the message is sent by the bot with the callback button that originated the query.
59
- """
60
-
61
- return self.message.map(lambda m: m.v.message_id)
62
-
63
- @property
64
- def chat(self) -> Option[Chat]:
65
- """Optional. Chat the callback query originated from. This will be present
66
- if the message is sent by the bot with the callback button that originated the query.
67
- """
68
-
69
- return self.message.map(lambda m: m.v.chat)
70
-
71
- def decode_callback_data(self) -> Option[dict[str, typing.Any]]:
72
- if "cached_callback_data" in self.__dict__:
73
- return self.__dict__["cached_callback_data"]
74
- data = Nothing()
75
- with suppress(msgspec.ValidationError, msgspec.DecodeError):
76
- data = Some(decoder.decode(self.data.unwrap()))
77
- self.__dict__["cached_callback_data"] = data
78
- return data
79
-
80
- @shortcut("answer_callback_query", custom_params={"callback_query_id"})
81
- async def answer(
82
- self,
83
- text: str | None = None,
84
- callback_query_id: str | None = None,
85
- show_alert: bool | None = None,
86
- url: str | None = None,
87
- cache_time: int | None = None,
88
- **other: typing.Any,
89
- ) -> Result[bool, APIError]:
90
- """Shortcut `API.answer_callback_query()`, see the [documentation](https://core.telegram.org/bots/api#answercallbackquery)
91
-
92
- Use this method to send answers to callback queries sent from inline keyboards.
93
- The answer will be displayed to the user as a notification at the top of the
94
- chat screen or as an alert. On success, True is returned."""
95
-
96
- params = compose_method_params(
97
- get_params(locals()), self, default_params={("callback_query_id", "id")}
98
- )
99
- return await self.ctx_api.answer_callback_query(**params)
100
-
101
- @shortcut(
102
- "copy_message",
103
- custom_params={
104
- "reply_parameters",
105
- "message_thread_id",
106
- "chat_id",
107
- "message_id",
108
- "from_chat_id",
109
- "reply_markup",
110
- },
111
- )
112
- async def copy(
113
- self,
114
- chat_id: int | str | None = None,
115
- from_chat_id: int | str | None = None,
116
- message_id: int | None = None,
117
- message_thread_id: int | None = None,
118
- caption: str | None = None,
119
- parse_mode: str | None = None,
120
- caption_entities: list[MessageEntity] | None = None,
121
- disable_notification: bool | None = None,
122
- protect_content: bool | None = None,
123
- reply_parameters: ReplyParameters | dict[str, typing.Any] | None = None,
124
- reply_markup: ReplyMarkup | None = None,
125
- show_caption_above_media: bool | None = None,
126
- **other: typing.Any,
127
- ) -> Result[MessageId, APIError]:
128
- """Shortcut `API.copy_message()`, see the [documentation](https://core.telegram.org/bots/api#copymessage)
129
-
130
- Use this method to copy messages of any kind. Service messages, paid media
131
- messages, giveaway messages, giveaway winners messages, and invoice
132
- messages can't be copied. A quiz poll can be copied only if the value of the
133
- field correct_option_id is known to the bot. The method is analogous to
134
- the method forwardMessage, but the copied message doesn't have a link to
135
- the original message. Returns the MessageId of the sent message on success."""
136
-
137
- return await MessageCute.copy(self, **get_params(locals())) # type: ignore
138
-
139
- @shortcut("delete_message", custom_params={"message_thread_id", "chat_id", "message_id"})
140
- async def delete(
141
- self,
142
- chat_id: int | None = None,
143
- message_id: int | None = None,
144
- message_thread_id: int | None = None,
145
- **other: typing.Any,
146
- ) -> Result[bool, APIError]:
147
- """Shortcut `API.delete_message()`, see the [documentation](https://core.telegram.org/bots/api#deletemessage)
148
-
149
- Use this method to delete a message, including service messages, with the
150
- following limitations: - A message can only be deleted if it was sent less
151
- than 48 hours ago. - Service messages about a supergroup, channel, or forum
152
- topic creation can't be deleted. - A dice message in a private chat can only
153
- be deleted if it was sent more than 24 hours ago. - Bots can delete outgoing
154
- messages in private chats, groups, and supergroups. - Bots can delete incoming
155
- messages in private chats. - Bots granted can_post_messages permissions
156
- can delete outgoing messages in channels. - If the bot is an administrator
157
- of a group, it can delete any message there. - If the bot has can_delete_messages
158
- permission in a supergroup or a channel, it can delete any message there.
159
- Returns True on success."""
160
-
161
- return await MessageCute.delete(self, **get_params(locals())) # type: ignore
162
-
163
- @shortcut(
164
- "edit_message_text",
165
- executor=execute_method_edit,
166
- custom_params={"message_thread_id", "link_preview_options"},
167
- )
168
- async def edit_text(
169
- self,
170
- text: str,
171
- inline_message_id: str | None = None,
172
- chat_id: int | str | None = None,
173
- message_id: int | None = None,
174
- message_thread_id: int | None = None,
175
- parse_mode: str | None = None,
176
- entities: list[MessageEntity] | None = None,
177
- link_preview_options: LinkPreviewOptions | dict[str, typing.Any] | None = None,
178
- reply_markup: InlineKeyboardMarkup | None = None,
179
- business_connection_id: str | None = None,
180
- **other: typing.Any,
181
- ) -> Result[Variative[MessageCute, bool], APIError]:
182
- """Shortcut `API.edit_message_text()`, see the [documentation](https://core.telegram.org/bots/api#editmessagetext)
183
-
184
- Use this method to edit text and game messages. On success, if the edited
185
- message is not an inline message, the edited Message is returned, otherwise
186
- True is returned. Note that business messages that were not sent by the bot
187
- and do not contain an inline keyboard can only be edited within 48 hours from
188
- the time they were sent.
189
- :param business_connection_id: Unique identifier of the business connection on behalf of which the messageto be edited was sent.
190
-
191
- :param chat_id: Required if inline_message_id is not specified. Unique identifier forthe target chat or username of the target channel (in the format @channelusername).
192
- :param message_id: Required if inline_message_id is not specified. Identifier of the messageto edit.
193
-
194
- :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of theinline message.
195
-
196
- :param text: New text of the message, 1-4096 characters after entities parsing.
197
-
198
- :param parse_mode: Mode for parsing entities in the message text. See formatting options formore details.
199
-
200
- :param entities: A JSON-serialized list of special entities that appear in message text,which can be specified instead of parse_mode.
201
-
202
- :param link_preview_options: Link preview generation options for the message.
203
-
204
- :param reply_markup: A JSON-serialized object for an inline keyboard."""
205
-
206
- ...
207
-
208
- @shortcut(
209
- "edit_message_live_location",
210
- executor=execute_method_edit,
211
- custom_params={"message_thread_id"},
212
- )
213
- async def edit_live_location(
214
- self,
215
- latitude: float,
216
- longitude: float,
217
- inline_message_id: str | None = None,
218
- message_thread_id: int | None = None,
219
- chat_id: int | str | None = None,
220
- message_id: int | None = None,
221
- horizontal_accuracy: float | None = None,
222
- heading: int | None = None,
223
- proximity_alert_radius: int | None = None,
224
- reply_markup: InlineKeyboardMarkup | None = None,
225
- business_connection_id: str | None = None,
226
- live_period: int | None = None,
227
- **other: typing.Any,
228
- ) -> Result[Variative[MessageCute, bool], APIError]:
229
- """Shortcut `API.edit_message_live_location()`, see the [documentation](https://core.telegram.org/bots/api#editmessagelivelocation)
230
-
231
- Use this method to edit live location messages. A location can be edited
232
- until its live_period expires or editing is explicitly disabled by a call
233
- to stopMessageLiveLocation. On success, if the edited message is not an
234
- inline message, the edited Message is returned, otherwise True is returned.
235
- :param business_connection_id: Unique identifier of the business connection on behalf of which the messageto be edited was sent.
236
-
237
- :param chat_id: Required if inline_message_id is not specified. Unique identifier forthe target chat or username of the target channel (in the format @channelusername).
238
- :param message_id: Required if inline_message_id is not specified. Identifier of the messageto edit.
239
-
240
- :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of theinline message.
241
-
242
- :param latitude: Latitude of new location.
243
-
244
- :param longitude: Longitude of new location.
245
-
246
- :param live_period: New period in seconds during which the location can be updated, startingfrom the message send date. If 0x7FFFFFFF is specified, then the locationcan be updated forever. Otherwise, the new value must not exceed the currentlive_period by more than a day, and the live location expiration date mustremain within the next 90 days. If not specified, then live_period remainsunchanged.
247
-
248
- :param horizontal_accuracy: The radius of uncertainty for the location, measured in meters; 0-1500.
249
- :param heading: Direction in which the user is moving, in degrees. Must be between 1 and 360if specified.
250
-
251
- :param proximity_alert_radius: The maximum distance for proximity alerts about approaching another chatmember, in meters. Must be between 1 and 100000 if specified.
252
-
253
- :param reply_markup: A JSON-serialized object for a new inline keyboard."""
254
-
255
- ...
256
-
257
- @shortcut(
258
- "edit_message_caption",
259
- executor=execute_method_edit,
260
- custom_params={"message_thread_id"},
261
- )
262
- async def edit_caption(
263
- self,
264
- caption: str | None = None,
265
- chat_id: int | str | None = None,
266
- message_id: int | None = None,
267
- message_thread_id: int | None = None,
268
- inline_message_id: str | None = None,
269
- parse_mode: str | None = None,
270
- caption_entities: list[MessageEntity] | None = None,
271
- reply_markup: InlineKeyboardMarkup | None = None,
272
- business_connection_id: str | None = None,
273
- show_caption_above_media: bool | None = None,
274
- **other: typing.Any,
275
- ) -> Result[Variative[MessageCute, bool], APIError]:
276
- """Shortcut `API.edit_message_caption()`, see the [documentation](https://core.telegram.org/bots/api#editmessagecaption)
277
-
278
- Use this method to edit captions of messages. On success, if the edited message
279
- is not an inline message, the edited Message is returned, otherwise True
280
- is returned. Note that business messages that were not sent by the bot and
281
- do not contain an inline keyboard can only be edited within 48 hours from
282
- the time they were sent.
283
- :param business_connection_id: Unique identifier of the business connection on behalf of which the messageto be edited was sent.
284
-
285
- :param chat_id: Required if inline_message_id is not specified. Unique identifier forthe target chat or username of the target channel (in the format @channelusername).
286
- :param message_id: Required if inline_message_id is not specified. Identifier of the messageto edit.
287
-
288
- :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of theinline message.
289
-
290
- :param caption: New caption of the message, 0-1024 characters after entities parsing.
291
- :param parse_mode: Mode for parsing entities in the message caption. See formatting optionsfor more details.
292
-
293
- :param caption_entities: A JSON-serialized list of special entities that appear in the caption,which can be specified instead of parse_mode.
294
-
295
- :param show_caption_above_media: Pass True, if the caption must be shown above the message media. Supportedonly for animation, photo and video messages.
296
-
297
- :param reply_markup: A JSON-serialized object for an inline keyboard."""
298
-
299
- ...
300
-
301
- @shortcut(
302
- "edit_message_media",
303
- custom_params={
304
- "media",
305
- "type",
306
- "message_thread_id",
307
- "caption",
308
- "parse_mode",
309
- "caption_entities",
310
- },
311
- )
312
- async def edit_media(
313
- self,
314
- media: str | InputFile | InputMedia,
315
- type: MediaType | None = None,
316
- caption: str | None = None,
317
- parse_mode: str | None = None,
318
- caption_entities: list[MessageEntity] | None = None,
319
- inline_message_id: str | None = None,
320
- chat_id: int | str | None = None,
321
- message_id: int | None = None,
322
- message_thread_id: int | None = None,
323
- reply_markup: InlineKeyboardMarkup | None = None,
324
- business_connection_id: str | None = None,
325
- **other: typing.Any,
326
- ) -> Result[Variative[MessageCute, bool], APIError]:
327
- """Shortcut `API.edit_message_media()`, see the [documentation](https://core.telegram.org/bots/api#editmessagemedia)
328
-
329
- Use this method to edit animation, audio, document, photo, or video messages.
330
- If a message is part of a message album, then it can be edited only to an audio
331
- for audio albums, only to a document for document albums and to a photo or
332
- a video otherwise. When an inline message is edited, a new file can't be uploaded;
333
- use a previously uploaded file via its file_id or specify a URL. On success,
334
- if the edited message is not an inline message, the edited Message is returned,
335
- otherwise True is returned. Note that business messages that were not sent
336
- by the bot and do not contain an inline keyboard can only be edited within
337
- 48 hours from the time they were sent.
338
- :param business_connection_id: Unique identifier of the business connection on behalf of which the messageto be edited was sent.
339
-
340
- :param chat_id: Required if inline_message_id is not specified. Unique identifier forthe target chat or username of the target channel (in the format @channelusername).
341
- :param message_id: Required if inline_message_id is not specified. Identifier of the messageto edit.
342
-
343
- :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of theinline message.
344
-
345
- :param media: A JSON-serialized object for a new media content of the message.
346
-
347
- :param reply_markup: A JSON-serialized object for a new inline keyboard."""
348
-
349
- return await MessageCute.edit_media(self, **get_params(locals())) # type: ignore
350
-
351
- @shortcut(
352
- "edit_message_reply_markup",
353
- executor=execute_method_edit,
354
- custom_params={"message_thread_id"},
355
- )
356
- async def edit_reply_markup(
357
- self,
358
- inline_message_id: str | None = None,
359
- message_id: int | None = None,
360
- message_thread_id: int | None = None,
361
- chat_id: int | str | None = None,
362
- reply_markup: InlineKeyboardMarkup | None = None,
363
- business_connection_id: str | None = None,
364
- **other: typing.Any,
365
- ) -> Result[Variative[MessageCute, bool], APIError]:
366
- """Shortcut `API.edit_message_reply_markup()`, see the [documentation](https://core.telegram.org/bots/api#editmessagereplymarkup)
367
-
368
- Use this method to edit only the reply markup of messages. On success, if
369
- the edited message is not an inline message, the edited Message is returned,
370
- otherwise True is returned. Note that business messages that were not sent
371
- by the bot and do not contain an inline keyboard can only be edited within
372
- 48 hours from the time they were sent.
373
- :param business_connection_id: Unique identifier of the business connection on behalf of which the messageto be edited was sent.
374
-
375
- :param chat_id: Required if inline_message_id is not specified. Unique identifier forthe target chat or username of the target channel (in the format @channelusername).
376
- :param message_id: Required if inline_message_id is not specified. Identifier of the messageto edit.
377
-
378
- :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of theinline message.
379
-
380
- :param reply_markup: A JSON-serialized object for an inline keyboard."""
381
-
382
- ...
383
-
384
-
385
- __all__ = ("CallbackQueryCute",)
1
+ import base64
2
+ import typing
3
+ from contextlib import suppress
4
+
5
+ import msgspec
6
+ from fntypes.co import Nothing, Result, Some, Variative, unwrapping
7
+
8
+ from telegrinder.api import API, APIError
9
+ from telegrinder.bot.cute_types.base import BaseCute, compose_method_params
10
+ from telegrinder.bot.cute_types.message import MediaType, MessageCute, ReplyMarkup, execute_method_edit
11
+ from telegrinder.model import UNSET, From, field, get_params
12
+ from telegrinder.msgspec_utils import Option, decoder
13
+ from telegrinder.tools.magic import shortcut
14
+ from telegrinder.types.objects import *
15
+
16
+
17
+ class CallbackQueryCute(BaseCute[CallbackQuery], CallbackQuery, kw_only=True):
18
+ api: API
19
+
20
+ message: Option[Variative[MessageCute, InaccessibleMessage]] = field(
21
+ default=UNSET,
22
+ converter=From[MessageCute | InaccessibleMessage | None],
23
+ )
24
+ """Optional. Message sent by the bot with the callback button that originated
25
+ the query."""
26
+
27
+ @property
28
+ def from_user(self) -> User:
29
+ return self.from_
30
+
31
+ @property
32
+ def chat_id(self) -> Option[int]:
33
+ """Optional. Message from chat ID. This will be present if the message is sent
34
+ by the bot with the callback button that originated the query.
35
+ """
36
+ return self.message.map(lambda m: m.v.chat.id)
37
+
38
+ @property
39
+ def is_topic_message(self) -> Option[bool]:
40
+ """Optional. True, if the message is a topic message with a name,
41
+ color and icon. This will be present if the message is sent
42
+ by the bot with the callback button that originated the query.
43
+ """
44
+ return self.message.map(
45
+ lambda m: m.only().map(lambda m: m.is_topic_message.unwrap_or(False)).unwrap_or(False),
46
+ )
47
+
48
+ @property
49
+ @unwrapping
50
+ def message_thread_id(self) -> Option[int]:
51
+ """Optional. Unique identifier of the target message thread (for forum supergroups only).
52
+ This will be present if the message is sent
53
+ by the bot with the callback button that originated the query.
54
+ """
55
+ return self.message.unwrap().only().map(lambda m: m.message_thread_id.unwrap()).cast(Some, Nothing)
56
+
57
+ @property
58
+ def message_id(self) -> Option[int]:
59
+ """Optional. Unique message identifier inside this chat. This will be present
60
+ if the message is sent by the bot with the callback button that originated the query.
61
+ """
62
+ return self.message.map(lambda m: m.v.message_id)
63
+
64
+ @property
65
+ def chat(self) -> Option[Chat]:
66
+ """Optional. Chat the callback query originated from. This will be present
67
+ if the message is sent by the bot with the callback button that originated the query.
68
+ """
69
+ return self.message.map(lambda m: m.v.chat)
70
+
71
+ @typing.overload
72
+ def decode_data(self) -> Option[dict[str, typing.Any]]: ...
73
+
74
+ @typing.overload
75
+ def decode_data[T](self, *, to: type[T]) -> Option[T]: ...
76
+
77
+ def decode_data[T](self, *, to: type[T] = dict[str, typing.Any]) -> Option[T]:
78
+ if not self.data:
79
+ return Nothing()
80
+
81
+ if "cached_callback_data" in self.__dict__:
82
+ return self.__dict__["cached_callback_data"]
83
+
84
+ data = Nothing()
85
+ with suppress(msgspec.ValidationError, msgspec.DecodeError):
86
+ data = (
87
+ Some(decoder.decode(self.data.unwrap(), type=to))
88
+ if not issubclass(to, str | bytes)
89
+ else self.data
90
+ if issubclass(to, str)
91
+ else Some(base64.urlsafe_b64decode(self.data.unwrap()))
92
+ )
93
+
94
+ self.__dict__["cached_callback_data"] = data
95
+ return data # type: ignore
96
+
97
+ @shortcut("answer_callback_query", custom_params={"callback_query_id"})
98
+ async def answer(
99
+ self,
100
+ text: str | None = None,
101
+ *,
102
+ cache_time: int | None = None,
103
+ callback_query_id: str | None = None,
104
+ show_alert: bool | None = None,
105
+ url: str | None = None,
106
+ **other: typing.Any,
107
+ ) -> Result[bool, APIError]:
108
+ """Shortcut `API.answer_callback_query()`, see the [documentation](https://core.telegram.org/bots/api#answercallbackquery)
109
+
110
+ Use this method to send answers to callback queries sent from inline keyboards.
111
+ The answer will be displayed to the user as a notification at the top of the
112
+ chat screen or as an alert. On success, True is returned."""
113
+ params = compose_method_params(get_params(locals()), self, default_params={("callback_query_id", "id")})
114
+ return await self.ctx_api.answer_callback_query(**params)
115
+
116
+ @shortcut(
117
+ "copy_message",
118
+ custom_params={
119
+ "message_thread_id",
120
+ "chat_id",
121
+ "message_id",
122
+ "from_chat_id",
123
+ "reply_markup",
124
+ },
125
+ )
126
+ async def copy(
127
+ self,
128
+ chat_id: int | str | None = None,
129
+ *,
130
+ allow_paid_broadcast: bool | None = None,
131
+ caption: str | None = None,
132
+ caption_entities: list[MessageEntity] | None = None,
133
+ disable_notification: bool | None = None,
134
+ from_chat_id: int | str | None = None,
135
+ message_id: int | None = None,
136
+ message_thread_id: int | None = None,
137
+ parse_mode: str | None = None,
138
+ protect_content: bool | None = None,
139
+ reply_markup: ReplyMarkup | None = None,
140
+ reply_parameters: ReplyParameters | None = None,
141
+ show_caption_above_media: bool | None = None,
142
+ video_start_timestamp: int | None = None,
143
+ **other: typing.Any,
144
+ ) -> Result[MessageId, APIError]:
145
+ """Shortcut `API.copy_message()`, see the [documentation](https://core.telegram.org/bots/api#copymessage)
146
+
147
+ Use this method to copy messages of any kind. Service messages, paid media
148
+ messages, giveaway messages, giveaway winners messages, and invoice
149
+ messages can't be copied. A quiz poll can be copied only if the value of the
150
+ field correct_option_id is known to the bot. The method is analogous to
151
+ the method forwardMessage, but the copied message doesn't have a link to
152
+ the original message. Returns the MessageId of the sent message on success."""
153
+ return await MessageCute.copy(self, **get_params(locals())) # type: ignore
154
+
155
+ @shortcut("delete_message", custom_params={"message_thread_id", "chat_id", "message_id"})
156
+ async def delete(
157
+ self,
158
+ *,
159
+ chat_id: int | None = None,
160
+ message_id: int | None = None,
161
+ message_thread_id: int | None = None,
162
+ **other: typing.Any,
163
+ ) -> Result[bool, APIError]:
164
+ """Shortcut `API.delete_message()`, see the [documentation](https://core.telegram.org/bots/api#deletemessage)
165
+
166
+ Use this method to delete a message, including service messages, with the
167
+ following limitations: - A message can only be deleted if it was sent less
168
+ than 48 hours ago. - Service messages about a supergroup, channel, or forum
169
+ topic creation can't be deleted. - A dice message in a private chat can only
170
+ be deleted if it was sent more than 24 hours ago. - Bots can delete outgoing
171
+ messages in private chats, groups, and supergroups. - Bots can delete incoming
172
+ messages in private chats. - Bots granted can_post_messages permissions
173
+ can delete outgoing messages in channels. - If the bot is an administrator
174
+ of a group, it can delete any message there. - If the bot has can_delete_messages
175
+ permission in a supergroup or a channel, it can delete any message there.
176
+ Returns True on success."""
177
+ return await MessageCute.delete(self, **get_params(locals())) # type: ignore
178
+
179
+ @shortcut(
180
+ "edit_message_text",
181
+ executor=execute_method_edit,
182
+ custom_params={"message_thread_id"},
183
+ )
184
+ async def edit_text(
185
+ self,
186
+ text: str,
187
+ *,
188
+ business_connection_id: str | None = None,
189
+ chat_id: int | str | None = None,
190
+ entities: list[MessageEntity] | None = None,
191
+ inline_message_id: str | None = None,
192
+ link_preview_options: LinkPreviewOptions | None = None,
193
+ message_id: int | None = None,
194
+ message_thread_id: int | None = None,
195
+ parse_mode: str | None = None,
196
+ reply_markup: InlineKeyboardMarkup | None = None,
197
+ **other: typing.Any,
198
+ ) -> Result[Variative[MessageCute, bool], APIError]:
199
+ """Shortcut `API.edit_message_text()`, see the [documentation](https://core.telegram.org/bots/api#editmessagetext)
200
+
201
+ Use this method to edit text and game messages. On success, if the edited
202
+ message is not an inline message, the edited Message is returned, otherwise
203
+ True is returned. Note that business messages that were not sent by the bot
204
+ and do not contain an inline keyboard can only be edited within 48 hours from
205
+ the time they were sent.
206
+ :param business_connection_id: Unique identifier of the business connection on behalf of which the messageto be edited was sent.
207
+
208
+ :param chat_id: Required if inline_message_id is not specified. Unique identifier forthe target chat or username of the target channel (in the format @channelusername).
209
+ :param message_id: Required if inline_message_id is not specified. Identifier of the messageto edit.
210
+
211
+ :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of theinline message.
212
+
213
+ :param text: New text of the message, 1-4096 characters after entities parsing.
214
+
215
+ :param parse_mode: Mode for parsing entities in the message text. See formatting options formore details.
216
+
217
+ :param entities: A JSON-serialized list of special entities that appear in message text,which can be specified instead of parse_mode.
218
+
219
+ :param link_preview_options: Link preview generation options for the message.
220
+
221
+ :param reply_markup: A JSON-serialized object for an inline keyboard."""
222
+ ...
223
+
224
+ @shortcut(
225
+ "edit_message_live_location",
226
+ executor=execute_method_edit,
227
+ custom_params={"message_thread_id"},
228
+ )
229
+ async def edit_live_location(
230
+ self,
231
+ *,
232
+ longitude: float,
233
+ business_connection_id: str | None = None,
234
+ chat_id: int | str | None = None,
235
+ heading: int | None = None,
236
+ horizontal_accuracy: float | None = None,
237
+ inline_message_id: str | None = None,
238
+ live_period: int | None = None,
239
+ message_id: int | None = None,
240
+ message_thread_id: int | None = None,
241
+ proximity_alert_radius: int | None = None,
242
+ reply_markup: InlineKeyboardMarkup | None = None,
243
+ **other: typing.Any,
244
+ ) -> Result[Variative[MessageCute, bool], APIError]:
245
+ """Shortcut `API.edit_message_live_location()`, see the [documentation](https://core.telegram.org/bots/api#editmessagelivelocation)
246
+
247
+ Use this method to edit live location messages. A location can be edited
248
+ until its live_period expires or editing is explicitly disabled by a call
249
+ to stopMessageLiveLocation. On success, if the edited message is not an
250
+ inline message, the edited Message is returned, otherwise True is returned.
251
+ :param business_connection_id: Unique identifier of the business connection on behalf of which the messageto be edited was sent.
252
+
253
+ :param chat_id: Required if inline_message_id is not specified. Unique identifier forthe target chat or username of the target channel (in the format @channelusername).
254
+ :param message_id: Required if inline_message_id is not specified. Identifier of the messageto edit.
255
+
256
+ :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of theinline message.
257
+
258
+ :param latitude: Latitude of new location.
259
+
260
+ :param longitude: Longitude of new location.
261
+
262
+ :param live_period: New period in seconds during which the location can be updated, startingfrom the message send date. If 0x7FFFFFFF is specified, then the locationcan be updated forever. Otherwise, the new value must not exceed the currentlive_period by more than a day, and the live location expiration date mustremain within the next 90 days. If not specified, then live_period remainsunchanged.
263
+
264
+ :param horizontal_accuracy: The radius of uncertainty for the location, measured in meters; 0-1500.
265
+ :param heading: Direction in which the user is moving, in degrees. Must be between 1 and 360if specified.
266
+
267
+ :param proximity_alert_radius: The maximum distance for proximity alerts about approaching another chatmember, in meters. Must be between 1 and 100000 if specified.
268
+
269
+ :param reply_markup: A JSON-serialized object for a new inline keyboard."""
270
+ ...
271
+
272
+ @shortcut(
273
+ "edit_message_caption",
274
+ executor=execute_method_edit,
275
+ custom_params={"message_thread_id"},
276
+ )
277
+ async def edit_caption(
278
+ self,
279
+ caption: str | None = None,
280
+ *,
281
+ business_connection_id: str | None = None,
282
+ caption_entities: list[MessageEntity] | None = None,
283
+ chat_id: int | str | None = None,
284
+ inline_message_id: str | None = None,
285
+ message_id: int | None = None,
286
+ message_thread_id: int | None = None,
287
+ parse_mode: str | None = None,
288
+ reply_markup: InlineKeyboardMarkup | None = None,
289
+ show_caption_above_media: bool | None = None,
290
+ **other: typing.Any,
291
+ ) -> Result[Variative[MessageCute, bool], APIError]:
292
+ """Shortcut `API.edit_message_caption()`, see the [documentation](https://core.telegram.org/bots/api#editmessagecaption)
293
+
294
+ Use this method to edit captions of messages. On success, if the edited message
295
+ is not an inline message, the edited Message is returned, otherwise True
296
+ is returned. Note that business messages that were not sent by the bot and
297
+ do not contain an inline keyboard can only be edited within 48 hours from
298
+ the time they were sent.
299
+ :param business_connection_id: Unique identifier of the business connection on behalf of which the messageto be edited was sent.
300
+
301
+ :param chat_id: Required if inline_message_id is not specified. Unique identifier forthe target chat or username of the target channel (in the format @channelusername).
302
+ :param message_id: Required if inline_message_id is not specified. Identifier of the messageto edit.
303
+
304
+ :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of theinline message.
305
+
306
+ :param caption: New caption of the message, 0-1024 characters after entities parsing.
307
+ :param parse_mode: Mode for parsing entities in the message caption. See formatting optionsfor more details.
308
+
309
+ :param caption_entities: A JSON-serialized list of special entities that appear in the caption,which can be specified instead of parse_mode.
310
+
311
+ :param show_caption_above_media: Pass True, if the caption must be shown above the message media. Supportedonly for animation, photo and video messages.
312
+
313
+ :param reply_markup: A JSON-serialized object for an inline keyboard."""
314
+ ...
315
+
316
+ @shortcut(
317
+ "edit_message_media",
318
+ custom_params={
319
+ "media",
320
+ "type",
321
+ "message_thread_id",
322
+ "caption",
323
+ "parse_mode",
324
+ "caption_entities",
325
+ },
326
+ )
327
+ async def edit_media(
328
+ self,
329
+ media: str | InputFile | InputMedia,
330
+ *,
331
+ business_connection_id: str | None = None,
332
+ caption: str | None = None,
333
+ caption_entities: list[MessageEntity] | None = None,
334
+ chat_id: int | str | None = None,
335
+ inline_message_id: str | None = None,
336
+ message_id: int | None = None,
337
+ message_thread_id: int | None = None,
338
+ parse_mode: str | None = None,
339
+ reply_markup: InlineKeyboardMarkup | None = None,
340
+ type: MediaType | None = None,
341
+ **other: typing.Any,
342
+ ) -> Result[Variative[MessageCute, bool], APIError]:
343
+ """Shortcut `API.edit_message_media()`, see the [documentation](https://core.telegram.org/bots/api#editmessagemedia)
344
+
345
+ Use this method to edit animation, audio, document, photo, or video messages,
346
+ or to add media to text messages. If a message is part of a message album, then
347
+ it can be edited only to an audio for audio albums, only to a document for document
348
+ albums and to a photo or a video otherwise. When an inline message is edited,
349
+ a new file can't be uploaded; use a previously uploaded file via its file_id
350
+ or specify a URL. On success, if the edited message is not an inline message,
351
+ the edited Message is returned, otherwise True is returned. Note that business
352
+ messages that were not sent by the bot and do not contain an inline keyboard
353
+ can only be edited within 48 hours from the time they were sent.
354
+ :param business_connection_id: Unique identifier of the business connection on behalf of which the messageto be edited was sent.
355
+
356
+ :param chat_id: Required if inline_message_id is not specified. Unique identifier forthe target chat or username of the target channel (in the format @channelusername).
357
+ :param message_id: Required if inline_message_id is not specified. Identifier of the messageto edit.
358
+
359
+ :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of theinline message.
360
+
361
+ :param media: A JSON-serialized object for a new media content of the message.
362
+
363
+ :param reply_markup: A JSON-serialized object for a new inline keyboard."""
364
+ return await MessageCute.edit_media(self, **get_params(locals())) # type: ignore
365
+
366
+ @shortcut(
367
+ "edit_message_reply_markup",
368
+ executor=execute_method_edit,
369
+ custom_params={"message_thread_id"},
370
+ )
371
+ async def edit_reply_markup(
372
+ self,
373
+ *,
374
+ business_connection_id: str | None = None,
375
+ chat_id: int | str | None = None,
376
+ inline_message_id: str | None = None,
377
+ message_id: int | None = None,
378
+ message_thread_id: int | None = None,
379
+ reply_markup: InlineKeyboardMarkup | None = None,
380
+ **other: typing.Any,
381
+ ) -> Result[Variative[MessageCute, bool], APIError]:
382
+ """Shortcut `API.edit_message_reply_markup()`, see the [documentation](https://core.telegram.org/bots/api#editmessagereplymarkup)
383
+
384
+ Use this method to edit only the reply markup of messages. On success, if
385
+ the edited message is not an inline message, the edited Message is returned,
386
+ otherwise True is returned. Note that business messages that were not sent
387
+ by the bot and do not contain an inline keyboard can only be edited within
388
+ 48 hours from the time they were sent.
389
+ :param business_connection_id: Unique identifier of the business connection on behalf of which the messageto be edited was sent.
390
+
391
+ :param chat_id: Required if inline_message_id is not specified. Unique identifier forthe target chat or username of the target channel (in the format @channelusername).
392
+ :param message_id: Required if inline_message_id is not specified. Identifier of the messageto edit.
393
+
394
+ :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of theinline message.
395
+
396
+ :param reply_markup: A JSON-serialized object for an inline keyboard."""
397
+ ...
398
+
399
+
400
+ __all__ = ("CallbackQueryCute",)