maxapi-python 1.2.5__py3-none-any.whl → 2.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 (169) hide show
  1. maxapi_python-2.0.0.dist-info/METADATA +217 -0
  2. maxapi_python-2.0.0.dist-info/RECORD +140 -0
  3. {maxapi_python-1.2.5.dist-info → maxapi_python-2.0.0.dist-info}/WHEEL +1 -1
  4. pymax/__init__.py +50 -105
  5. pymax/api/__init__.py +17 -0
  6. pymax/api/auth/__init__.py +1 -0
  7. pymax/api/auth/enums.py +17 -0
  8. pymax/api/auth/payloads.py +129 -0
  9. pymax/api/auth/service.py +313 -0
  10. pymax/api/auth/types.py +13 -0
  11. pymax/api/chats/__init__.py +8 -0
  12. pymax/api/chats/enums.py +27 -0
  13. pymax/api/chats/payloads.py +103 -0
  14. pymax/api/chats/service.py +277 -0
  15. pymax/api/facade.py +32 -0
  16. pymax/api/messages/__init__.py +1 -0
  17. pymax/api/messages/enums.py +17 -0
  18. pymax/api/messages/payloads.py +92 -0
  19. pymax/api/messages/service.py +337 -0
  20. pymax/api/models.py +13 -0
  21. pymax/api/response.py +123 -0
  22. pymax/api/self/__init__.py +2 -0
  23. pymax/api/self/enums.py +11 -0
  24. pymax/api/self/payloads.py +41 -0
  25. pymax/api/self/service.py +142 -0
  26. pymax/api/session/__init__.py +1 -0
  27. pymax/api/session/enums.py +10 -0
  28. pymax/api/session/payloads.py +76 -0
  29. pymax/api/session/service.py +72 -0
  30. pymax/api/uploads/__init__.py +1 -0
  31. pymax/api/uploads/models.py +49 -0
  32. pymax/api/uploads/payloads.py +25 -0
  33. pymax/api/uploads/service.py +458 -0
  34. pymax/api/users/__init__.py +2 -0
  35. pymax/api/users/enums.py +12 -0
  36. pymax/api/users/payloads.py +16 -0
  37. pymax/api/users/service.py +124 -0
  38. pymax/app.py +273 -0
  39. pymax/auth/__init__.py +25 -0
  40. pymax/auth/base.py +37 -0
  41. pymax/auth/email.py +0 -0
  42. pymax/auth/models.py +5 -0
  43. pymax/auth/providers.py +127 -0
  44. pymax/auth/qr.py +135 -0
  45. pymax/auth/service.py +25 -0
  46. pymax/auth/sms.py +122 -0
  47. pymax/base.py +204 -0
  48. pymax/client.py +106 -0
  49. pymax/client_web.py +83 -0
  50. pymax/config.py +215 -0
  51. pymax/connection/__init__.py +1 -0
  52. pymax/connection/connection.py +205 -0
  53. pymax/connection/pending.py +46 -0
  54. pymax/connection/readers/__init__.py +2 -0
  55. pymax/connection/readers/base.py +6 -0
  56. pymax/connection/readers/tcp.py +29 -0
  57. pymax/connection/readers/ws.py +14 -0
  58. pymax/dispatch/__init__.py +10 -0
  59. pymax/dispatch/dispatcher.py +222 -0
  60. pymax/dispatch/enums.py +12 -0
  61. pymax/dispatch/mapping.py +73 -0
  62. pymax/dispatch/resolvers.py +52 -0
  63. pymax/dispatch/router.py +216 -0
  64. pymax/exceptions.py +22 -89
  65. pymax/files/__init__.py +9 -0
  66. pymax/files/base.py +82 -0
  67. pymax/files/file.py +76 -0
  68. pymax/files/photo.py +108 -0
  69. pymax/files/static.py +10 -0
  70. pymax/files/video.py +74 -0
  71. pymax/formatting/__init__.py +0 -0
  72. pymax/formatting/markdown.py +217 -0
  73. pymax/infra/__init__.py +1 -0
  74. pymax/infra/auth.py +55 -0
  75. pymax/infra/base.py +15 -0
  76. pymax/infra/chat.py +240 -0
  77. pymax/infra/message.py +252 -0
  78. pymax/infra/protocol.py +9 -0
  79. pymax/infra/self.py +139 -0
  80. pymax/infra/user.py +107 -0
  81. pymax/logging.py +129 -0
  82. pymax/protocol/__init__.py +11 -0
  83. pymax/protocol/base.py +13 -0
  84. pymax/protocol/enums.py +180 -0
  85. pymax/protocol/models.py +33 -0
  86. pymax/protocol/tcp/__init__.py +1 -0
  87. pymax/protocol/tcp/compression.py +97 -0
  88. pymax/protocol/tcp/framing.py +68 -0
  89. pymax/protocol/tcp/payload.py +127 -0
  90. pymax/protocol/tcp/protocol.py +68 -0
  91. pymax/protocol/ws/__init__.py +1 -0
  92. pymax/protocol/ws/protocol.py +27 -0
  93. pymax/py.typed +0 -0
  94. pymax/routers.py +8 -0
  95. pymax/session/__init__.py +3 -0
  96. pymax/session/models.py +11 -0
  97. pymax/session/protocol.py +14 -0
  98. pymax/session/store.py +232 -0
  99. pymax/telemetry/__init__.py +3 -0
  100. pymax/telemetry/navigation.py +181 -0
  101. pymax/telemetry/payloads.py +142 -0
  102. pymax/telemetry/service.py +225 -0
  103. pymax/transport/__init__.py +0 -0
  104. pymax/transport/base.py +14 -0
  105. pymax/transport/tcp.py +93 -0
  106. pymax/transport/websocket.py +50 -0
  107. pymax/types/__init__.py +2 -0
  108. pymax/types/domain/__init__.py +11 -0
  109. pymax/types/domain/attachments/__init__.py +11 -0
  110. pymax/types/domain/attachments/audio.py +35 -0
  111. pymax/types/domain/attachments/call.py +26 -0
  112. pymax/types/domain/attachments/contact.py +32 -0
  113. pymax/types/domain/attachments/control.py +20 -0
  114. pymax/types/domain/attachments/enums.py +27 -0
  115. pymax/types/domain/attachments/file.py +56 -0
  116. pymax/types/domain/attachments/keyboards/__init__.py +1 -0
  117. pymax/types/domain/attachments/keyboards/inline.py +19 -0
  118. pymax/types/domain/attachments/photo.py +45 -0
  119. pymax/types/domain/attachments/share.py +29 -0
  120. pymax/types/domain/attachments/sticker.py +50 -0
  121. pymax/types/domain/attachments/video.py +90 -0
  122. pymax/types/domain/auth.py +161 -0
  123. pymax/types/domain/base.py +17 -0
  124. pymax/types/domain/chat.py +426 -0
  125. pymax/types/domain/element.py +24 -0
  126. pymax/types/domain/enums.py +24 -0
  127. pymax/types/domain/error.py +20 -0
  128. pymax/types/domain/folder.py +74 -0
  129. pymax/types/domain/login.py +35 -0
  130. pymax/types/domain/message.py +378 -0
  131. pymax/types/domain/name.py +20 -0
  132. pymax/types/domain/profile.py +15 -0
  133. pymax/types/domain/session.py +52 -0
  134. pymax/types/domain/sync.py +80 -0
  135. pymax/types/domain/user.py +117 -0
  136. pymax/types/events/__init__.py +3 -0
  137. pymax/types/events/file.py +5 -0
  138. pymax/types/events/message.py +37 -0
  139. pymax/types/events/video.py +5 -0
  140. maxapi_python-1.2.5.dist-info/METADATA +0 -202
  141. maxapi_python-1.2.5.dist-info/RECORD +0 -33
  142. pymax/core.py +0 -398
  143. pymax/crud.py +0 -96
  144. pymax/files.py +0 -138
  145. pymax/filters.py +0 -164
  146. pymax/formatter.py +0 -31
  147. pymax/formatting.py +0 -74
  148. pymax/interfaces.py +0 -558
  149. pymax/mixins/__init__.py +0 -40
  150. pymax/mixins/auth.py +0 -594
  151. pymax/mixins/channel.py +0 -130
  152. pymax/mixins/group.py +0 -458
  153. pymax/mixins/handler.py +0 -285
  154. pymax/mixins/message.py +0 -879
  155. pymax/mixins/scheduler.py +0 -28
  156. pymax/mixins/self.py +0 -259
  157. pymax/mixins/socket.py +0 -306
  158. pymax/mixins/telemetry.py +0 -118
  159. pymax/mixins/user.py +0 -219
  160. pymax/mixins/websocket.py +0 -151
  161. pymax/models.py +0 -8
  162. pymax/navigation.py +0 -187
  163. pymax/payloads.py +0 -403
  164. pymax/protocols.py +0 -123
  165. pymax/static/constant.py +0 -96
  166. pymax/static/enum.py +0 -231
  167. pymax/types.py +0 -1220
  168. pymax/utils.py +0 -90
  169. {maxapi_python-1.2.5.dist-info → maxapi_python-2.0.0.dist-info}/licenses/LICENSE +0 -0
pymax/mixins/channel.py DELETED
@@ -1,130 +0,0 @@
1
- from pymax.exceptions import Error, ResponseError, ResponseStructureError
2
- from pymax.payloads import (
3
- GetGroupMembersPayload,
4
- JoinChatPayload,
5
- ResolveLinkPayload,
6
- SearchGroupMembersPayload,
7
- )
8
- from pymax.protocols import ClientProtocol
9
- from pymax.static.constant import (
10
- DEFAULT_CHAT_MEMBERS_LIMIT,
11
- DEFAULT_MARKER_VALUE,
12
- )
13
- from pymax.static.enum import Opcode
14
- from pymax.types import Channel, Member
15
- from pymax.utils import MixinsUtils
16
-
17
-
18
- class ChannelMixin(ClientProtocol):
19
- async def resolve_channel_by_name(self, name: str) -> Channel | None:
20
- """
21
- Получает информацию о канале по его имени
22
-
23
- :param name: Имя канала
24
- :type name: str
25
- :return: Объект Channel или None, если канал не найден
26
- :rtype: Channel | None
27
- """
28
- payload = ResolveLinkPayload(
29
- link=f"https://max.ru/{name}",
30
- ).model_dump(by_alias=True)
31
-
32
- data = await self._send_and_wait(opcode=Opcode.LINK_INFO, payload=payload)
33
- if data.get("payload", {}).get("error"):
34
- MixinsUtils.handle_error(data)
35
-
36
- channel = Channel.from_dict(data.get("payload", {}).get("chat", {}))
37
- if channel not in self.channels:
38
- self.channels.append(channel)
39
- return channel
40
-
41
- async def join_channel(self, link: str) -> Channel | None:
42
- """
43
- Присоединяется к каналу по ссылке
44
-
45
- :param link: Ссылка на канал
46
- :type link: str
47
- :return: Объект канала, если присоединение прошло успешно, иначе None
48
- :rtype: Channel | None
49
- """
50
- payload = JoinChatPayload(
51
- link=link,
52
- ).model_dump(by_alias=True)
53
-
54
- data = await self._send_and_wait(opcode=Opcode.CHAT_JOIN, payload=payload)
55
- if data.get("payload", {}).get("error"):
56
- MixinsUtils.handle_error(data)
57
-
58
- channel = Channel.from_dict(data.get("payload", {}).get("chat", {}))
59
- if channel not in self.channels:
60
- self.channels.append(channel)
61
- return channel
62
-
63
- async def _query_members(
64
- self, payload: GetGroupMembersPayload | SearchGroupMembersPayload
65
- ) -> tuple[list[Member], int | None]:
66
- data = await self._send_and_wait(
67
- opcode=Opcode.CHAT_MEMBERS,
68
- payload=payload.model_dump(by_alias=True, exclude_none=True),
69
- )
70
- response_payload = data.get("payload", {})
71
- if data.get("payload", {}).get("error"):
72
- MixinsUtils.handle_error(data)
73
- marker = response_payload.get("marker")
74
- if isinstance(marker, str):
75
- marker = int(marker)
76
- elif isinstance(marker, int):
77
- pass
78
- elif marker is None:
79
- # маркер может отсутствовать
80
- pass
81
- else:
82
- raise ResponseStructureError("Invalid marker type in response")
83
- members = response_payload.get("members")
84
- member_list = []
85
- if isinstance(members, list):
86
- for item in members:
87
- if not isinstance(item, dict):
88
- raise ResponseStructureError("Invalid member structure in response")
89
- member_list.append(Member.from_dict(item))
90
- else:
91
- raise ResponseStructureError("Invalid members type in response")
92
- return member_list, marker
93
-
94
- async def load_members(
95
- self,
96
- chat_id: int,
97
- marker: int | None = DEFAULT_MARKER_VALUE,
98
- count: int = DEFAULT_CHAT_MEMBERS_LIMIT,
99
- ) -> tuple[list[Member], int | None]:
100
- """
101
- Загружает членов канала
102
-
103
- :param chat_id: Идентификатор канала
104
- :type chat_id: int
105
- :param marker: Маркер для пагинации. По умолчанию DEFAULT_MARKER_VALUE
106
- :type marker: int | None
107
- :param count: Количество членов для загрузки. По умолчанию DEFAULT_CHAT_MEMBERS_LIMIT.
108
- :type count: int
109
- :return: Список участников канала и маркер для следующей страницы
110
- :rtype: tuple[list[Member], int | None]
111
- """
112
-
113
- payload = GetGroupMembersPayload(chat_id=chat_id, marker=marker, count=count)
114
- return await self._query_members(payload)
115
-
116
- async def find_members(self, chat_id: int, query: str) -> tuple[list[Member], int | None]:
117
- """
118
- Поиск участников канала по строке
119
- Внимание! веб-клиент всегда возвращает только определённое количество пользователей,
120
- тоесть пагинация здесь не реализована!
121
-
122
- :param chat_id: Идентификатор канала
123
- :type chat_id: int
124
- :param query: Строка для поиска участников
125
- :type query: str
126
- :return: Список участников канала
127
- :rtype: tuple[list[Member], int | None]
128
- """
129
- payload = SearchGroupMembersPayload(chat_id=chat_id, query=query)
130
- return await self._query_members(payload)
pymax/mixins/group.py DELETED
@@ -1,458 +0,0 @@
1
- import time
2
-
3
- from pymax.exceptions import Error
4
- from pymax.payloads import (
5
- ChangeGroupProfilePayload,
6
- ChangeGroupSettingsOptions,
7
- ChangeGroupSettingsPayload,
8
- CreateGroupAttach,
9
- CreateGroupMessage,
10
- CreateGroupPayload,
11
- FetchChatsPayload,
12
- GetChatInfoPayload,
13
- InviteUsersPayload,
14
- JoinChatPayload,
15
- LeaveChatPayload,
16
- RemoveUsersPayload,
17
- ReworkInviteLinkPayload,
18
- )
19
- from pymax.protocols import ClientProtocol
20
- from pymax.static.enum import Opcode
21
- from pymax.types import Chat, Message
22
- from pymax.utils import MixinsUtils
23
-
24
-
25
- class GroupMixin(ClientProtocol):
26
- async def create_group(
27
- self,
28
- name: str,
29
- participant_ids: list[int] | None = None,
30
- notify: bool = True,
31
- ) -> tuple[Chat, Message] | None:
32
- """
33
- Создает группу
34
-
35
- Args:
36
- name (str): Название группы.
37
- participant_ids (list[int] | None, optional): Список идентификаторов участников. Defaults to None.
38
- notify (bool, optional): Флаг оповещения. Defaults to True.
39
-
40
- Returns:
41
- tuple[Chat, Message] | None: Объект Chat и Message или None при ошибке.
42
- """
43
- payload = CreateGroupPayload(
44
- message=CreateGroupMessage(
45
- cid=int(time.time() * 1000),
46
- attaches=[
47
- CreateGroupAttach(
48
- _type="CONTROL",
49
- title=name,
50
- user_ids=(participant_ids if participant_ids else []),
51
- )
52
- ],
53
- ),
54
- notify=notify,
55
- ).model_dump(by_alias=True)
56
-
57
- data = await self._send_and_wait(opcode=Opcode.MSG_SEND, payload=payload)
58
- if data.get("payload", {}).get("error"):
59
- MixinsUtils.handle_error(data)
60
-
61
- chat = Chat.from_dict(data["payload"]["chat"])
62
- message = Message.from_dict(data["payload"])
63
-
64
- if chat:
65
- cached_chat = await self._get_chat(chat.id)
66
- if cached_chat is None:
67
- self.chats.append(chat)
68
- else:
69
- idx = self.chats.index(cached_chat)
70
- self.chats[idx] = chat
71
-
72
- return chat, message
73
-
74
- async def invite_users_to_group(
75
- self,
76
- chat_id: int,
77
- user_ids: list[int],
78
- show_history: bool = True,
79
- ) -> Chat | None:
80
- """
81
- Приглашает пользователей в группу
82
-
83
- Args:
84
- chat_id (int): ID группы.
85
- user_ids (list[int]): Список идентификаторов пользователей.
86
- show_history (bool, optional): Флаг оповещения. Defaults to True.
87
-
88
- Returns:
89
- Chat | None: Объект Chat или None при ошибке.
90
- """
91
- payload = InviteUsersPayload(
92
- chat_id=chat_id,
93
- user_ids=user_ids,
94
- show_history=show_history,
95
- operation="add",
96
- ).model_dump(by_alias=True)
97
-
98
- data = await self._send_and_wait(opcode=Opcode.CHAT_MEMBERS_UPDATE, payload=payload)
99
-
100
- if data.get("payload", {}).get("error"):
101
- MixinsUtils.handle_error(data)
102
-
103
- chat = Chat.from_dict(data["payload"]["chat"])
104
- if chat:
105
- cached_chat = await self._get_chat(chat.id)
106
- if cached_chat is None:
107
- self.chats.append(chat)
108
- else:
109
- idx = self.chats.index(cached_chat)
110
- self.chats[idx] = chat
111
-
112
- return chat
113
-
114
- async def invite_users_to_channel(
115
- self,
116
- chat_id: int,
117
- user_ids: list[int],
118
- show_history: bool = True,
119
- ) -> Chat | None:
120
- """
121
- Приглашает пользователей в канал
122
-
123
- Args:
124
- chat_id (int): ID канала.
125
- user_ids (list[int]): Список идентификаторов пользователей.
126
- show_history (bool, optional): Флаг оповещения. Defaults to True.
127
-
128
- Returns:
129
- Chat | None: Объект Chat или None при ошибке.
130
- """
131
- return await self.invite_users_to_group(chat_id, user_ids, show_history)
132
-
133
- async def remove_users_from_group(
134
- self,
135
- chat_id: int,
136
- user_ids: list[int],
137
- clean_msg_period: int,
138
- ) -> bool:
139
- """
140
- Удаляет пользователей из группы
141
-
142
- Args:
143
- chat_id (int): ID группы.
144
- user_ids (list[int]): Список идентификаторов пользователей.
145
- clean_msg_period (int): Период очистки сообщений.
146
-
147
- Returns:
148
- bool: True, если удаление прошло успешно, иначе False.
149
- """
150
- payload = RemoveUsersPayload(
151
- chat_id=chat_id,
152
- user_ids=user_ids,
153
- clean_msg_period=clean_msg_period,
154
- ).model_dump(by_alias=True)
155
-
156
- data = await self._send_and_wait(opcode=Opcode.CHAT_MEMBERS_UPDATE, payload=payload)
157
-
158
- if data.get("payload", {}).get("error"):
159
- MixinsUtils.handle_error(data)
160
-
161
- chat = Chat.from_dict(data["payload"]["chat"])
162
- if chat:
163
- cached_chat = await self._get_chat(chat.id)
164
- if cached_chat is None:
165
- self.chats.append(chat)
166
- else:
167
- idx = self.chats.index(cached_chat)
168
- self.chats[idx] = chat
169
-
170
- return True
171
-
172
- async def change_group_settings(
173
- self,
174
- chat_id: int,
175
- all_can_pin_message: bool | None = None,
176
- only_owner_can_change_icon_title: bool | None = None,
177
- only_admin_can_add_member: bool | None = None,
178
- only_admin_can_call: bool | None = None,
179
- members_can_see_private_link: bool | None = None,
180
- ) -> None:
181
- """
182
- Изменяет настройки группы
183
-
184
- Args:
185
- chat_id (int): ID группы.
186
- all_can_pin_message (bool | None, optional): Все могут закреплять сообщения. Defaults to None.
187
- only_owner_can_change_icon_title (bool | None, optional): Только владелец может менять иконку и название. Defaults to None.
188
- only_admin_can_add_member (bool | None, optional): Только администраторы могут добавлять участников. Defaults to None.
189
- only_admin_can_call (bool | None, optional): Только администраторы могут звонить. Defaults to None.
190
- members_can_see_private_link (bool | None, optional): Участники могут видеть приватную ссылку. Defaults to None.
191
- Returns:
192
- None
193
- """
194
- payload = ChangeGroupSettingsPayload(
195
- chat_id=chat_id,
196
- options=ChangeGroupSettingsOptions(
197
- ALL_CAN_PIN_MESSAGE=all_can_pin_message,
198
- ONLY_OWNER_CAN_CHANGE_ICON_TITLE=only_owner_can_change_icon_title,
199
- ONLY_ADMIN_CAN_ADD_MEMBER=only_admin_can_add_member,
200
- ONLY_ADMIN_CAN_CALL=only_admin_can_call,
201
- MEMBERS_CAN_SEE_PRIVATE_LINK=members_can_see_private_link,
202
- ),
203
- ).model_dump(by_alias=True, exclude_none=True)
204
-
205
- data = await self._send_and_wait(opcode=Opcode.CHAT_UPDATE, payload=payload)
206
-
207
- if data.get("payload", {}).get("error"):
208
- MixinsUtils.handle_error(data)
209
-
210
- chat = Chat.from_dict(data["payload"]["chat"])
211
- if chat:
212
- cached_chat = await self._get_chat(chat.id)
213
- if cached_chat is None:
214
- self.chats.append(chat)
215
- else:
216
- idx = self.chats.index(cached_chat)
217
- self.chats[idx] = chat
218
-
219
- async def change_group_profile(
220
- self,
221
- chat_id: int,
222
- name: str | None,
223
- description: str | None = None,
224
- ) -> None:
225
- """
226
- Изменяет профиль группы
227
-
228
- Args:
229
- chat_id (int): ID группы.
230
- name (str | None): Название группы.
231
- description (str | None, optional): Описание группы. Defaults to None.
232
-
233
- Returns:
234
- None
235
- """
236
- payload = ChangeGroupProfilePayload(
237
- chat_id=chat_id,
238
- theme=name,
239
- description=description,
240
- ).model_dump(by_alias=True, exclude_none=True)
241
-
242
- data = await self._send_and_wait(opcode=Opcode.CHAT_UPDATE, payload=payload)
243
-
244
- if data.get("payload", {}).get("error"):
245
- MixinsUtils.handle_error(data)
246
-
247
- chat = Chat.from_dict(data["payload"]["chat"])
248
- if chat:
249
- cached_chat = await self._get_chat(chat.id)
250
- if cached_chat is None:
251
- self.chats.append(chat)
252
- else:
253
- idx = self.chats.index(cached_chat)
254
- self.chats[idx] = chat
255
-
256
- def _process_chat_join_link(self, link: str) -> str | None:
257
- idx = link.find("join/")
258
- return link[idx:] if idx != -1 else None
259
-
260
- async def join_group(self, link: str) -> Chat:
261
- """
262
- Вступает в группу по ссылке
263
-
264
- Args:
265
- link (str): Ссылка на группу.
266
-
267
- Returns:
268
- Chat: Объект чата группы
269
- """
270
- proceed_link = self._process_chat_join_link(link)
271
- if proceed_link is None:
272
- raise ValueError("Invalid group link")
273
-
274
- payload = JoinChatPayload(link=proceed_link).model_dump(by_alias=True)
275
-
276
- data = await self._send_and_wait(opcode=Opcode.CHAT_JOIN, payload=payload)
277
-
278
- if data.get("payload", {}).get("error"):
279
- MixinsUtils.handle_error(data)
280
-
281
- chat = Chat.from_dict(data["payload"]["chat"])
282
- if chat:
283
- cached_chat = await self._get_chat(chat.id)
284
- if cached_chat is None:
285
- self.chats.append(chat)
286
- else:
287
- idx = self.chats.index(cached_chat)
288
- self.chats[idx] = chat
289
-
290
- return chat
291
-
292
- async def resolve_group_by_link(self, link: str) -> Chat | None:
293
- """
294
- Разрешает группу по ссылке
295
-
296
- Args:
297
- link (str): Ссылка на группу.
298
-
299
- Returns:
300
- Chat | None: Объект чата группы или None, если не найдено.
301
- """
302
- proceed_link = self._process_chat_join_link(link)
303
- if proceed_link is None:
304
- raise ValueError("Invalid group link")
305
-
306
- data = await self._send_and_wait(
307
- opcode=Opcode.LINK_INFO,
308
- payload={
309
- "link": proceed_link,
310
- },
311
- )
312
-
313
- if data.get("payload", {}).get("error"):
314
- MixinsUtils.handle_error(data)
315
-
316
- chat = Chat.from_dict(data["payload"].get("chat", {}))
317
- return chat
318
-
319
- async def rework_invite_link(self, chat_id: int) -> Chat:
320
- """
321
- Пересоздает ссылку для приглашения в группу
322
-
323
- Args:
324
- chat_id (int): ID группы.
325
-
326
- Returns:
327
- Chat: Обновленный объект чата с новой ссылкой.
328
- """
329
- payload = ReworkInviteLinkPayload(chat_id=chat_id).model_dump(by_alias=True)
330
-
331
- data = await self._send_and_wait(opcode=Opcode.CHAT_UPDATE, payload=payload)
332
-
333
- if data.get("payload", {}).get("error"):
334
- MixinsUtils.handle_error(data)
335
-
336
- chat = Chat.from_dict(data["payload"].get("chat"))
337
- if not chat:
338
- raise Error("no_chat", "Chat data missing in response", "Chat Error")
339
-
340
- return chat
341
-
342
- async def get_chats(self, chat_ids: list[int]) -> list[Chat]:
343
- """
344
- Получает информацию о группах по их ID
345
-
346
- :param chat_ids: Список идентификаторов групп.
347
- :type chat_ids: list[int]
348
- :return: Список объектов Chat.
349
- :rtype: list[Chat]
350
- """
351
- missed_chat_ids = [
352
- chat_id for chat_id in chat_ids if await self._get_chat(chat_id) is None
353
- ]
354
- if missed_chat_ids:
355
- payload = GetChatInfoPayload(chat_ids=missed_chat_ids).model_dump(by_alias=True)
356
- else:
357
- chats: list[Chat] = [
358
- chat for chat_id in chat_ids if (chat := await self._get_chat(chat_id)) is not None
359
- ]
360
- return chats
361
-
362
- data = await self._send_and_wait(opcode=Opcode.CHAT_INFO, payload=payload)
363
-
364
- if data.get("payload", {}).get("error"):
365
- MixinsUtils.handle_error(data)
366
-
367
- chats_data = data["payload"].get("chats", [])
368
- chats: list[Chat] = []
369
- for chat_dict in chats_data:
370
- chat = Chat.from_dict(chat_dict)
371
- chats.append(chat)
372
- cached_chat = await self._get_chat(chat.id)
373
- if cached_chat is None:
374
- self.chats.append(chat)
375
- else:
376
- idx = self.chats.index(cached_chat)
377
- self.chats[idx] = chat
378
-
379
- return chats
380
-
381
- async def get_chat(self, chat_id: int) -> Chat:
382
- """
383
- Получает информацию о группе по ее ID
384
-
385
- Args:
386
- chat_id (int): Идентификатор группы.
387
-
388
- Returns:
389
- Chat: Объект Chat.
390
- """
391
- chats = await self.get_chats([chat_id])
392
- if not chats:
393
- raise Error("no_chat", "Chat not found in response", "Chat Error")
394
- return chats[0]
395
-
396
- async def leave_group(self, chat_id: int) -> None:
397
- """
398
- Покидает группу
399
-
400
- :param chat_id: Идентификатор группы.
401
- :type chat_id: int
402
- :return: None
403
- :rtype: None
404
- """
405
- payload = LeaveChatPayload(chat_id=chat_id).model_dump(by_alias=True)
406
-
407
- data = await self._send_and_wait(opcode=Opcode.CHAT_LEAVE, payload=payload)
408
-
409
- if data.get("payload", {}).get("error"):
410
- MixinsUtils.handle_error(data)
411
-
412
- cached_chat = await self._get_chat(chat_id)
413
- if cached_chat is not None:
414
- self.chats.remove(cached_chat)
415
-
416
- async def leave_channel(self, chat_id: int) -> None:
417
- """
418
- Покидает канал
419
-
420
- :param chat_id: Идентификатор канала.
421
- :type chat_id: int
422
- :return: None
423
- :rtype: None
424
- """
425
- await self.leave_group(chat_id)
426
-
427
- async def fetch_chats(self, marker: int | None = None) -> list[Chat]:
428
- """
429
- Загружает список чатов
430
-
431
- :param marker: Маркер для пагинации, по умолчанию None
432
- :type marker: int | None
433
- :return: Список объектов Chat
434
- :rtype: list[Chat]
435
- """
436
- if marker is None:
437
- marker = int(time.time() * 1000)
438
-
439
- payload = FetchChatsPayload(marker=marker).model_dump(by_alias=True)
440
-
441
- data = await self._send_and_wait(opcode=Opcode.CHATS_LIST, payload=payload)
442
-
443
- if data.get("payload", {}).get("error"):
444
- MixinsUtils.handle_error(data)
445
-
446
- chats_data = data["payload"].get("chats", [])
447
- chats: list[Chat] = []
448
- for chat_dict in chats_data:
449
- chat = Chat.from_dict(chat_dict)
450
- chats.append(chat)
451
- cached_chat = await self._get_chat(chat.id)
452
- if cached_chat is None:
453
- self.chats.append(chat)
454
- else:
455
- idx = self.chats.index(cached_chat)
456
- self.chats[idx] = chat
457
-
458
- return chats