maxapi-python 1.1.19__tar.gz → 1.1.20__tar.gz
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.
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/PKG-INFO +1 -1
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/docs/api.md +266 -30
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/docs/client.md +5 -7
- maxapi_python-1.1.20/docs/examples.md +149 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/docs/index.md +4 -2
- maxapi_python-1.1.20/docs/methods.md +876 -0
- maxapi_python-1.1.20/docs/types.md +512 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/examples/example.py +55 -18
- maxapi_python-1.1.20/examples/reg.py +13 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/examples/telegram_bridge.py +1 -1
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/pyproject.toml +1 -1
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/core.py +58 -7
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/files.py +15 -12
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/interfaces.py +9 -5
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/auth.py +1 -1
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/channel.py +6 -6
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/group.py +60 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/handler.py +2 -1
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/message.py +89 -12
- maxapi_python-1.1.20/src/pymax/mixins/self.py +155 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/socket.py +53 -26
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/websocket.py +10 -1
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/payloads.py +36 -3
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/static/enum.py +0 -1
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/types.py +114 -2
- maxapi_python-1.1.19/docs/examples.md +0 -418
- maxapi_python-1.1.19/docs/methods.md +0 -499
- maxapi_python-1.1.19/docs/types.md +0 -314
- maxapi_python-1.1.19/src/pymax/mixins/self.py +0 -41
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/.github/FUNDING.yml +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/.github/ISSUE_TEMPLATE/refactor.md +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/.github/pull_request_template.md +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/.github/workflows/publish.yml +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/.gitignore +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/.pre-commit-config.yaml +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/LICENSE +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/README.md +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/assets/icon.svg +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/assets/logo.svg +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/docs/assets/icon.svg +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/mkdocs.yml +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/ruff.toml +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/__init__.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/crud.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/exceptions.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/filters.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/formatter.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/formatting.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/__init__.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/telemetry.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/user.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/utils.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/models.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/navigation.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/static/constant.py +0 -0
|
@@ -22,12 +22,20 @@
|
|
|
22
22
|
```python
|
|
23
23
|
MaxClient(
|
|
24
24
|
phone: str,
|
|
25
|
-
uri: str = "
|
|
25
|
+
uri: str = "wss://...",
|
|
26
|
+
headers: UserAgentPayload = UserAgentPayload(),
|
|
26
27
|
token: str | None = None,
|
|
27
|
-
|
|
28
|
+
send_fake_telemetry: bool = True,
|
|
29
|
+
host: str = "...",
|
|
30
|
+
port: int = ...,
|
|
31
|
+
proxy: str | Literal[True] | None = None,
|
|
32
|
+
work_dir: str = ".",
|
|
33
|
+
registration: bool = False,
|
|
34
|
+
first_name: str = "",
|
|
35
|
+
last_name: str | None = None,
|
|
36
|
+
logger: logging.Logger | None = None,
|
|
28
37
|
reconnect: bool = True,
|
|
29
|
-
reconnect_delay: float =
|
|
30
|
-
...
|
|
38
|
+
reconnect_delay: float = 1.0,
|
|
31
39
|
)
|
|
32
40
|
```
|
|
33
41
|
|
|
@@ -37,9 +45,18 @@ MaxClient(
|
|
|
37
45
|
|----------|-----|---------|
|
|
38
46
|
| `phone` | `str` | Номер телефона для авторизации (обязательно) |
|
|
39
47
|
| `uri` | `str` | URI WebSocket сервера |
|
|
48
|
+
| `headers` | `UserAgentPayload` | Заголовки User-Agent для подключения |
|
|
40
49
|
| `token` | `str | None` | Токен для восстановления сессии |
|
|
41
|
-
| `
|
|
42
|
-
| `
|
|
50
|
+
| `send_fake_telemetry` | `bool` | Отправлять ли фейковую телеметрию (по умолчанию True) |
|
|
51
|
+
| `host` | `str` | Хост API сервера |
|
|
52
|
+
| `port` | `int` | Порт API сервера |
|
|
53
|
+
| `proxy` | `str | Literal[True] | None` | Прокси для WebSocket подключения |
|
|
54
|
+
| `work_dir` | `str` | Директория для хранения БД сессии |
|
|
55
|
+
| `registration` | `bool` | Регистрировать ли новый аккаунт |
|
|
56
|
+
| `first_name` | `str` | Имя для регистрации (если registration=True) |
|
|
57
|
+
| `last_name` | `str | None` | Фамилия для регистрации |
|
|
58
|
+
| `logger` | `logging.Logger | None` | Пользовательский логгер |
|
|
59
|
+
| `reconnect` | `bool` | Автоматическое переподключение при разрыве |
|
|
43
60
|
| `reconnect_delay` | `float` | Задержка переподключения в секундах |
|
|
44
61
|
|
|
45
62
|
#### Основные методы
|
|
@@ -61,6 +78,54 @@ await client.start()
|
|
|
61
78
|
await client.close()
|
|
62
79
|
```
|
|
63
80
|
|
|
81
|
+
##### async get_chats(chat_ids: list[int]) -> list[Chat]
|
|
82
|
+
|
|
83
|
+
Получает информацию о нескольких чатах по их ID.
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
chats = await client.get_chats([123, 456])
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
##### async get_chat(chat_id: int) -> Chat
|
|
90
|
+
|
|
91
|
+
Получает информацию об одном чате по его ID.
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
chat = await client.get_chat(123)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
##### async create_folder(title: str, chat_include: list[int], filters: list[Any] | None = None) -> FolderUpdate
|
|
98
|
+
|
|
99
|
+
Создаёт новую папку (фильтр) и возвращает результат операции.
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
res = await client.create_folder(title="Friends", chat_include=[111,222])
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
##### async get_folders(folder_sync: int = 0) -> FolderList
|
|
106
|
+
|
|
107
|
+
Возвращает список папок текущего пользователя.
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
folders = await client.get_folders()
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
##### async update_folder(folder_id: str, title: str, chat_include: list[int] | None = None, filters: list[Any] | None = None, options: list[Any] | None = None) -> FolderUpdate
|
|
114
|
+
|
|
115
|
+
Обновляет существующую папку.
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
updated = await client.update_folder(folder_id=res.folder.id, title="Best")
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
##### async delete_folder(folder_id: str) -> FolderUpdate
|
|
122
|
+
|
|
123
|
+
Удаляет папку и возвращает информацию об обновлении порядка папок.
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
await client.delete_folder(folder_id=res.folder.id)
|
|
127
|
+
```
|
|
128
|
+
|
|
64
129
|
#### Свойства
|
|
65
130
|
|
|
66
131
|
| Свойство | Тип | Описание |
|
|
@@ -85,6 +150,46 @@ async def handle_message(msg: Message):
|
|
|
85
150
|
print(f"Сообщение от {msg.sender}: {msg.text}")
|
|
86
151
|
```
|
|
87
152
|
|
|
153
|
+
##### @on_message_edit(filter: Filter | None = None)
|
|
154
|
+
|
|
155
|
+
Регистрирует обработчик редактированных сообщений.
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
@client.on_message_edit()
|
|
159
|
+
async def handle_edited(msg: Message):
|
|
160
|
+
print(f"Сообщение {msg.id} отредактировано")
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
##### @on_message_delete(filter: Filter | None = None)
|
|
164
|
+
|
|
165
|
+
Регистрирует обработчик удаленных сообщений.
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
@client.on_message_delete()
|
|
169
|
+
async def handle_deleted(msg: Message):
|
|
170
|
+
print(f"Сообщение {msg.id} удалено")
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
##### @on_reaction_change
|
|
174
|
+
|
|
175
|
+
Регистрирует обработчик изменения реакций.
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
@client.on_reaction_change
|
|
179
|
+
async def handle_reaction(reaction: str, message_id: int, info: ReactionInfo):
|
|
180
|
+
print(f"Реакция: {reaction}")
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
##### @on_chat_update
|
|
184
|
+
|
|
185
|
+
Регистрирует обработчик обновлений чата.
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
@client.on_chat_update
|
|
189
|
+
async def handle_chat_update(chat: Chat):
|
|
190
|
+
print(f"Чат {chat.id} обновлен")
|
|
191
|
+
```
|
|
192
|
+
|
|
88
193
|
##### @on_start()
|
|
89
194
|
|
|
90
195
|
Регистрирует обработчик события запуска клиента.
|
|
@@ -119,7 +224,8 @@ client = SocketMaxClient(phone="+1234567890")
|
|
|
119
224
|
| `phone` | `str` | Номер телефона |
|
|
120
225
|
| `names` | `list[Names]` | Список имен профиля |
|
|
121
226
|
| `account_status` | `int` | Код статуса аккаунта |
|
|
122
|
-
| `
|
|
227
|
+
| `update_time` | `int` | Время последнего обновления профиля |
|
|
228
|
+
| `options` | `list[str] | None` | Дополнительные параметры |
|
|
123
229
|
|
|
124
230
|
### User
|
|
125
231
|
|
|
@@ -132,8 +238,16 @@ client = SocketMaxClient(phone="+1234567890")
|
|
|
132
238
|
| `id` | `int` | ID пользователя |
|
|
133
239
|
| `names` | `list[Names]` | Список имен |
|
|
134
240
|
| `account_status` | `int` | Статус аккаунта |
|
|
241
|
+
| `update_time` | `int` | Время обновления профиля |
|
|
242
|
+
| `options` | `list[str] | None` | Опции |
|
|
243
|
+
| `base_url` | `str | None` | URL профиля |
|
|
244
|
+
| `base_raw_url` | `str | None` | Внутренний URL профиля |
|
|
135
245
|
| `photo_id` | `int | None` | ID фото профиля |
|
|
136
246
|
| `description` | `str | None` | Биография/описание |
|
|
247
|
+
| `gender` | `int | None` | Пол пользователя |
|
|
248
|
+
| `link` | `str | None` | Ссылка на профиль |
|
|
249
|
+
| `web_app` | `str | None` | URL веб-приложения пользователя |
|
|
250
|
+
| `menu_button` | `dict[str, Any] | None` | Конфигурация меню-кнопки |
|
|
137
251
|
|
|
138
252
|
### Message
|
|
139
253
|
|
|
@@ -149,9 +263,68 @@ client = SocketMaxClient(phone="+1234567890")
|
|
|
149
263
|
| `text` | `str` | Текст сообщения |
|
|
150
264
|
| `time` | `int` | Unix timestamp |
|
|
151
265
|
| `type` | `MessageType | str` | Тип сообщения |
|
|
152
|
-
| `
|
|
266
|
+
| `elements` | `list[Element] | None` | Элементы форматирования |
|
|
267
|
+
| `attaches` | `list[PhotoAttach | VideoAttach | FileAttach | StickerAttach | AudioAttach | ControlAttach] | None` | Вложенные файлы/медиа |
|
|
268
|
+
| `status` | `MessageStatus | None` | Статус сообщения |
|
|
153
269
|
| `reaction_info` | `ReactionInfo | None` | Данные реакций |
|
|
154
|
-
| `
|
|
270
|
+
| `link` | `MessageLink | None` | Связанное сообщение |
|
|
271
|
+
| `options` | `int | None` | Опции сообщения |
|
|
272
|
+
|
|
273
|
+
### MessageLink
|
|
274
|
+
|
|
275
|
+
Связь на сообщение в другом чате/диалоге.
|
|
276
|
+
|
|
277
|
+
**Свойства:**
|
|
278
|
+
|
|
279
|
+
| Свойство | Тип | Описание |
|
|
280
|
+
|----------|-----|---------|
|
|
281
|
+
| `chat_id` | `int` | ID чата |
|
|
282
|
+
| `message` | `Message` | Объект сообщения |
|
|
283
|
+
| `type` | `str` | Тип ссылки |
|
|
284
|
+
|
|
285
|
+
### ReactionCounter
|
|
286
|
+
|
|
287
|
+
Счётчик конкретной реакции.
|
|
288
|
+
|
|
289
|
+
**Свойства:**
|
|
290
|
+
|
|
291
|
+
| Свойство | Тип | Описание |
|
|
292
|
+
|----------|-----|---------|
|
|
293
|
+
| `count` | `int` | Количество реакций |
|
|
294
|
+
| `reaction` | `str` | Символ/тип реакции |
|
|
295
|
+
|
|
296
|
+
### Presence
|
|
297
|
+
|
|
298
|
+
Информация о присутствии пользователя.
|
|
299
|
+
|
|
300
|
+
**Свойства:**
|
|
301
|
+
|
|
302
|
+
| Свойство | Тип | Описание |
|
|
303
|
+
|----------|-----|---------|
|
|
304
|
+
| `seen` | `int | None` | Временная метка последнего посещения |
|
|
305
|
+
|
|
306
|
+
### FileRequest
|
|
307
|
+
|
|
308
|
+
Запрос файла (метаданные).
|
|
309
|
+
|
|
310
|
+
**Свойства:**
|
|
311
|
+
|
|
312
|
+
| Свойство | Тип | Описание |
|
|
313
|
+
|----------|-----|---------|
|
|
314
|
+
| `unsafe` | `bool` | Небезопасен ли файл |
|
|
315
|
+
| `url` | `str` | Ссылка на файл |
|
|
316
|
+
|
|
317
|
+
### VideoRequest
|
|
318
|
+
|
|
319
|
+
Запрос видео (метаданные).
|
|
320
|
+
|
|
321
|
+
**Свойства:**
|
|
322
|
+
|
|
323
|
+
| Свойство | Тип | Описание |
|
|
324
|
+
|----------|-----|---------|
|
|
325
|
+
| `external` | `str` | Внешний источник video |
|
|
326
|
+
| `cache` | `bool` | Использовать кеш |
|
|
327
|
+
| `url` | `str` | Ссылка на видео |
|
|
155
328
|
|
|
156
329
|
### Chat
|
|
157
330
|
|
|
@@ -165,10 +338,68 @@ client = SocketMaxClient(phone="+1234567890")
|
|
|
165
338
|
| `type` | `ChatType | str` | Тип: DIALOG, CHAT, CHANNEL |
|
|
166
339
|
| `title` | `str | None` | Название чата |
|
|
167
340
|
| `owner` | `int` | ID владельца |
|
|
341
|
+
| `access` | `AccessType | str` | Тип доступа (PUBLIC, PRIVATE, SECRET) |
|
|
168
342
|
| `participants_count` | `int` | Количество участников |
|
|
169
343
|
| `admins` | `list[int]` | Список ID администраторов |
|
|
170
344
|
| `description` | `str | None` | Описание чата |
|
|
171
|
-
| `
|
|
345
|
+
| `link` | `str | None` | Ссылка-приглашение |
|
|
346
|
+
| `base_icon_url` | `str | None` | URL иконки чата |
|
|
347
|
+
| `base_raw_icon_url` | `str | None` | Внутренний URL иконки |
|
|
348
|
+
| `cid` | `int` | Внутренний CID чата |
|
|
349
|
+
| `created` | `int` | Время создания чата |
|
|
350
|
+
| `join_time` | `int` | Время присоединения |
|
|
351
|
+
| `last_message` | `Message | None` | Последнее сообщение |
|
|
352
|
+
| `last_event_time` | `int` | Время последнего события |
|
|
353
|
+
| `last_delayed_update_time` | `int` | Время последнего отложенного обновления |
|
|
354
|
+
| `last_fire_delayed_error_time` | `int` | Время последней отложенной ошибки |
|
|
355
|
+
| `messages_count` | `int` | Количество сообщений |
|
|
356
|
+
| `modified` | `int` | Время последнего изменения |
|
|
357
|
+
| `admin_participants` | `dict[int, dict[Any, Any]]` | Структура администраторов |
|
|
358
|
+
| `options` | `dict[str, bool]` | Опции чата |
|
|
359
|
+
| `prev_message_id` | `str | None` | ID предыдущего сообщения |
|
|
360
|
+
| `restrictions` | `int | None` | Ограничения в чате |
|
|
361
|
+
| `status` | `str` | Статус чата |
|
|
362
|
+
|
|
363
|
+
### Folder
|
|
364
|
+
|
|
365
|
+
Папка (фильтр для чатов пользователя).
|
|
366
|
+
|
|
367
|
+
**Свойства:**
|
|
368
|
+
|
|
369
|
+
| Свойство | Тип | Описание |
|
|
370
|
+
|----------|-----|---------|
|
|
371
|
+
| `source_id` | `int` | ID источника папки |
|
|
372
|
+
| `include` | `list[int]` | Список ID чатов, включённых в папку |
|
|
373
|
+
| `options` | `list[Any]` | Опции папки |
|
|
374
|
+
| `update_time` | `int` | Время последнего обновления папки |
|
|
375
|
+
| `id` | `str` | Уникальный ID папки |
|
|
376
|
+
| `filters` | `list[Any]` | Правила/фильтры папки |
|
|
377
|
+
| `title` | `str` | Название папки |
|
|
378
|
+
|
|
379
|
+
### FolderUpdate
|
|
380
|
+
|
|
381
|
+
Результат операций обновления/создания/удаления папки.
|
|
382
|
+
|
|
383
|
+
**Свойства:**
|
|
384
|
+
|
|
385
|
+
| Свойство | Тип | Описание |
|
|
386
|
+
|----------|-----|---------|
|
|
387
|
+
| `folder_order` | `list[str] | None` | Порядок ID папок после операции |
|
|
388
|
+
| `folder` | `Folder | None` | Обновлённый объект папки, если присутствует |
|
|
389
|
+
| `folder_sync` | `int` | Синхронизационный маркер папок |
|
|
390
|
+
|
|
391
|
+
### FolderList
|
|
392
|
+
|
|
393
|
+
Список папок пользователя.
|
|
394
|
+
|
|
395
|
+
**Свойства:**
|
|
396
|
+
|
|
397
|
+
| Свойство | Тип | Описание |
|
|
398
|
+
|----------|-----|---------|
|
|
399
|
+
| `folders_order` | `list[str]` | Порядок ID папок |
|
|
400
|
+
| `folders` | `list[Folder]` | Список объектов `Folder` |
|
|
401
|
+
| `folder_sync` | `int` | Синхронизационный маркер |
|
|
402
|
+
| `all_filter_exclude_folders` | `list[Any] | None` | Исключённые папки для фильтров |
|
|
172
403
|
|
|
173
404
|
### Dialog
|
|
174
405
|
|
|
@@ -182,6 +413,18 @@ client = SocketMaxClient(phone="+1234567890")
|
|
|
182
413
|
| `owner` | `int` | ID собеседника |
|
|
183
414
|
| `type` | `ChatType` | Всегда `ChatType.DIALOG` |
|
|
184
415
|
| `last_message` | `Message | None` | Последнее сообщение |
|
|
416
|
+
| `cid` | `int | None` | Внутренний CID диалога |
|
|
417
|
+
| `has_bots` | `bool | None` | Наличие ботов в диалоге |
|
|
418
|
+
| `join_time` | `int` | Время присоединения |
|
|
419
|
+
| `created` | `int` | Время создания |
|
|
420
|
+
| `last_fire_delayed_error_time` | `int` | Время последней отложенной ошибки |
|
|
421
|
+
| `last_delayed_update_time` | `int` | Время последнего отложенного обновления |
|
|
422
|
+
| `prev_message_id` | `str | None` | ID предыдущего сообщения |
|
|
423
|
+
| `options` | `dict` | Опции диалога |
|
|
424
|
+
| `modified` | `int` | Время последнего изменения |
|
|
425
|
+
| `last_event_time` | `int` | Время последнего события |
|
|
426
|
+
| `participants` | `dict[str, int]` | Список участников |
|
|
427
|
+
| `status` | `str` | Статус диалога |
|
|
185
428
|
|
|
186
429
|
### Channel
|
|
187
430
|
|
|
@@ -197,8 +440,12 @@ client = SocketMaxClient(phone="+1234567890")
|
|
|
197
440
|
|----------|-----|---------|
|
|
198
441
|
| `id` | `int` | ID контакта |
|
|
199
442
|
| `names` | `list[Names]` | Имена контакта |
|
|
200
|
-
| `
|
|
201
|
-
| `
|
|
443
|
+
| `account_status` | `int` | Код статуса |
|
|
444
|
+
| `photo_id` | `int | None` | ID фото контакта |
|
|
445
|
+
| `base_url` | `str | None` | URL для изображений |
|
|
446
|
+
| `base_raw_url` | `str | None` | Внутренний URL для изображений |
|
|
447
|
+
| `options` | `list[str] | None` | Дополнительные параметры |
|
|
448
|
+
| `update_time` | `int` | Время обновления контакта |
|
|
202
449
|
|
|
203
450
|
### Member
|
|
204
451
|
|
|
@@ -219,7 +466,7 @@ client = SocketMaxClient(phone="+1234567890")
|
|
|
219
466
|
Вложение с фотографией.
|
|
220
467
|
|
|
221
468
|
```python
|
|
222
|
-
PhotoAttach(
|
|
469
|
+
PhotoAttach(photo_id: int, base_url: str, width: int, height: int, preview_data: str | None, ...)
|
|
223
470
|
```
|
|
224
471
|
|
|
225
472
|
#### VideoAttach
|
|
@@ -243,7 +490,7 @@ FileAttach(id: int, name: str, size: int, ...)
|
|
|
243
490
|
Вложение со стикером.
|
|
244
491
|
|
|
245
492
|
```python
|
|
246
|
-
StickerAttach(
|
|
493
|
+
StickerAttach(sticker_id: int, set_id: int, ...)
|
|
247
494
|
```
|
|
248
495
|
|
|
249
496
|
#### AudioAttach
|
|
@@ -251,7 +498,7 @@ StickerAttach(id: int, sticker_id: int, ...)
|
|
|
251
498
|
Вложение с аудио/голосовым сообщением.
|
|
252
499
|
|
|
253
500
|
```python
|
|
254
|
-
AudioAttach(
|
|
501
|
+
AudioAttach(audio_id: int, duration: int, ...)
|
|
255
502
|
```
|
|
256
503
|
|
|
257
504
|
#### ControlAttach
|
|
@@ -322,7 +569,7 @@ except pymax.SocketNotConnectedError:
|
|
|
322
569
|
|
|
323
570
|
```python
|
|
324
571
|
except pymax.RateLimitError as e:
|
|
325
|
-
print(f"Лимит превышен
|
|
572
|
+
print(f"Лимит превышен")
|
|
326
573
|
```
|
|
327
574
|
|
|
328
575
|
### ResponseError
|
|
@@ -428,8 +675,6 @@ if chat.type == ChatType.DIALOG:
|
|
|
428
675
|
| `mention` | Упоминание пользователя @user |
|
|
429
676
|
| `link` | Гиперссылка |
|
|
430
677
|
| `emoji` | Эмодзи/эмотикон |
|
|
431
|
-
| `bold` | Жирное форматирование |
|
|
432
|
-
| `italic` | Курсивное форматирование |
|
|
433
678
|
|
|
434
679
|
### FormattingType
|
|
435
680
|
|
|
@@ -437,11 +682,10 @@ if chat.type == ChatType.DIALOG:
|
|
|
437
682
|
|
|
438
683
|
| Значение | Описание |
|
|
439
684
|
|----------|---------|
|
|
440
|
-
| `
|
|
441
|
-
| `
|
|
685
|
+
| `STRONG` | Жирный текст |
|
|
686
|
+
| `EMPHASIZED` | Курсив |
|
|
442
687
|
| `UNDERLINE` | Подчеркивание |
|
|
443
688
|
| `STRIKETHROUGH` | Зачеркивание |
|
|
444
|
-
| `MONOSPACE` | Моноширинный/код |
|
|
445
689
|
|
|
446
690
|
### MarkupType
|
|
447
691
|
|
|
@@ -467,14 +711,6 @@ if chat.type == ChatType.DIALOG:
|
|
|
467
711
|
|
|
468
712
|
Коды операций протокола WebSocket (150+ значений).
|
|
469
713
|
|
|
470
|
-
Коды низкоуровневого общения для внутреннего использования.
|
|
471
|
-
|
|
472
|
-
| Значение | Код | Описание |
|
|
473
|
-
|----------|-----|---------|
|
|
474
|
-
| 1 | `PING` | Проверка соединения |
|
|
475
|
-
| 2 | `PONG` | Ответ на проверку |
|
|
476
|
-
| 3 | `LOGIN` | Запрос аутентификации |
|
|
477
|
-
| 4 | `MSG_SEND` | Отправка сообщения |
|
|
478
|
-
| 5 | `MSG_READ` | Отметить сообщение прочитанным |
|
|
714
|
+
Коды низкоуровневого общения для внутреннего использования.
|
|
479
715
|
|
|
480
716
|
---
|
|
@@ -135,7 +135,6 @@ async def close() -> None
|
|
|
135
135
|
```python
|
|
136
136
|
async def main():
|
|
137
137
|
async with MaxClient(phone="+79001234567") as client:
|
|
138
|
-
await client.start()
|
|
139
138
|
# Ваш код здесь
|
|
140
139
|
# Клиент автоматически закроется
|
|
141
140
|
```
|
|
@@ -163,10 +162,10 @@ async def main():
|
|
|
163
162
|
|
|
164
163
|
!!! example "Примеры фильтров"
|
|
165
164
|
```python
|
|
166
|
-
# Только
|
|
167
|
-
@client.on_message(Filter(chat_id=
|
|
168
|
-
async def
|
|
169
|
-
print(f"
|
|
165
|
+
# Только из конкретного чата
|
|
166
|
+
@client.on_message(Filter(chat_id=123456))
|
|
167
|
+
async def handle_chat(message: Message):
|
|
168
|
+
print(f"Сообщение в чате: {message.text}")
|
|
170
169
|
```
|
|
171
170
|
|
|
172
171
|
## Работа с данными {#работа-с-данными}
|
|
@@ -197,7 +196,7 @@ async def main():
|
|
|
197
196
|
me = client.me
|
|
198
197
|
if me:
|
|
199
198
|
name = me.names[0] if me.names else None
|
|
200
|
-
print(f"Авторизован как: {name.
|
|
199
|
+
print(f"Авторизован как: {name.first_name if name else me.phone}")
|
|
201
200
|
print(f"ID: {me.id}")
|
|
202
201
|
print(f"Статус: {me.account_status}")
|
|
203
202
|
```
|
|
@@ -225,7 +224,6 @@ async def main():
|
|
|
225
224
|
```python
|
|
226
225
|
async def main():
|
|
227
226
|
async with MaxClient(phone="+79001234567") as client:
|
|
228
|
-
await client.start()
|
|
229
227
|
# Ваш код здесь
|
|
230
228
|
# Клиент автоматически закроется
|
|
231
229
|
```
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Примеры использования
|
|
2
|
+
|
|
3
|
+
Ниже — небольшие и наглядные примеры, которые можно вставить прямо в проект.
|
|
4
|
+
Все примеры используют реальные методы библиотеки (см. исходники).
|
|
5
|
+
|
|
6
|
+
## Быстрый старт: запуск клиента и обработчики
|
|
7
|
+
|
|
8
|
+
Классический пример: регистрируем обработчики и запускаем клиента через `start()`.
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
import asyncio
|
|
12
|
+
from pymax import MaxClient
|
|
13
|
+
from pymax.filters import Filter
|
|
14
|
+
from pymax.types import Message
|
|
15
|
+
|
|
16
|
+
client = MaxClient(phone="+79000000000", work_dir="cache", reconnect=False)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@client.on_start
|
|
20
|
+
async def on_start() -> None:
|
|
21
|
+
# Метаданные пользователя доступны после синхронизации
|
|
22
|
+
print("Client started, me id:", client.me.id)
|
|
23
|
+
await client.send_message("Бот запущен!", chat_id=0, notify=True)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@client.on_message(filter=Filter(chat_id=0))
|
|
27
|
+
async def on_message(message: Message) -> None:
|
|
28
|
+
print("New message:", message.text)
|
|
29
|
+
# Отправка простого ответа
|
|
30
|
+
await client.send_message(f"Echo: {message.text}", chat_id=message.chat_id, notify=False)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
if __name__ == "__main__":
|
|
34
|
+
asyncio.run(client.start())
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Контекстный менеджер и .idle()
|
|
38
|
+
|
|
39
|
+
Используем `async with` (реализован в `__aenter__/__aexit__`) и `idle()` для ожидания событий.
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
import asyncio
|
|
43
|
+
from pymax import MaxClient
|
|
44
|
+
from pymax.files import File
|
|
45
|
+
|
|
46
|
+
client = MaxClient(phone="+79000000000", work_dir="cache")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
async def run():
|
|
50
|
+
async with client:
|
|
51
|
+
# внутри блока клиент подключён и синхронизирован
|
|
52
|
+
await client.send_message("Привет от контекстного менеджера!", chat_id=0, notify=True)
|
|
53
|
+
|
|
54
|
+
# отправка файла (локальный файл)
|
|
55
|
+
file = File(path="ruff.toml")
|
|
56
|
+
await client.send_message("Вот файл", chat_id=0, notify=True, attachment=file)
|
|
57
|
+
|
|
58
|
+
# блокируемся и ждём событий
|
|
59
|
+
await client.idle()
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
if __name__ == "__main__":
|
|
63
|
+
asyncio.run(run())
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Отправка вложений и работа с историей
|
|
67
|
+
|
|
68
|
+
Короткий пример: отправляем файл/фото, получаем историю и скачиваем файл по id.
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from pymax import MaxClient, File
|
|
72
|
+
from pymax.static.enum import AttachType
|
|
73
|
+
|
|
74
|
+
client = MaxClient(phone="+79000000000")
|
|
75
|
+
|
|
76
|
+
@client.on_start
|
|
77
|
+
async def _():
|
|
78
|
+
# отправить один файл
|
|
79
|
+
f = File(path="tests/test.txt")
|
|
80
|
+
msg = await client.send_message("Файл", chat_id=0, notify=True, attachment=f)
|
|
81
|
+
if msg:
|
|
82
|
+
print("Отправлено сообщение id=", msg.id)
|
|
83
|
+
|
|
84
|
+
# получить историю и найти вложения
|
|
85
|
+
history = await client.fetch_history(chat_id=0)
|
|
86
|
+
if history:
|
|
87
|
+
for m in history:
|
|
88
|
+
if m.attaches:
|
|
89
|
+
# Пример: если в сообщении есть вложение типа FILE
|
|
90
|
+
for a in m.attaches:
|
|
91
|
+
if a.type == AttachType.FILE:
|
|
92
|
+
file_info = await client.get_file_by_id(chat_id=m.chat_id, message_id=m.id, file_id=a.file_id)
|
|
93
|
+
print("Файл для скачивания:", file_info.url)
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Кастомный login flow
|
|
98
|
+
|
|
99
|
+
Если нужно реализовать кастомный вход (без автоматического интерфейса), используйте `request_code` и `login_with_code`.
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
import asyncio
|
|
103
|
+
from pymax import MaxClient
|
|
104
|
+
|
|
105
|
+
phone = "+79000000000"
|
|
106
|
+
client = MaxClient(phone=phone, work_dir="cache", reconnect=False)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
async def login_flow_test():
|
|
110
|
+
# Подключение к WS для отправки запроса к API
|
|
111
|
+
await client.connect()
|
|
112
|
+
|
|
113
|
+
# Запрашиваем временный токен (в сервис уходит SMS с кодом)
|
|
114
|
+
temp_token = await client.request_code(phone)
|
|
115
|
+
|
|
116
|
+
# Вводим код вручную
|
|
117
|
+
code = input("Введите код: ").strip()
|
|
118
|
+
|
|
119
|
+
# Отправляем код и сохраняем токен. start=False — не запускать пост-логин задачи автоматически
|
|
120
|
+
await client.login_with_code(temp_token, code, start=False)
|
|
121
|
+
|
|
122
|
+
# Токен сохранён в БД, теперь можно запустить обычный старт клиента
|
|
123
|
+
await client.start()
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
if __name__ == "__main__":
|
|
127
|
+
asyncio.run(login_flow_test())
|
|
128
|
+
```
|
|
129
|
+
## Короткие полезные примеры
|
|
130
|
+
|
|
131
|
+
Ниже — ещё пара компактных сценариев, которые удобно вставлять прямо в проект.
|
|
132
|
+
|
|
133
|
+
### Редактирование и закрепление сообщения
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from pymax import MaxClient
|
|
137
|
+
from pymax.filters import Filter
|
|
138
|
+
from pymax.types import Message
|
|
139
|
+
|
|
140
|
+
client = MaxClient(phone="+79000000000")
|
|
141
|
+
|
|
142
|
+
@client.on_message(filter=Filter(chat_id=0))
|
|
143
|
+
async def edit_and_pin(message: Message) -> None:
|
|
144
|
+
# Обновляем текст
|
|
145
|
+
await client.edit_message(chat_id=message.chat_id, message_id=message.id, text="Обновлённый текст")
|
|
146
|
+
# Закрепляем сообщение
|
|
147
|
+
await client.pin_message(chat_id=message.chat_id, message_id=message.id, notify_pin=True)
|
|
148
|
+
|
|
149
|
+
```
|
|
@@ -12,9 +12,11 @@ async def main():
|
|
|
12
12
|
|
|
13
13
|
@client.on_message()
|
|
14
14
|
async def handle_message(message):
|
|
15
|
+
user = await client.get_user(message.sender)
|
|
16
|
+
user_name = user.names[0].first_name if user and user.names else "User"
|
|
15
17
|
await client.send_message(
|
|
16
18
|
chat_id=message.chat_id,
|
|
17
|
-
text=f"Привет, {
|
|
19
|
+
text=f"Привет, {user_name}! {message.text}"
|
|
18
20
|
)
|
|
19
21
|
|
|
20
22
|
await client.start()
|
|
@@ -39,5 +41,5 @@ uv add -U maxapi-python
|
|
|
39
41
|
## Ссылки
|
|
40
42
|
|
|
41
43
|
- [GitHub](https://github.com/ink-developer/PyMax)
|
|
42
|
-
- [PyPI](https://pypi.org/project/
|
|
44
|
+
- [PyPI](https://pypi.org/project/maxapi-python/)
|
|
43
45
|
- [Issues](https://github.com/ink-developer/PyMax/issues)
|