Skip to content
This repository was archived by the owner on Feb 11, 2026. It is now read-only.

Commit b5d08a7

Browse files
committed
Фикс доков, добавил проверку device_type, добавил возможность переименования сессии
1 parent 947a38c commit b5d08a7

5 files changed

Lines changed: 27 additions & 18 deletions

File tree

redocs/source/guides.rst

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,6 @@ Guides
9393
async def greeting(message: Message) -> None:
9494
pass
9595
96-
# Только личные
97-
@client.on_message(Filters.dialog())
98-
async def private(message: Message) -> None:
99-
pass
100-
10196
# Только группы
10297
@client.on_message(Filters.chat())
10398
async def in_group(message: Message) -> None:

redocs/source/quickstart.rst

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,6 @@ Quick Start
6868
text="И тебе привет!"
6969
)
7070
71-
# Только личные сообщения
72-
@client.on_message(Filters.dialog())
73-
async def private_handler(message: Message) -> None:
74-
print(f"Личное сообщение: {message.text}")
7571
7672
Обработчики событий
7773
--------------------

src/pymax/core.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,7 @@
2222
from .interfaces import BaseClient
2323
from .mixins import ApiMixin, SocketMixin, WebSocketMixin
2424
from .payloads import UserAgentPayload
25-
from .static.constant import (
26-
HOST,
27-
PORT,
28-
WEBSOCKET_URI,
29-
)
25+
from .static.constant import HOST, PORT, SESSION_STORAGE_DB, WEBSOCKET_URI
3026

3127
if TYPE_CHECKING:
3228
from collections.abc import Callable
@@ -42,6 +38,7 @@
4238

4339

4440
class MaxClient(ApiMixin, WebSocketMixin, BaseClient):
41+
allowed_device_types: set[str] = {"WEB"}
4542
"""
4643
Основной клиент для работы с WebSocket API сервиса Max.
4744
@@ -81,7 +78,8 @@ def __init__(
8178
self,
8279
phone: str,
8380
uri: str = WEBSOCKET_URI,
84-
headers: UserAgentPayload = UserAgentPayload(),
81+
session_name: str = SESSION_STORAGE_DB,
82+
headers: UserAgentPayload | None = None,
8583
token: str | None = None,
8684
send_fake_telemetry: bool = True,
8785
host: str = HOST,
@@ -120,7 +118,7 @@ def __init__(
120118
self._users: dict[int, User] = {}
121119

122120
self._work_dir: str = work_dir
123-
self._database_path: Path = Path(work_dir) / "session.db"
121+
self._database_path: Path = Path(work_dir) / session_name
124122
self._database_path.parent.mkdir(parents=True, exist_ok=True)
125123
self._database_path.touch(exist_ok=True)
126124
self._database = Database(self._work_dir)
@@ -143,7 +141,10 @@ def __init__(
143141
self._file_upload_waiters: dict[int, asyncio.Future[dict[str, Any]]] = {}
144142

145143
self._token = self._database.get_auth_token() or token
144+
if headers is None:
145+
headers = self._default_headers()
146146
self.user_agent = headers
147+
self._validate_device_type()
147148
self._send_fake_telemetry: bool = send_fake_telemetry
148149
self._session_id: int = int(time.time() * 1000)
149150
self._action_id: int = 1
@@ -181,6 +182,17 @@ def __init__(
181182
self._work_dir,
182183
)
183184

185+
@staticmethod
186+
def _default_headers() -> UserAgentPayload:
187+
return UserAgentPayload(device_type="WEB")
188+
189+
def _validate_device_type(self) -> None:
190+
if self.user_agent.device_type not in self.allowed_device_types:
191+
raise ValueError(
192+
f"{self.__class__.__name__} does not support "
193+
f"device_type={self.user_agent.device_type}"
194+
)
195+
184196
async def _wait_forever(self) -> None:
185197
try:
186198
await self.ws.wait_closed()
@@ -267,7 +279,6 @@ async def start(self) -> None:
267279
:return: None
268280
:rtype: None
269281
"""
270-
271282
self.logger.info("Client starting")
272283
while not self._stop_event.is_set():
273284
try:
@@ -318,6 +329,12 @@ async def start(self) -> None:
318329

319330

320331
class SocketMaxClient(SocketMixin, MaxClient):
332+
allowed_device_types = {"ANDROID", "IOS", "DESKTOP"}
333+
334+
@staticmethod
335+
def _default_headers() -> UserAgentPayload:
336+
return UserAgentPayload(device_type="DESKTOP")
337+
321338
@override
322339
async def _wait_forever(self):
323340
if self._recv_task:

src/pymax/interfaces.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ def _get_retry_delay(self, error: Exception, retry_count: int) -> float:
485485
else:
486486
return float(2**retry_count)
487487

488-
async def _sync(self, user_agent: UserAgentPayload | None) -> None:
488+
async def _sync(self, user_agent: UserAgentPayload | None = None) -> None:
489489
self.logger.info("Starting initial sync")
490490

491491
if user_agent is None:

src/pymax/static/constant.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767

6868
PHONE_REGEX: Final[Pattern[str]] = compile(r"^\+?\d{10,15}$")
6969
WEBSOCKET_URI: Final[str] = "wss://ws-api.oneme.ru/websocket"
70+
SESSION_STORAGE_DB = "session.db"
7071
WEBSOCKET_ORIGIN: Final[Origin] = Origin("https://web.max.ru")
7172
HOST: Final[str] = "api.oneme.ru"
7273
PORT: Final[int] = 443

0 commit comments

Comments
 (0)