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

Commit b325c95

Browse files
Merge pull request #35 from MaxApiTeam/dev/1.2.5
Dev/1.2.5
2 parents a6e69af + aa736c9 commit b325c95

File tree

12 files changed

+558
-184
lines changed

12 files changed

+558
-184
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "maxapi-python"
3-
version = "1.2.4"
3+
version = "1.2.5"
44
description = "Python wrapper для API мессенджера Max"
55
readme = "README.md"
66
requires-python = ">=3.10"

redocs/source/release_notes.rst

Lines changed: 34 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,143 +1,61 @@
1-
Release Notes v1.2.4
1+
Release Notes v1.2.5
22
====================
33

44
Новые функции
55
-------------
66

7-
**Поддержка различных типов файлов в классах File и Photo**
8-
Классы ``Photo``, ``File`` и ``Video`` теперь поддерживают работу с байтами, что позволяет загружать файлы из памяти напрямую.
7+
**Двухфакторная аутентификация (2FA)**
8+
Добавлена полная поддержка двухфакторной аутентификации с использованием пароля, email-кода и подсказок для восстановления пароля. Теперь возможен вход в аккаунт когда включена 2FA с проверкой пароля.
99

10-
**Автоматическая отправка уведомлений о прочтении сообщений**
11-
Клиент теперь автоматически отправляет сервису уведомления о получении сообщений для улучшения синхронизации.
10+
**Управление паролем аккаунта**
11+
Новый метод ``set_password()`` позволяет устанавливать, изменять и управлять паролем аккаунта с поддержкой подсказок и email для восстановления.
1212

13-
**Параметр session_name для управления сессией**
14-
Параметр ``session_name`` позволяет указать пользовательское имя файла для сохранения сессии.
13+
**Исправления в обработке сокетов**
14+
Улучшена обработка последовательности сообщений (sequence numbers) для корректной работы с 8-битными числами.
1515

16-
**Получение текущей версии веб-приложения**
17-
Новый метод ``get_current_web_version()`` в утилитах для получения текущей версии веб-приложения Max.
18-
19-
**Улучшенная генерация User-Agent**
20-
Теперь используется библиотека ``ua-generator`` для более реалистичной генерации User-Agent строк и параметров устройства.
16+
**Улучшения протокола WebSocket**
17+
Добавлена поддержка версии протокола (ver=11) в сообщениях WebSocket.
2118

2219
Новые методы
2320
------------
2421

25-
read_message(chat_id: int, message_id: int) -> ReadState
26-
Отмечает сообщение как прочитанное. Возвращает объект ReadState с информацией о состоянии.
27-
28-
pymax.utils.MixinsUtils.get_current_web_version() -> str | None
29-
Получает текущую версию веб-приложения Max из источника. Возвращает версию в формате "XX.XX.XX" или None.
30-
31-
Измененные методы
32-
-----------------
33-
34-
MaxClient.start()
35-
Улучшена логика работы цикла переподключения с использованием ``asyncio.Event`` для более чистого завершения.
36-
Исправлена обработка состояния при отключении и переподключении.
37-
38-
MaxClient.close()
39-
Упрощена логика закрытия клиента. Теперь использует ``asyncio.Event`` для сигнала остановки.
40-
41-
Новые параметры
42-
---------------
43-
44-
MaxClient.__init__(session_name: str = "session.db")
45-
Позволяет указать пользовательское имя файла базы данных сессии.
46-
47-
Измененные типы
48-
---------------
49-
50-
BaseFile
51-
Теперь поддерживает работу с байтами через параметр ``raw`` во всех подклассах.
22+
MaxClient.set_password(password: str, email: str | None = None, hint: str | None = UNSET)
23+
Устанавливает пароль для аккаунта с возможностью добавления подсказки и email для восстановления.
5224

53-
Photo
54-
Добавлен параметр ``name`` для явного указания имени файла при работе с байтами.
55-
Улучшена валидация расширений файлов.
25+
Новые типы и перечисления
26+
--------------------------
5627

57-
File
58-
Добавлена поддержка работы с байтами через параметр ``raw``.
59-
Улучшена обработка имен файлов.
28+
Capability
29+
Перечисление для описания возможностей аккаунта в контексте двухфакторной аутентификации.
6030

61-
Video
62-
Добавлена поддержка работы с байтами через параметр ``raw``.
63-
Улучшена работа с видеофайлами.
31+
Payload классы
32+
``CheckPasswordChallengePayload`` — для проверки пароля при 2FA
33+
``CreateTrackPayload`` — для создания отслеживающего ID
34+
``SetPasswordPayload`` — для установки пароля
35+
``SetHintPayload`` — для установки подсказки пароля
36+
``RequestEmailCodePayload`` — для запроса кода по email
37+
``SendEmailCodePayload`` — для отправки email кода
38+
``SetTwoFactorPayload`` — для установки параметров 2FA
6439

6540
Исправления и улучшения
6641
------------------------
6742

68-
- Добавлена валидация ``device_type`` для MaxClient (поддерживает только WEB) и SocketMaxClient (поддерживает ANDROID, IOS, DESKTOP)
69-
- Улучшена обработка ошибок WebSocket при отключении
70-
- Добавлена опция ``ua-generator`` для более реалистичной генерации параметров устройства
71-
- Обновлена версия приложения до 25.12.14
72-
- Улучшена обработка уведомлений о доставке сообщений
73-
- Исправлены проблемы с завершением async задач при закрытии клиента
74-
75-
Зависимости
76-
-----------
77-
78-
Добавлены новые зависимости:
79-
- ``ua-generator>=2.0.19`` — для генерации реалистичных User-Agent строк и параметров устройства
43+
- Исправлена обработка последовательности сообщений в socket-клиенте (seq % 256)
44+
- Исправлена обработка последовательности сообщений в websocket-клиенте
45+
- Добавлена проверка подключения перед отправкой уведомлений о прочтении
46+
- Улучшена обработка двухфакторной аутентификации при логине
47+
- Исправлена инициализация seq на 255 вместо 0 в core.py
48+
- Добавлена обработка ``SocketNotConnectedError`` в telemetry
49+
- Исправлена обработка ошибок при отправке в socket/websocket
8050

8151
Версия
8252
------
8353

84-
**1.2.4** - выпущена 30 декабря 2025 г.
54+
**1.2.5** - выпущена 31 декабря 2025 г.
8555

8656
---
8757

88-
Release Notes v1.2.3
89-
====================
90-
91-
Новые функции
92-
-------------
93-
94-
**Загрузка фотографий профиля**
95-
Профиль теперь может быть обновлен с загрузкой новой фотографии через метод ``change_profile()``.
96-
97-
**Разрешение групп по ссылке**
98-
Группы теперь могут быть разрешены (получены) прямо по их ссылке через метод ``resolve_group_by_link()``.
99-
100-
**Поддержка контактов в сообщениях**
101-
Сообщения теперь поддерживают вложения типа контакта с информацией о контакте (ContactAttach).
102-
103-
**Список контактов клиента**
104-
Клиент теперь ведет список всех контактов пользователя через свойство ``client.contacts``.
105-
106-
Новые методы
107-
------------
108-
109-
MaxClient.resolve_group_by_link(link: str) -> Chat | None
110-
Разрешает группу по ссылке. Возвращает объект чата группы или None, если не найдено.
111-
112-
MaxClient.change_profile(first_name, last_name, description, photo)
113-
Изменяет информацию профиля текущего пользователя, включая загрузку новой фотографии.
114-
115-
Новые типы
116-
----------
117-
118-
ContactAttach
119-
Представляет контакт в сообщении. Содержит информацию о контакте (ID, имя, фамилия, фото).
120-
121-
Измененные типы
122-
---------------
123-
124-
Message
125-
Теперь поддерживает вложения типа ContactAttach в список attaches.
126-
127-
Names
128-
Улучшен для работы с различными форматами имен пользователя.
129-
130-
StickerAttach
131-
Улучшено представление стикеров в сообщениях.
132-
133-
Photo
134-
Улучшено для работы с фотографиями профиля.
135-
136-
AttachType
137-
Добавлено значение CONTACT для контактов.
138-
139-
Новые параметры
140-
---------------
58+
Архив
59+
-----
14160

142-
MaxClient.contacts: list[User]
143-
Список контактов текущего пользователя.
61+
Предыдущие версии доступны в :doc:`release_notes_archive`.
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
Archive
2+
=======
3+
4+
Архив предыдущих версий.
5+
6+
v1.2.4 (30 декабря 2025)
7+
=========================
8+
9+
Новые функции
10+
-------------
11+
12+
**Поддержка различных типов файлов в классах File и Photo**
13+
Классы ``Photo``, ``File`` и ``Video`` теперь поддерживают работу с байтами, что позволяет загружать файлы из памяти напрямую.
14+
15+
**Автоматическая отправка уведомлений о прочтении сообщений**
16+
Клиент теперь автоматически отправляет сервису уведомления о получении сообщений для улучшения синхронизации.
17+
18+
**Параметр session_name для управления сессией**
19+
Параметр ``session_name`` позволяет указать пользовательское имя файла для сохранения сессии.
20+
21+
**Получение текущей версии веб-приложения**
22+
Новый метод ``get_current_web_version()`` в утилитах для получения текущей версии веб-приложения Max.
23+
24+
**Улучшенная генерация User-Agent**
25+
Теперь используется библиотека ``ua-generator`` для более реалистичной генерации User-Agent строк и параметров устройства.
26+
27+
Новые методы
28+
------------
29+
30+
read_message(chat_id: int, message_id: int) -> ReadState
31+
Отмечает сообщение как прочитанное. Возвращает объект ReadState с информацией о состоянии.
32+
33+
pymax.utils.MixinsUtils.get_current_web_version() -> str | None
34+
Получает текущую версию веб-приложения Max из источника. Возвращает версию в формате "XX.XX.XX" или None.
35+
36+
Измененные методы
37+
-----------------
38+
39+
MaxClient.start()
40+
Улучшена логика работы цикла переподключения с использованием ``asyncio.Event`` для более чистого завершения.
41+
Исправлена обработка состояния при отключении и переподключении.
42+
43+
MaxClient.close()
44+
Упрощена логика закрытия клиента. Теперь использует ``asyncio.Event`` для сигнала остановки.
45+
46+
Новые параметры
47+
---------------
48+
49+
MaxClient.__init__(session_name: str = "session.db")
50+
Позволяет указать пользовательское имя файла базы данных сессии.
51+
52+
Измененные типы
53+
---------------
54+
55+
BaseFile
56+
Теперь поддерживает работу с байтами через параметр ``raw`` во всех подклассах.
57+
58+
Photo
59+
Добавлен параметр ``name`` для явного указания имени файла при работе с байтами.
60+
Улучшена валидация расширений файлов.
61+
62+
File
63+
Добавлена поддержка работы с байтами через параметр ``raw``.
64+
Улучшена обработка имен файлов.
65+
66+
Video
67+
Добавлена поддержка работы с байтами через параметр ``raw``.
68+
Улучшена работа с видеофайлами.
69+
70+
Исправления и улучшения
71+
------------------------
72+
73+
- Добавлена валидация ``device_type`` для MaxClient (поддерживает только WEB) и SocketMaxClient (поддерживает ANDROID, IOS, DESKTOP)
74+
- Улучшена обработка ошибок WebSocket при отключении
75+
- Добавлена опция ``ua-generator`` для более реалистичной генерации параметров устройства
76+
- Обновлена версия приложения до 25.12.14
77+
- Улучшена обработка уведомлений о доставке сообщений
78+
- Исправлены проблемы с завершением async задач при закрытии клиента
79+
80+
Зависимости
81+
-----------
82+
83+
Добавлены новые зависимости:
84+
- ``ua-generator>=2.0.19`` — для генерации реалистичных User-Agent строк и параметров устройства
85+
86+
v1.2.3 (24 декабря 2025)
87+
=========================
88+
89+
Новые функции
90+
-------------
91+
92+
**Загрузка фотографий профиля**
93+
Профиль теперь может быть обновлен с загрузкой новой фотографии через метод ``change_profile()``.
94+
95+
**Разрешение групп по ссылке**
96+
Группы теперь могут быть разрешены (получены) прямо по их ссылке через метод ``resolve_group_by_link()``.
97+
98+
**Поддержка контактов в сообщениях**
99+
Сообщения теперь поддерживают вложения типа контакта с информацией о контакте (ContactAttach).
100+
101+
**Список контактов клиента**
102+
Клиент теперь ведет список всех контактов пользователя через свойство ``client.contacts``.
103+
104+
Новые методы
105+
------------
106+
107+
MaxClient.resolve_group_by_link(link: str) -> Chat | None
108+
Разрешает группу по ссылке. Возвращает объект чата группы или None, если не найдено.
109+
110+
MaxClient.change_profile(first_name, last_name, description, photo)
111+
Изменяет информацию профиля текущего пользователя, включая загрузку новой фотографии.
112+
113+
Новые типы
114+
----------
115+
116+
ContactAttach
117+
Представляет контакт в сообщении. Содержит информацию о контакте (ID, имя, фамилия, фото).
118+
119+
Измененные типы
120+
---------------
121+
122+
Message
123+
Теперь поддерживает вложения типа ContactAttach в список attaches.
124+
125+
Names
126+
Улучшен для работы с различными форматами имен пользователя.
127+
128+
StickerAttach
129+
Улучшено представление стикеров в сообщениях.
130+
131+
Photo
132+
Улучшено для работы с фотографиями профиля.
133+
134+
AttachType
135+
Добавлено значение CONTACT для контактов.
136+
137+
Новые параметры
138+
---------------
139+
140+
MaxClient.contacts: list[User]
141+
Список контактов текущего пользователя.

src/pymax/core.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,15 @@ async def login_with_code(self, temp_token: str, code: str, start: bool = False)
252252
:rtype: None
253253
"""
254254
resp = await self._send_code(code, temp_token)
255-
token = resp.get("tokenAttrs", {}).get("LOGIN", {}).get("token")
255+
256+
login_attrs = resp.get("tokenAttrs", {}).get("LOGIN", {})
257+
password_challenge = resp.get("passwordChallenge")
258+
259+
if password_challenge and not login_attrs:
260+
token = await self._two_factor_auth(password_challenge)
261+
else:
262+
token = login_attrs.get("token")
263+
256264
if not token:
257265
raise ValueError("Login response did not contain tokenAttrs.LOGIN.token")
258266
self._token = token

src/pymax/interfaces.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from typing_extensions import Self
1212

13-
from pymax.exceptions import WebSocketNotConnectedError
13+
from pymax.exceptions import SocketNotConnectedError, WebSocketNotConnectedError
1414
from pymax.filters import BaseFilter
1515
from pymax.formatter import ColoredFormatter
1616
from pymax.payloads import BaseWebSocketMessage, SyncPayload, UserAgentPayload
@@ -188,6 +188,7 @@ def _make_message(
188188
self._seq += 1
189189

190190
msg = BaseWebSocketMessage(
191+
ver=11,
191192
cmd=cmd,
192193
seq=self._seq,
193194
opcode=opcode.value,
@@ -206,8 +207,11 @@ async def _send_interactive_ping(self) -> None:
206207
cmd=0,
207208
)
208209
self.logger.debug("Interactive ping sent successfully")
210+
except SocketNotConnectedError:
211+
self.logger.debug("Socket disconnected, exiting ping loop")
212+
break
209213
except Exception:
210-
self.logger.warning("Interactive ping failed", exc_info=True)
214+
self.logger.warning("Interactive ping failed")
211215
await asyncio.sleep(DEFAULT_PING_INTERVAL)
212216

213217
async def _handshake(self, user_agent: UserAgentPayload) -> dict[str, Any]:
@@ -283,6 +287,8 @@ async def _handle_file_upload(self, data: dict[str, Any]) -> None:
283287
self.logger.debug("Fulfilled file upload waiter for %s=%s", key, id_)
284288

285289
async def _send_notification_response(self, chat_id: int, message_id: str) -> None:
290+
if self._socket is not None and self.is_connected:
291+
return
286292
await self._send_and_wait(
287293
opcode=Opcode.NOTIF_MESSAGE,
288294
payload={"chatId": chat_id, "messageId": message_id},

0 commit comments

Comments
 (0)