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.
Files changed (57) hide show
  1. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/PKG-INFO +1 -1
  2. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/docs/api.md +266 -30
  3. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/docs/client.md +5 -7
  4. maxapi_python-1.1.20/docs/examples.md +149 -0
  5. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/docs/index.md +4 -2
  6. maxapi_python-1.1.20/docs/methods.md +876 -0
  7. maxapi_python-1.1.20/docs/types.md +512 -0
  8. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/examples/example.py +55 -18
  9. maxapi_python-1.1.20/examples/reg.py +13 -0
  10. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/examples/telegram_bridge.py +1 -1
  11. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/pyproject.toml +1 -1
  12. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/core.py +58 -7
  13. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/files.py +15 -12
  14. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/interfaces.py +9 -5
  15. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/auth.py +1 -1
  16. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/channel.py +6 -6
  17. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/group.py +60 -0
  18. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/handler.py +2 -1
  19. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/message.py +89 -12
  20. maxapi_python-1.1.20/src/pymax/mixins/self.py +155 -0
  21. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/socket.py +53 -26
  22. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/websocket.py +10 -1
  23. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/payloads.py +36 -3
  24. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/static/enum.py +0 -1
  25. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/types.py +114 -2
  26. maxapi_python-1.1.19/docs/examples.md +0 -418
  27. maxapi_python-1.1.19/docs/methods.md +0 -499
  28. maxapi_python-1.1.19/docs/types.md +0 -314
  29. maxapi_python-1.1.19/src/pymax/mixins/self.py +0 -41
  30. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/.github/FUNDING.yml +0 -0
  31. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  32. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  33. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/.github/ISSUE_TEMPLATE/refactor.md +0 -0
  34. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/.github/pull_request_template.md +0 -0
  35. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/.github/workflows/publish.yml +0 -0
  36. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/.gitignore +0 -0
  37. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/.pre-commit-config.yaml +0 -0
  38. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/LICENSE +0 -0
  39. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/README.md +0 -0
  40. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/assets/icon.svg +0 -0
  41. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/assets/logo.svg +0 -0
  42. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/docs/assets/icon.svg +0 -0
  43. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/mkdocs.yml +0 -0
  44. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/ruff.toml +0 -0
  45. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/__init__.py +0 -0
  46. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/crud.py +0 -0
  47. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/exceptions.py +0 -0
  48. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/filters.py +0 -0
  49. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/formatter.py +0 -0
  50. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/formatting.py +0 -0
  51. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/__init__.py +0 -0
  52. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/telemetry.py +0 -0
  53. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/user.py +0 -0
  54. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/mixins/utils.py +0 -0
  55. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/models.py +0 -0
  56. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/navigation.py +0 -0
  57. {maxapi_python-1.1.19 → maxapi_python-1.1.20}/src/pymax/static/constant.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maxapi-python
3
- Version: 1.1.19
3
+ Version: 1.1.20
4
4
  Summary: Python wrapper для API мессенджера Max
5
5
  Project-URL: Homepage, https://github.com/ink-developer/PyMax
6
6
  Project-URL: Repository, https://github.com/ink-developer/PyMax
@@ -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
- work_dir: str = "...",
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 = 5.0,
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
- | `work_dir` | `str` | Директория для БД сессии |
42
- | `reconnect` | `bool` | Включить автоматическое переподключение |
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
- | `options` | `dict` | Дополнительные параметры |
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
- | `attaches` | `list` | Вложенные файлы/медиа |
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
- | `edit_time` | `int | None` | Время редактирования |
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
- | `rules` | `str | None` | Правила чата |
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
- | `status` | `int` | Код статуса |
201
- | `photos` | `list` | Фотографии контакта |
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(id: int, width: int, height: int, ...)
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(id: int, sticker_id: int, ...)
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(id: int, duration: int, ...)
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"Лимит превышен на {e.retry_after} секунд")
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
- | `BOLD` | Жирный текст |
441
- | `ITALIC` | Курсив |
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=0))
168
- async def handle_text(message: Message):
169
- print(f"Текст: {message.text}")
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.name if name else me.phone}")
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"Привет, {message.author.username}! {message.text}"
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/pymax/)
44
+ - [PyPI](https://pypi.org/project/maxapi-python/)
43
45
  - [Issues](https://github.com/ink-developer/PyMax/issues)