python-trueconf-bot 1.0.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.
Files changed (120) hide show
  1. python_trueconf_bot-1.0.0.dist-info/METADATA +115 -0
  2. python_trueconf_bot-1.0.0.dist-info/RECORD +120 -0
  3. python_trueconf_bot-1.0.0.dist-info/WHEEL +5 -0
  4. python_trueconf_bot-1.0.0.dist-info/licenses/LICENSE +32 -0
  5. python_trueconf_bot-1.0.0.dist-info/top_level.txt +1 -0
  6. trueconf/__init__.py +18 -0
  7. trueconf/_version.py +34 -0
  8. trueconf/client/__init__.py +0 -0
  9. trueconf/client/bot.py +1269 -0
  10. trueconf/client/context_controller.py +27 -0
  11. trueconf/client/session.py +60 -0
  12. trueconf/dispatcher/__init__.py +0 -0
  13. trueconf/dispatcher/dispatcher.py +56 -0
  14. trueconf/dispatcher/router.py +207 -0
  15. trueconf/enums/__init__.py +23 -0
  16. trueconf/enums/aouth_error.py +15 -0
  17. trueconf/enums/chat_participant_role.py +18 -0
  18. trueconf/enums/chat_type.py +17 -0
  19. trueconf/enums/envelope_author_type.py +13 -0
  20. trueconf/enums/file_ready_state.py +14 -0
  21. trueconf/enums/incoming_update_method.py +14 -0
  22. trueconf/enums/message_type.py +27 -0
  23. trueconf/enums/parse_mode.py +14 -0
  24. trueconf/enums/survey_type.py +6 -0
  25. trueconf/enums/update_type.py +14 -0
  26. trueconf/exceptions.py +17 -0
  27. trueconf/filters/__init__.py +11 -0
  28. trueconf/filters/base.py +8 -0
  29. trueconf/filters/command.py +32 -0
  30. trueconf/filters/instance_of.py +11 -0
  31. trueconf/filters/message.py +15 -0
  32. trueconf/filters/method.py +12 -0
  33. trueconf/loggers.py +4 -0
  34. trueconf/methods/__init__.py +59 -0
  35. trueconf/methods/add_participant_to_chat.py +22 -0
  36. trueconf/methods/auth.py +25 -0
  37. trueconf/methods/base.py +107 -0
  38. trueconf/methods/create_channel.py +20 -0
  39. trueconf/methods/create_group_chat.py +20 -0
  40. trueconf/methods/create_p2p_chat.py +20 -0
  41. trueconf/methods/edit_message.py +25 -0
  42. trueconf/methods/edit_survey.py +32 -0
  43. trueconf/methods/forward_message.py +22 -0
  44. trueconf/methods/get_chat_by_id.py +20 -0
  45. trueconf/methods/get_chat_history.py +24 -0
  46. trueconf/methods/get_chat_participants.py +24 -0
  47. trueconf/methods/get_chats.py +22 -0
  48. trueconf/methods/get_file_info.py +20 -0
  49. trueconf/methods/get_message_by_id.py +19 -0
  50. trueconf/methods/get_user_display_name.py +20 -0
  51. trueconf/methods/has_chat_participant.py +22 -0
  52. trueconf/methods/remove_chat.py +20 -0
  53. trueconf/methods/remove_message.py +23 -0
  54. trueconf/methods/remove_participant_from_chat.py +23 -0
  55. trueconf/methods/send_file.py +25 -0
  56. trueconf/methods/send_message.py +29 -0
  57. trueconf/methods/send_survey.py +40 -0
  58. trueconf/methods/subscribe_file_progress.py +21 -0
  59. trueconf/methods/unsubscribe_file_progress.py +21 -0
  60. trueconf/methods/upload_file.py +21 -0
  61. trueconf/py.typed +0 -0
  62. trueconf/types/__init__.py +25 -0
  63. trueconf/types/author_box.py +17 -0
  64. trueconf/types/chat_participant.py +11 -0
  65. trueconf/types/content/__init__.py +25 -0
  66. trueconf/types/content/attachment.py +14 -0
  67. trueconf/types/content/base.py +8 -0
  68. trueconf/types/content/chat_created.py +9 -0
  69. trueconf/types/content/document.py +71 -0
  70. trueconf/types/content/forward_message.py +21 -0
  71. trueconf/types/content/photo.py +70 -0
  72. trueconf/types/content/remove_participant.py +9 -0
  73. trueconf/types/content/sticker.py +70 -0
  74. trueconf/types/content/survey.py +19 -0
  75. trueconf/types/content/text.py +9 -0
  76. trueconf/types/content/video.py +71 -0
  77. trueconf/types/last_message.py +33 -0
  78. trueconf/types/message.py +411 -0
  79. trueconf/types/parser.py +90 -0
  80. trueconf/types/requests/__init__.py +21 -0
  81. trueconf/types/requests/added_chat_participant.py +40 -0
  82. trueconf/types/requests/created_channel.py +42 -0
  83. trueconf/types/requests/created_group_chat.py +42 -0
  84. trueconf/types/requests/created_personal_chat.py +42 -0
  85. trueconf/types/requests/edited_message.py +37 -0
  86. trueconf/types/requests/removed_chat.py +32 -0
  87. trueconf/types/requests/removed_chat_participant.py +39 -0
  88. trueconf/types/requests/removed_message.py +37 -0
  89. trueconf/types/requests/uploading_progress.py +34 -0
  90. trueconf/types/responses/__init__.py +57 -0
  91. trueconf/types/responses/add_chat_participant_response.py +8 -0
  92. trueconf/types/responses/api_error.py +38 -0
  93. trueconf/types/responses/auth_response_payload.py +9 -0
  94. trueconf/types/responses/create_channel_response.py +8 -0
  95. trueconf/types/responses/create_group_chat_response.py +8 -0
  96. trueconf/types/responses/create_p2p_chat_response.py +8 -0
  97. trueconf/types/responses/edit_message_response.py +9 -0
  98. trueconf/types/responses/edit_survey_response.py +9 -0
  99. trueconf/types/responses/forward_message_response.py +10 -0
  100. trueconf/types/responses/get_chat_by_id_response.py +13 -0
  101. trueconf/types/responses/get_chat_history_response.py +13 -0
  102. trueconf/types/responses/get_chat_participants_response.py +12 -0
  103. trueconf/types/responses/get_chats_response.py +12 -0
  104. trueconf/types/responses/get_file_info_response.py +24 -0
  105. trueconf/types/responses/get_message_by_id_response.py +26 -0
  106. trueconf/types/responses/get_user_display_name_response.py +8 -0
  107. trueconf/types/responses/has_chat_participant_response.py +8 -0
  108. trueconf/types/responses/remove_chat_participant_response.py +8 -0
  109. trueconf/types/responses/remove_chat_response.py +8 -0
  110. trueconf/types/responses/remove_message_response.py +8 -0
  111. trueconf/types/responses/send_file_response.py +10 -0
  112. trueconf/types/responses/send_message_response.py +10 -0
  113. trueconf/types/responses/send_survey_response.py +10 -0
  114. trueconf/types/responses/subscribe_file_progress_response.py +8 -0
  115. trueconf/types/responses/unsubscribe_file_progress_response.py +8 -0
  116. trueconf/types/responses/upload_file_response.py +8 -0
  117. trueconf/types/update.py +12 -0
  118. trueconf/utils/__init__.py +3 -0
  119. trueconf/utils/generate_secret_for_survey.py +10 -0
  120. trueconf/utils/token.py +78 -0
@@ -0,0 +1,411 @@
1
+ from __future__ import annotations
2
+ from dataclasses import dataclass, field
3
+ from typing import Optional, Union
4
+ from mashumaro import DataClassDictMixin
5
+ from trueconf.enums.message_type import MessageType
6
+ from trueconf.types.author_box import EnvelopeAuthor, EnvelopeBox
7
+ from trueconf.types.content.text import TextContent
8
+ from trueconf.types.content.attachment import AttachmentContent
9
+ from trueconf.types.content.survey import SurveyContent
10
+ from trueconf.types.content.remove_participant import RemoveParticipant
11
+ from trueconf.types.content.forward_message import ForwardMessage
12
+ from trueconf.types.content.chat_created import ParticipantRoleContent
13
+ from trueconf.types.content.photo import Photo
14
+ from trueconf.types.content.video import Video
15
+ from trueconf.types.content.sticker import Sticker
16
+ from trueconf.types.content.document import Document
17
+ from trueconf.client.context_controller import BoundToBot
18
+ from trueconf.enums.parse_mode import ParseMode
19
+
20
+ import logging
21
+
22
+ logger = logging.getLogger("chat_bot")
23
+
24
+
25
+ @dataclass
26
+ class Message(BoundToBot, DataClassDictMixin):
27
+ """
28
+ Represents a single chat message within TrueConf Chatbot Connector.
29
+
30
+ The `Message` object is automatically created for each incoming update and
31
+ contains metadata (author, chat, timestamp, type) along with the actual
32
+ message content. It also provides helper properties and shortcut methods
33
+ to interact with the message (e.g., replying, forwarding, deleting, sending
34
+ media files).
35
+
36
+ Source:
37
+ https://trueconf.com/docs/chatbot-connector/en/server-requests/#sendMessage
38
+
39
+ Attributes:
40
+ timestamp (int): Unix timestamp of the message.
41
+ type (MessageType): Type of the message (e.g., TEXT, ATTACHMENT).
42
+ author (EnvelopeAuthor): Information about the user who sent the message.
43
+ box (EnvelopeBox): Information about the chat (box) where the message was sent.
44
+ content (Union[TextContent, AttachmentContent, SurveyContent,
45
+ ParticipantRoleContent, RemoveParticipant, ForwardMessage]):
46
+ The actual message content, which can be text, media, or service data.
47
+ message_id (str): Unique identifier of the message.
48
+ chat_id (str): Unique identifier of the chat where the message was sent.
49
+ is_edited (bool): Indicates whether the message was edited.
50
+ reply_message_id (Optional[str]): Identifier of the message this one replies to.
51
+
52
+ from_user (EnvelopeAuthor): Shortcut for accessing the message author.
53
+ content_type (MessageType): Returns the type of the message.
54
+ text (Optional[str]): Returns the message text if it contains text, else None.
55
+ document (Optional[Document]): Returns a document attachment if the message
56
+ contains a non-media file (not photo, video, sticker).
57
+ photo (Optional[Photo]): Returns a photo attachment if available.
58
+ video (Optional[Video]): Returns a video attachment if available.
59
+ sticker (Optional[Sticker]): Returns a sticker attachment if available.
60
+
61
+ Methods:
62
+ answer(text, parse_mode): Sends a text message in the same chat.
63
+ reply(text, parse_mode): Sends a reply message referencing the current one.
64
+ forward(chat_id): Forwards the current message to another chat.
65
+ copy_to(chat_id): Sends a copy of the current message (text-only).
66
+ answer_photo(file_path): Sends a photo to the current chat.
67
+ answer_document(file_path): Sends a document to the current chat.
68
+ answer_sticker(file_path): Sends a sticker to the current chat.
69
+ delete(for_all): Deletes the current message from the chat.
70
+ """
71
+
72
+ timestamp: int
73
+ type: MessageType
74
+ author: EnvelopeAuthor
75
+ box: EnvelopeBox
76
+ content: Union[
77
+ TextContent, AttachmentContent, SurveyContent, ParticipantRoleContent, RemoveParticipant, ForwardMessage]
78
+ message_id: str = field(metadata={"alias": "messageId"})
79
+ chat_id: str = field(metadata={"alias": "chatId"})
80
+ is_edited: bool = field(metadata={"alias": "isEdited"})
81
+ reply_message_id: Optional[str] = field(default=None, metadata={"alias": "replyMessageId"})
82
+
83
+ @property
84
+ def from_user(self) -> EnvelopeAuthor:
85
+ """
86
+ Returns the author of the current message.
87
+
88
+ Returns:
89
+ EnvelopeAuthor: Shortcut for accessing the message author.
90
+ """
91
+ return self.author
92
+
93
+ @property
94
+ def content_type(self) -> MessageType:
95
+ """
96
+ Returns the type of the current message content.
97
+
98
+ Returns:
99
+ MessageType: Message content type (e.g., TEXT, ATTACHMENT).
100
+ """
101
+ return self.type
102
+
103
+ @property
104
+ def text(self) -> str | None:
105
+ """
106
+ Returns the text of the current message if present.
107
+
108
+ Returns:
109
+ Optional[str]: Message text, or None if the message has no text content.
110
+ """
111
+ return self.content.text if isinstance(self.content, TextContent) else None
112
+
113
+ @property
114
+ def document(self) -> Optional["Document"]:
115
+ """
116
+ Returns the attached document if the message contains a non-media file.
117
+
118
+ Use this property only for documents that are **not** photos, videos, or stickers.
119
+ For media attachments, use the corresponding properties: `photo`, `video`, or `sticker`.
120
+ If you need to handle **any** attached file (including media), use `message.content` directly.
121
+
122
+ Returns:
123
+ Optional[Document]: Document attachment bound to the bot, or None if not applicable.
124
+ """
125
+
126
+ if isinstance(self.content, AttachmentContent) and not self.content.mimetype.startswith(
127
+ ("image/", "video/", "audio/")):
128
+ return Document(
129
+ file_id=self.content.file_id,
130
+ file_name=self.content.file_name,
131
+ file_size=self.content.file_size,
132
+ mimetype=self.content.mimetype,
133
+ ).bind(self.bot)
134
+
135
+ return None
136
+
137
+ @property
138
+ def photo(self) -> Optional["Photo"]:
139
+ """
140
+ Returns the attached photo object if the current message contains an image.
141
+
142
+ This is a shortcut for accessing photo metadata from image attachments.
143
+
144
+ Returns:
145
+ Optional[Photo]: A `Photo` object bound to the bot, or None if the message does not contain an image.
146
+ """
147
+
148
+ if isinstance(self.content, AttachmentContent) and self.content.mimetype.startswith("image/"):
149
+ return Photo(
150
+ file_id=self.content.file_id,
151
+ file_name=self.content.file_name,
152
+ file_size=self.content.file_size,
153
+ mimetype=self.content.mimetype,
154
+ ).bind(self.bot)
155
+ return None
156
+
157
+ @property
158
+ def video(self) -> Optional["Video"]:
159
+ """
160
+ Returns the attached video object if the current message contains a video.
161
+
162
+ This is a shortcut for accessing video metadata from video attachments.
163
+
164
+ Returns:
165
+ Optional[Video]: A `Video` object bound to the bot, or None if the message does not contain a video.
166
+ """
167
+
168
+ if isinstance(self.content, AttachmentContent) and self.content.mimetype.startswith("video/"):
169
+ return Video(
170
+ file_id=self.content.file_id,
171
+ file_name=self.content.file_name,
172
+ file_size=self.content.file_size,
173
+ mimetype=self.content.mimetype,
174
+ ).bind(self.bot)
175
+ return None
176
+
177
+ @property
178
+ def sticker(self) -> Optional["Sticker"]:
179
+ """
180
+ Returns the attached sticker object if the current message contains a sticker.
181
+
182
+ Returns:
183
+ Optional[Sticker]: A `Sticker` object bound to the bot, or None if the message does not contain a sticker.
184
+ """
185
+
186
+ if isinstance(self.content, AttachmentContent) and self.content.mimetype.startswith("sticker/"):
187
+ return Sticker(
188
+ file_id=self.content.file_id,
189
+ file_name=self.content.file_name,
190
+ file_size=self.content.file_size,
191
+ mimetype=self.content.mimetype,
192
+ ).bind(self.bot)
193
+ return None
194
+
195
+ async def answer_photo(self, file_path: str, preview_path: str | None) -> object:
196
+ """
197
+ Shortcut for the [`send_photo`][trueconf.Bot.send_photo] method of the bot instance. Use this method to send a photo in response to the current message.
198
+
199
+ Automatically fills the following attributes:
200
+ - `chat_id`
201
+
202
+ Source:
203
+ https://trueconf.com/docs/chatbot-connector/en/files/#sending-an-image
204
+
205
+ Args:
206
+ file_path: Path to the image file (supported formats: `.jpg`, `.jpeg`, `.png`, `.webp`, `.bmp`, `.gif`, `.tiff`).
207
+ preview_path: Path to the preview image.
208
+
209
+ Returns:
210
+ SendFileResponse: Object containing the result of the photo upload.
211
+
212
+ Examples:
213
+ >>> @<router>.message()
214
+ >>> async def on_message(message:Message):
215
+ >>> await message.answer_photo(file_path='/path/to/file.jpg', preview_path='/path/to/preview.jpg')
216
+ """
217
+
218
+ return await self.bot.send_photo(
219
+ chat_id=self.chat_id,
220
+ file_path=file_path,
221
+ preview_path=preview_path,
222
+ )
223
+
224
+ async def answer_document(self, file_path: str) -> object:
225
+ """
226
+ Shortcut for the [`send_document`][trueconf.Bot.send_document] method of the bot instance. Use this method to send a document in response to the current message.
227
+
228
+ Automatically fills the following attributes:
229
+ - `chat_id`
230
+
231
+ Source:
232
+ https://trueconf.com/docs/chatbot-connector/en/files/#working-with-files
233
+
234
+ Args:
235
+ file_path (str): Path to the document file.
236
+
237
+ Returns:
238
+ SendFileResponse: Object containing the result of the document upload.
239
+
240
+ Examples:
241
+ >>> @<router>.message()
242
+ >>> async def on_message(message:Message):
243
+ >>> await message.answer_sticker(file_path='/path/to/file.webp')
244
+ """
245
+
246
+ return await self.bot.send_document(
247
+ chat_id=self.chat_id,
248
+ file_path=file_path,
249
+ )
250
+
251
+ async def answer_sticker(self, file_path: str) -> object:
252
+ """
253
+ Shortcut for the [`send_sticker`][trueconf.Bot.send_sticker] method of the bot instance. Use this method to send a sticker in response to the current message.
254
+
255
+ Automatically fills the following attributes:
256
+ - `chat_id`
257
+
258
+ Source:
259
+ https://trueconf.com/docs/chatbot-connector/en/files/#upload-file-to-server-storage
260
+
261
+ Args:
262
+ file_path (str): Path to the sticker file (must be in WebP format).
263
+
264
+ Returns:
265
+ SendFileResponse: Object containing the result of the sticker delivery.
266
+
267
+ Examples:
268
+ >>> @<router>.message()
269
+ >>> async def on_message(message:Message):
270
+ >>> await message.answer_sticker(file_path='/path/to/file.webp')
271
+ """
272
+
273
+ return await self.bot.send_sticker(
274
+ chat_id=self.chat_id,
275
+ file_path=file_path,
276
+ )
277
+
278
+ async def answer(self, text: str, parse_mode: ParseMode | str = ParseMode.HTML) -> object:
279
+ """
280
+ Shortcut for the [`send_message`][trueconf.Bot.send_message] method of the bot instance. Use this method to send a text message to the current chat.
281
+
282
+ Automatically fills the following attributes:
283
+ - `chat_id`
284
+
285
+ Source:
286
+ https://trueconf.com/docs/chatbot-connector/en/messages/#sendMessage
287
+
288
+ Args:
289
+ text (str): Text of the message to be sent.
290
+ parse_mode (ParseMode | str, optional): Text formatting mode. Defaults to HTML.
291
+
292
+ Returns:
293
+ SendMessageResponse: Object containing the result of the message delivery.
294
+
295
+ Examples:
296
+ >>> @<router>.message()
297
+ >>> async def on_message(message:Message):
298
+ >>> await message.answer("Hi, there!")
299
+
300
+ >>> @<router>.message()
301
+ >>> async def on_message(message:Message):
302
+ >>> await message.answer("Hi, **there!**", parse_mode=ParseMode.MARKDOWN)
303
+ """
304
+
305
+ return await self.bot.send_message(
306
+ chat_id=self.chat_id,
307
+ text=text,
308
+ parse_mode=parse_mode
309
+ )
310
+
311
+ async def reply(self, text: str, parse_mode: ParseMode | str = ParseMode.HTML) -> object:
312
+ """
313
+ Shortcut for the [`reply_message`][trueconf.Bot.reply_message] method of the bot instance. Use this method to send a reply message to the current chat.
314
+
315
+ Automatically fills the following attributes:
316
+ - `chat_id`
317
+ - `reply_message_id`
318
+
319
+ Source: https://trueconf.com/docs/chatbot-connector/en/messages/#replyMessage
320
+
321
+ Args:
322
+ text (str): Text of the reply message.
323
+ parse_mode (ParseMode | str, optional): Text formatting mode. Defaults to HTML.
324
+
325
+ Returns:
326
+ SendMessageResponse: Object containing the result of the message delivery.
327
+ """
328
+
329
+ return await self.bot.reply_message(
330
+ chat_id=self.chat_id,
331
+ message_id=self.message_id,
332
+ text=text,
333
+ parse_mode=parse_mode,
334
+ )
335
+
336
+ async def forward(self, chat_id: str) -> object:
337
+ """
338
+ Shortcut for the [`forward_message`][trueconf.Bot.forward_message] method of the bot instance. Use this method to forward the current message to another chat.
339
+
340
+ Automatically fills the following attributes:
341
+ - `message_id`
342
+
343
+ Source:
344
+ https://trueconf.com/docs/chatbot-connector/en/messages/#forwardMessage
345
+
346
+ Args:
347
+ chat_id (str): Identifier of the target chat to forward the message to.
348
+
349
+ Returns:
350
+ ForwardMessageResponse: Object containing the result of the message forwarding.
351
+ """
352
+
353
+ return await self.bot.forward_message(
354
+ chat_id=chat_id,
355
+ message_id=self.message_id,
356
+ )
357
+
358
+ async def copy_to(self, chat_id: str) -> object:
359
+ """
360
+ Shortcut for the [`send_message`][trueconf.Bot.send_message] method of the bot instance. Use this method to send a copy of the current message (without metadata or reply context) to another chat.
361
+
362
+ Automatically fills the following attributes:
363
+ - `text`
364
+ - `parse_mode`
365
+
366
+ Source:
367
+ https://trueconf.com/docs/chatbot-connector/en/messages/#sendMessage
368
+
369
+ Args:
370
+ chat_id (str): Identifier of the target chat to send the copied message to.
371
+
372
+ Returns:
373
+ SendMessageResponse: Object containing the result of the message delivery.
374
+ """
375
+
376
+ if isinstance(self.content, TextContent):
377
+ return await self.bot.send_message(
378
+ chat_id=chat_id,
379
+ text=self.content.text,
380
+ parse_mode=self.content.parse_mode
381
+ )
382
+
383
+ logger.warning(
384
+ "copy_to(): unsupported content type for non-text message "
385
+ "(type=%s). Nothing was sent. Use forward() if needed.",
386
+ getattr(self.type, "name", self.type),
387
+ )
388
+ return None
389
+
390
+ async def delete(self, for_all: bool = False) -> object:
391
+ """
392
+ Shortcut for the [`remove_message`][trueconf.Bot.remove_message] method of the bot instance. Use this method to delete the current message from the chat.
393
+
394
+ Automatically fills the following attributes:
395
+ - `message_id`
396
+
397
+ Source:
398
+ https://trueconf.com/docs/chatbot-connector/en/messages/#removeMessage
399
+
400
+ Args:
401
+ for_all (bool, optional): If True, delete the message for all participants.
402
+ Defaults to False (deletes only for the bot).
403
+
404
+ Returns:
405
+ RemoveMessageResponse: Object containing the result of the message deletion.
406
+ """
407
+
408
+ return await self.bot.remove_message(
409
+ message_id=self.message_id,
410
+ for_all=for_all,
411
+ )
@@ -0,0 +1,90 @@
1
+ from __future__ import annotations
2
+ from typing import TypeVar
3
+ from trueconf.enums.incoming_update_method import IncomingUpdateMethod as IUM
4
+ from trueconf.enums.message_type import MessageType
5
+ from trueconf.enums.update_type import UpdateType
6
+ from trueconf.types.author_box import EnvelopeAuthor, EnvelopeBox
7
+ from trueconf.types.content.attachment import AttachmentContent
8
+ from trueconf.types.content.survey import SurveyContent
9
+ from trueconf.types.content.text import TextContent
10
+ from trueconf.types.message import Message
11
+ from trueconf.types.requests.added_chat_participant import AddedChatParticipant
12
+ from trueconf.types.requests.created_channel import CreatedChannel
13
+ from trueconf.types.requests.created_group_chat import CreatedGroupChat
14
+ from trueconf.types.requests.created_personal_chat import CreatedPersonalChat
15
+ from trueconf.types.requests.edited_message import EditedMessage
16
+ from trueconf.types.requests.removed_chat import RemovedChat
17
+ from trueconf.types.requests.removed_chat_participant import RemovedChatParticipant
18
+ from trueconf.types.requests.removed_message import RemovedMessage
19
+ from trueconf.types.requests.uploading_progress import UploadingProgress
20
+ from trueconf.types.update import Update
21
+
22
+ T = TypeVar("T")
23
+
24
+
25
+ def _content_factory(env_type: MessageType, raw: dict):
26
+ if env_type == MessageType.PLAIN_MESSAGE:
27
+ return TextContent.from_dict(raw)
28
+ if env_type == MessageType.ATTACHMENT:
29
+ return AttachmentContent.from_dict(raw)
30
+ if env_type == MessageType.SURVEY:
31
+ return SurveyContent.from_dict(raw)
32
+ return None
33
+
34
+
35
+ def parse_update(raw: dict):
36
+ if raw.get("type") == UpdateType.RESPONSE:
37
+ return None
38
+
39
+ p = raw.get("payload")
40
+ if not isinstance(p, dict):
41
+ return None
42
+
43
+ match raw["method"]:
44
+ case IUM.UPLOADING_PROGRESS:
45
+ return UploadingProgress.from_dict(raw["payload"])
46
+
47
+ case IUM.REMOVED_CHAT_PARTICIPANT:
48
+ return RemovedChatParticipant.from_dict(raw["payload"])
49
+
50
+ case IUM.REMOVED_MESSAGE:
51
+ return RemovedMessage.from_dict(raw["payload"])
52
+
53
+ case IUM.REMOVED_CHAT:
54
+ return RemovedChat.from_dict(raw["payload"])
55
+
56
+ case IUM.EDITED_MESSAGE:
57
+ return EditedMessage.from_dict(raw["payload"])
58
+
59
+ case IUM.ADDED_CHAT_PARTICIPANT:
60
+ return AddedChatParticipant.from_dict(raw["payload"])
61
+
62
+ case IUM.CREATED_PERSONAL_CHAT:
63
+ return CreatedPersonalChat.from_dict(raw["payload"])
64
+
65
+ case IUM.CREATED_GROUP_CHAT:
66
+ return CreatedGroupChat.from_dict(raw["payload"])
67
+
68
+ case IUM.CREATED_CHANNEL:
69
+ return CreatedChannel.from_dict(raw["payload"])
70
+
71
+ case IUM.MESSAGE:
72
+ env_type = MessageType(p.get("type", 0))
73
+ content = _content_factory(env_type, p.get("content", {}))
74
+ if content is None:
75
+ return None
76
+ p["content"] = content
77
+ return Message(
78
+ message_id=p["messageId"],
79
+ chat_id=p["chatId"],
80
+ timestamp=p["timestamp"],
81
+ reply_message_id=p.get("replyMessageId"),
82
+ is_edited=p["isEdited"],
83
+ type=env_type,
84
+ author=EnvelopeAuthor.from_dict(p["author"]),
85
+ box=EnvelopeBox.from_dict(p["box"]),
86
+ content=content,
87
+ )
88
+
89
+ case _:
90
+ return Update(raw["method"], raw["type"], raw["id"], raw["payload"])
@@ -0,0 +1,21 @@
1
+ from .added_chat_participant import AddedChatParticipant
2
+ from .created_channel import CreatedChannel
3
+ from .created_group_chat import CreatedGroupChat
4
+ from .created_personal_chat import CreatedPersonalChat
5
+ from .edited_message import EditedMessage
6
+ from .removed_chat import RemovedChat
7
+ from .removed_chat_participant import RemovedChatParticipant
8
+ from .removed_message import RemovedMessage
9
+ from .uploading_progress import UploadingProgress
10
+
11
+ __all__ = [
12
+ 'AddedChatParticipant',
13
+ 'CreatedChannel',
14
+ 'CreatedGroupChat',
15
+ 'CreatedPersonalChat',
16
+ 'EditedMessage',
17
+ 'RemovedChat',
18
+ 'RemovedChatParticipant',
19
+ 'RemovedMessage',
20
+ 'UploadingProgress',
21
+ ]
@@ -0,0 +1,40 @@
1
+ from __future__ import annotations
2
+ from dataclasses import dataclass, field
3
+ from mashumaro import DataClassDictMixin
4
+ from trueconf.client.context_controller import BoundToBot
5
+ from trueconf.types.author_box import EnvelopeAuthor
6
+
7
+
8
+ @dataclass
9
+ class AddedChatParticipant(BoundToBot, DataClassDictMixin):
10
+ """
11
+ **Event type:** a new participant was added to a chat.
12
+
13
+ This object is received in the handler when a user is added to a personal chat, group chat, channel, or conference chat.
14
+
15
+ Notes:
16
+ This class is used as the event type in handler functions decorated with `@<router>.added_chat_participant()`.
17
+
18
+ Source:
19
+ https://trueconf.com/docs/chatbot-connector/en/server-requests/#addChatParticipant
20
+
21
+ Attributes:
22
+ timestamp (int): Unix timestamp (milliseconds) of when the event occurred.
23
+ chat_id (str): Unique identifier of the chat where the participant was added.
24
+ user_id (str): TrueConf ID of the participant who was added.
25
+ added_by (EnvelopeAuthor): Information about the user who added the participant.
26
+
27
+ Examples:
28
+ ```python
29
+ from trueconf.types import AddedChatParticipant
30
+
31
+ @<router>.added_chat_participant()
32
+ async def on_added(event: AddedChatParticipant):
33
+ print(event.user_id)
34
+ ```
35
+ """
36
+
37
+ timestamp: int
38
+ chat_id: str = field(metadata={"alias": "chatId"})
39
+ user_id: str = field(metadata={"alias": "userId"})
40
+ added_by: EnvelopeAuthor = field(metadata={"alias": "addedBy"})
@@ -0,0 +1,42 @@
1
+ from __future__ import annotations
2
+ from dataclasses import dataclass, field
3
+ from mashumaro import DataClassDictMixin
4
+ from trueconf.client.context_controller import BoundToBot
5
+ from trueconf.enums.chat_type import ChatType
6
+ from trueconf.types.last_message import LastMessage
7
+
8
+
9
+ @dataclass
10
+ class CreatedChannel(BoundToBot, DataClassDictMixin):
11
+ """
12
+ **Event type:** a new channel chat was created.
13
+
14
+ This object is received in the handler when a channel is created in TrueConf.
15
+
16
+ Notes:
17
+ This class is used as the event type in handler functions decorated with `@<router>.created_channel()`.
18
+
19
+ Source:
20
+ https://trueconf.com/docs/chatbot-connector/en/server-requests/#createChannel
21
+
22
+ Attributes:
23
+ chat_id (str): Unique identifier of the created channel.
24
+ title (str): Title of the channel.
25
+ chat_type (ChatType): Type of the chat (should be `channel`).
26
+ last_message (LastMessage | None): The last message in the channel, if available.
27
+ unread_messages (int): Number of unread messages in the channel.
28
+
29
+ Examples:
30
+ ```python
31
+ from trueconf.types import CreatedChannel
32
+
33
+ @<router>.created_channel()
34
+ async def on_created(event: CreatedChannel):
35
+ print(f"Channel {event.title} created with id {event.chat_id}")
36
+ ```
37
+ """
38
+ chat_id: str = field(metadata={"alias": "chatId"})
39
+ title: str
40
+ chat_type: ChatType = field(metadata={"alias": "chatType"})
41
+ last_message: LastMessage | None = field(metadata={"alias": "lastMessage"})
42
+ unread_messages: int = field(metadata={"alias": "unreadMessages"})
@@ -0,0 +1,42 @@
1
+ from __future__ import annotations
2
+ from dataclasses import dataclass, field
3
+ from mashumaro import DataClassDictMixin
4
+ from trueconf.client.context_controller import BoundToBot
5
+ from trueconf.enums.chat_type import ChatType
6
+ from trueconf.types.last_message import LastMessage
7
+
8
+
9
+ @dataclass
10
+ class CreatedGroupChat(BoundToBot, DataClassDictMixin):
11
+ """
12
+ **Event type:** a new group chat was created.
13
+
14
+ This object is received in the handler when a group chat is created in TrueConf.
15
+
16
+ Notes:
17
+ This class is used as the event type in handler functions decorated with `@<router>.created_group_chat()`.
18
+
19
+ Source:
20
+ https://trueconf.com/docs/chatbot-connector/en/server-requests/#createGroupChat
21
+
22
+ Attributes:
23
+ chat_id (str): Unique identifier of the group chat.
24
+ title (str): Title of the group chat.
25
+ chat_type (ChatType): Type of the chat (should be `group`).
26
+ last_message (LastMessage | None): The last message in the chat, if available.
27
+ unread_messages (int): Number of unread messages in the group chat.
28
+
29
+ Examples:
30
+ ```python
31
+ from trueconf.types import CreatedGroupChat
32
+
33
+ @<router>.created_group_chat()
34
+ async def on_created(event: CreatedGroupChat):
35
+ print(f"Group chat {event.title} created with id {event.chat_id}")
36
+ ```
37
+ """
38
+ chat_id: str = field(metadata={"alias": "chatId"})
39
+ title: str
40
+ chat_type: ChatType = field(metadata={"alias": "chatType"})
41
+ last_message: LastMessage | None = field(metadata={"alias": "lastMessage"})
42
+ unread_messages: int = field(metadata={"alias": "unreadMessages"})