maxapi-python 2.0.1__tar.gz → 2.1.1__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-2.0.1 → maxapi_python-2.1.1}/.github/workflows/publish.yml +31 -1
- maxapi_python-2.1.1/.pre-commit-config.yaml +14 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/PKG-INFO +4 -1
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/README.md +3 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/account.rst +15 -10
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/index.rst +7 -0
- maxapi_python-2.1.1/docs/release-2-1-0.rst +43 -0
- maxapi_python-2.1.1/docs/release-2-1-1.rst +16 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/pyproject.toml +17 -15
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/__init__.py +1 -1
- maxapi_python-2.1.1/src/pymax/api/auth/enums.py +28 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/auth/payloads.py +10 -6
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/auth/service.py +75 -12
- maxapi_python-2.1.1/src/pymax/api/bots/__init__.py +1 -0
- maxapi_python-2.1.1/src/pymax/api/bots/payloads.py +7 -0
- maxapi_python-2.1.1/src/pymax/api/bots/service.py +35 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/chats/enums.py +1 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/chats/payloads.py +14 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/chats/service.py +112 -12
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/facade.py +2 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/messages/payloads.py +5 -1
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/messages/service.py +36 -11
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/self/service.py +29 -10
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/session/payloads.py +9 -2
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/uploads/models.py +1 -4
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/uploads/payloads.py +9 -3
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/uploads/service.py +107 -37
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/users/service.py +15 -5
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/app.py +19 -5
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/auth/qr.py +11 -6
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/auth/sms.py +13 -4
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/base.py +1 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/client.py +4 -1
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/client_web.py +4 -2
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/config.py +11 -3
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/connection/connection.py +15 -5
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/connection/readers/tcp.py +4 -2
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/dispatch/dispatcher.py +28 -10
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/dispatch/mapping.py +9 -2
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/dispatch/router.py +2 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/files/base.py +6 -1
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/formatting/markdown.py +4 -1
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/infra/auth.py +42 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/infra/base.py +2 -0
- maxapi_python-2.1.1/src/pymax/infra/bots.py +33 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/infra/chat.py +102 -1
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/infra/self.py +2 -6
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/protocol/tcp/compression.py +3 -1
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/protocol/tcp/framing.py +6 -11
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/protocol/tcp/payload.py +3 -2
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/protocol/tcp/protocol.py +13 -3
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/protocol/ws/protocol.py +9 -3
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/session/protocol.py +6 -2
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/session/store.py +24 -8
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/telemetry/navigation.py +3 -1
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/telemetry/service.py +9 -3
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/transport/tcp.py +14 -6
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/transport/websocket.py +0 -2
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/__init__.py +3 -0
- maxapi_python-2.1.1/src/pymax/types/domain/bots.py +14 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/error.py +3 -3
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/folder.py +1 -1
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/login.py +18 -6
- maxapi_python-2.1.1/src/pymax/types/domain/member.py +16 -0
- maxapi_python-2.1.1/src/pymax/types/domain/presence.py +15 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/sync.py +21 -5
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/user.py +12 -0
- maxapi_python-2.1.1/tests/__init__.py +1 -0
- maxapi_python-2.1.1/tests/api/test_auth_service.py +246 -0
- maxapi_python-2.1.1/tests/api/test_chat_user_self_session_services.py +397 -0
- maxapi_python-2.1.1/tests/api/test_message_service.py +209 -0
- maxapi_python-2.1.1/tests/api/test_upload_service.py +188 -0
- maxapi_python-2.1.1/tests/app/test_app_runtime.py +152 -0
- maxapi_python-2.1.1/tests/auth/test_auth_flows.py +161 -0
- maxapi_python-2.1.1/tests/conftest.py +255 -0
- maxapi_python-2.1.1/tests/connection/test_connection.py +165 -0
- maxapi_python-2.1.1/tests/connection/test_readers_and_transports.py +193 -0
- maxapi_python-2.1.1/tests/dispatch/test_dispatcher.py +102 -0
- maxapi_python-2.1.1/tests/domain/test_bound_models.py +173 -0
- maxapi_python-2.1.1/tests/files/test_files_and_formatting.py +63 -0
- maxapi_python-2.1.1/tests/protocol/test_protocols.py +139 -0
- maxapi_python-2.1.1/tests/session/test_store.py +48 -0
- maxapi_python-2.1.1/tests/telemetry/test_telemetry.py +146 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/uv.lock +170 -165
- maxapi_python-2.0.1/src/pymax/api/auth/enums.py +0 -17
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/.github/ISSUE_TEMPLATE/refactor.md +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/.github/pull_request_template.md +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/.gitignore +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/LICENSE +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/_static/.gitkeep +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/api/auth.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/api/client.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/api/files.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/api/router.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/auth.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/chats.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/client.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/conf.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/examples.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/faq.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/files.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/formatting.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/getting-started.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/messages.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/router.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/troubleshooting.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/audio_attachment.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/call_attachment.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/chat.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/contact_attachment.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/control_attachment.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/element.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/enums.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/file_attachment.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/folder.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/folder_list.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/folder_update.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/index.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/inline_keyboard_attachment.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/message.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/message_delete_event.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/name.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/photo_attachment.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/profile.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/reaction_counter.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/reaction_info.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/read_state.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/session.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/share_attachment.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/sticker_attachment.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/sync_overrides.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/sync_state.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/user.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/types/video_attachment.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/docs/users.rst +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/auth/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/auth/types.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/chats/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/messages/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/messages/enums.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/models.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/response.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/self/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/self/enums.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/self/payloads.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/session/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/session/enums.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/session/service.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/uploads/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/users/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/users/enums.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/api/users/payloads.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/auth/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/auth/base.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/auth/email.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/auth/models.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/auth/providers.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/auth/service.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/connection/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/connection/pending.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/connection/readers/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/connection/readers/base.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/connection/readers/ws.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/dispatch/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/dispatch/enums.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/dispatch/resolvers.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/exceptions.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/files/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/files/file.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/files/photo.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/files/static.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/files/video.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/formatting/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/infra/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/infra/message.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/infra/protocol.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/infra/user.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/logging.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/protocol/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/protocol/base.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/protocol/enums.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/protocol/models.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/protocol/tcp/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/protocol/ws/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/py.typed +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/routers.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/session/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/session/models.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/telemetry/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/telemetry/payloads.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/transport/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/transport/base.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/attachments/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/attachments/audio.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/attachments/call.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/attachments/contact.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/attachments/control.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/attachments/enums.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/attachments/file.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/attachments/keyboards/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/attachments/keyboards/inline.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/attachments/photo.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/attachments/share.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/attachments/sticker.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/attachments/video.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/auth.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/base.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/chat.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/element.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/enums.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/message.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/name.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/profile.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/domain/session.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/events/__init__.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/events/file.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/events/message.py +0 -0
- {maxapi_python-2.0.1 → maxapi_python-2.1.1}/src/pymax/types/events/video.py +0 -0
|
@@ -9,22 +9,52 @@ permissions:
|
|
|
9
9
|
contents: read
|
|
10
10
|
|
|
11
11
|
jobs:
|
|
12
|
+
release-checks:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
with:
|
|
18
|
+
persist-credentials: false
|
|
19
|
+
|
|
20
|
+
- name: Set up uv
|
|
21
|
+
uses: astral-sh/setup-uv@v4
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.10"
|
|
24
|
+
enable-cache: true
|
|
25
|
+
|
|
26
|
+
- name: Check lint
|
|
27
|
+
run: uv run ruff check src tests
|
|
28
|
+
|
|
29
|
+
- name: Check formatting
|
|
30
|
+
run: uv run ruff format --check src tests
|
|
31
|
+
|
|
32
|
+
- name: Run tests
|
|
33
|
+
run: uv run pytest
|
|
34
|
+
|
|
35
|
+
- name: Build docs
|
|
36
|
+
run: uv run sphinx-build -b html docs /tmp/pymax-docs
|
|
37
|
+
|
|
12
38
|
release-build:
|
|
13
39
|
runs-on: ubuntu-latest
|
|
40
|
+
needs: release-checks
|
|
14
41
|
|
|
15
42
|
steps:
|
|
16
43
|
- uses: actions/checkout@v4
|
|
44
|
+
with:
|
|
45
|
+
persist-credentials: false
|
|
17
46
|
|
|
18
47
|
- name: Set up uv
|
|
19
48
|
uses: astral-sh/setup-uv@v4
|
|
20
49
|
with:
|
|
21
50
|
python-version: "3.10"
|
|
51
|
+
enable-cache: true
|
|
22
52
|
|
|
23
53
|
- name: Build release distributions
|
|
24
54
|
run: uv build
|
|
25
55
|
|
|
26
56
|
- name: Check distributions
|
|
27
|
-
run:
|
|
57
|
+
run: uv run twine check dist/*
|
|
28
58
|
|
|
29
59
|
- name: Upload distributions
|
|
30
60
|
uses: actions/upload-artifact@v4
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: local
|
|
3
|
+
hooks:
|
|
4
|
+
- id: ruff-check
|
|
5
|
+
name: ruff check
|
|
6
|
+
entry: uv run ruff check --fix
|
|
7
|
+
language: system
|
|
8
|
+
types_or: [python, pyi]
|
|
9
|
+
|
|
10
|
+
- id: ruff-format
|
|
11
|
+
name: ruff format
|
|
12
|
+
entry: uv run ruff format
|
|
13
|
+
language: system
|
|
14
|
+
types_or: [python, pyi]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maxapi-python
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.1.1
|
|
4
4
|
Summary: Python wrapper для API мессенджера Max
|
|
5
5
|
Project-URL: Homepage, https://github.com/MaxApiTeam/PyMax
|
|
6
6
|
Project-URL: Repository, https://github.com/MaxApiTeam/PyMax
|
|
@@ -196,6 +196,9 @@ client.include_router(router)
|
|
|
196
196
|
|
|
197
197
|
```bash
|
|
198
198
|
uv sync --all-groups
|
|
199
|
+
uv run pre-commit install
|
|
200
|
+
uv run pre-commit run --all-files
|
|
201
|
+
uv run pytest
|
|
199
202
|
uv run python -c "import pymax; print(pymax.__all__)"
|
|
200
203
|
uv run sphinx-build -b html docs docs/_build/html
|
|
201
204
|
```
|
|
@@ -153,6 +153,9 @@ client.include_router(router)
|
|
|
153
153
|
|
|
154
154
|
```bash
|
|
155
155
|
uv sync --all-groups
|
|
156
|
+
uv run pre-commit install
|
|
157
|
+
uv run pre-commit run --all-files
|
|
158
|
+
uv run pytest
|
|
156
159
|
uv run python -c "import pymax; print(pymax.__all__)"
|
|
157
160
|
uv run sphinx-build -b html docs docs/_build/html
|
|
158
161
|
```
|
|
@@ -32,21 +32,26 @@ Account
|
|
|
32
32
|
Фотография профиля
|
|
33
33
|
------------------
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
Передайте ``Photo`` в ``change_profile(photo=...)``, чтобы PyMax сам загрузил
|
|
36
|
+
файл и применил новый токен фотографии:
|
|
37
37
|
|
|
38
38
|
.. code-block:: python
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
print(upload_url)
|
|
40
|
+
from pymax import Photo
|
|
42
41
|
|
|
43
42
|
await client.change_profile(
|
|
44
43
|
first_name="Alex",
|
|
45
|
-
|
|
44
|
+
photo=Photo(path="avatar.jpg"),
|
|
46
45
|
)
|
|
47
46
|
|
|
48
|
-
Если
|
|
49
|
-
|
|
47
|
+
Если у вас уже есть токен фотографии от API Max, его можно передать напрямую:
|
|
48
|
+
|
|
49
|
+
.. code-block:: python
|
|
50
|
+
|
|
51
|
+
await client.change_profile(
|
|
52
|
+
first_name="Alex",
|
|
53
|
+
photo_token="PHOTO_TOKEN",
|
|
54
|
+
)
|
|
50
55
|
|
|
51
56
|
Папки чатов
|
|
52
57
|
-----------
|
|
@@ -118,9 +123,9 @@ Account
|
|
|
118
123
|
``on_start`` или после успешного ``await client.start()`` в собственном
|
|
119
124
|
lifecycle.
|
|
120
125
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
126
|
+
Фото профиля не обновилось
|
|
127
|
+
Если переданы и ``photo``, и ``photo_token``, PyMax загрузит ``photo`` и
|
|
128
|
+
использует новый токен загруженной фотографии.
|
|
124
129
|
|
|
125
130
|
Папка создалась, но список старый
|
|
126
131
|
Используйте ``get_folders()`` после изменения и сохраняйте новый
|
|
@@ -18,6 +18,13 @@ PyMax - асинхронная Python-библиотека для Max API. Он
|
|
|
18
18
|
минимальный рабочий пример с авторизацией, обработчиком сообщений и запуском
|
|
19
19
|
клиента.
|
|
20
20
|
|
|
21
|
+
.. toctree::
|
|
22
|
+
:maxdepth: 1
|
|
23
|
+
:caption: Новости
|
|
24
|
+
|
|
25
|
+
release-2-1-1
|
|
26
|
+
release-2-1-0
|
|
27
|
+
|
|
21
28
|
.. toctree::
|
|
22
29
|
:maxdepth: 2
|
|
23
30
|
:caption: Руководство
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
PyMax 2.1.0
|
|
2
|
+
===========
|
|
3
|
+
|
|
4
|
+
Изменения относительно ``2.0.1``.
|
|
5
|
+
|
|
6
|
+
Добавлено
|
|
7
|
+
---------
|
|
8
|
+
|
|
9
|
+
* Заявки на вступление в группы и каналы: ``get_join_requests()``,
|
|
10
|
+
``confirm_join_request()`` /
|
|
11
|
+
``confirm_join_requests()`` и отклонить их через ``decline_join_request()`` /
|
|
12
|
+
``decline_join_requests()``.
|
|
13
|
+
* Доменные типы ``Member`` и ``Presence`` для заявок.
|
|
14
|
+
* 2FA: ``check_2fa()`` и ``change_password()``.
|
|
15
|
+
* QR-вход: ``authorize_qr_login(qr_link)``.
|
|
16
|
+
* Web app-боты: ``get_bot_init_data(bot_id, chat_id, start_param=None)``.
|
|
17
|
+
|
|
18
|
+
Исправлено
|
|
19
|
+
----------
|
|
20
|
+
|
|
21
|
+
* TCP-заголовок приведен к схеме Max: ``ver:1``, ``cmd:1``, ``seq:2``,
|
|
22
|
+
``opcode:2``, ``len/cof:4``. ``seq`` больше не падает после ``255``.
|
|
23
|
+
* Upload фото, видео и файлов использует ``ExtraConfig.proxy`` для HTTP-отправки
|
|
24
|
+
на upload URL.
|
|
25
|
+
* ``MaxApiError.title`` и ``MaxApiError.localized_message`` могут быть ``None``.
|
|
26
|
+
|
|
27
|
+
Изменилось
|
|
28
|
+
----------
|
|
29
|
+
|
|
30
|
+
* ``check_2fa()`` возвращает ``False``, если профиль еще не загружен или сервер
|
|
31
|
+
не прислал ``profile_options``.
|
|
32
|
+
* При заданном ``ExtraConfig.proxy`` upload-запросы тоже идут через proxy.
|
|
33
|
+
Proxy должен выдерживать большие HTTP POST-запросы.
|
|
34
|
+
* ``Capability`` разделен на ``ProfileOptions`` и ``TwoFactorAction``.
|
|
35
|
+
* ``ApiFacade`` получил ``bots``-сервис.
|
|
36
|
+
|
|
37
|
+
Миграция
|
|
38
|
+
--------
|
|
39
|
+
|
|
40
|
+
* Код на ``Client`` и ``WebClient`` обычно менять не нужно.
|
|
41
|
+
* Импорт ``pymax.api.auth.enums.Capability`` замените на ``TwoFactorAction`` или
|
|
42
|
+
``ProfileOptions``.
|
|
43
|
+
* Если код ждал строку в ``MaxApiError.title``, теперь нужно учитывать ``None``.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
PyMax 2.1.1
|
|
2
|
+
===========
|
|
3
|
+
|
|
4
|
+
Изменения относительно ``2.1.0``.
|
|
5
|
+
|
|
6
|
+
Добавлено
|
|
7
|
+
---------
|
|
8
|
+
|
|
9
|
+
* ``change_profile(photo=...)`` теперь загружает фотографию профиля напрямую.
|
|
10
|
+
|
|
11
|
+
Исправлено
|
|
12
|
+
----------
|
|
13
|
+
|
|
14
|
+
* TLS-handshake при TCP-подключении через proxy передает ``server_hostname``.
|
|
15
|
+
* Локальный токен обновляется после ``close_all_sessions()`` и при получении
|
|
16
|
+
нового токена во время handshake.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "maxapi-python"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.1.1"
|
|
4
4
|
description = "Python wrapper для API мессенджера Max"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -89,24 +89,32 @@ dev = [
|
|
|
89
89
|
{include-group = "docs"},
|
|
90
90
|
{include-group = "test"},
|
|
91
91
|
"build>=1.2.0",
|
|
92
|
+
"pre-commit>=4.0.0",
|
|
92
93
|
"twine>=5.0.0",
|
|
93
94
|
"pyright>=1.1.390",
|
|
94
|
-
"
|
|
95
|
-
"isort>=5.13.0",
|
|
96
|
-
"flake8>=7.0.0",
|
|
95
|
+
"ruff>=0.8.0",
|
|
97
96
|
]
|
|
98
97
|
|
|
99
98
|
[tool.pyright]
|
|
100
99
|
venv = ".venv"
|
|
101
100
|
venvPath = "."
|
|
102
101
|
|
|
103
|
-
[tool.
|
|
102
|
+
[tool.ruff]
|
|
104
103
|
line-length = 79
|
|
105
|
-
target-version =
|
|
104
|
+
target-version = "py310"
|
|
106
105
|
|
|
107
|
-
[tool.
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
[tool.ruff.lint]
|
|
107
|
+
select = ["E", "F", "I"]
|
|
108
|
+
ignore = ["E501"]
|
|
109
|
+
|
|
110
|
+
[tool.ruff.lint.per-file-ignores]
|
|
111
|
+
"src/pymax/**/__init__.py" = ["F401", "F403"]
|
|
112
|
+
"tests/**" = ["F401"]
|
|
113
|
+
|
|
114
|
+
[tool.ruff.format]
|
|
115
|
+
quote-style = "double"
|
|
116
|
+
indent-style = "space"
|
|
117
|
+
line-ending = "auto"
|
|
110
118
|
|
|
111
119
|
[tool.mypy]
|
|
112
120
|
python_version = "3.10"
|
|
@@ -114,12 +122,6 @@ warn_return_any = true
|
|
|
114
122
|
warn_unused_configs = true
|
|
115
123
|
plugins = ["pydantic.mypy"]
|
|
116
124
|
|
|
117
|
-
[tool.isort]
|
|
118
|
-
profile = "black"
|
|
119
|
-
line_length = 79
|
|
120
|
-
multi_line_output = 3
|
|
121
|
-
include_trailing_comma = true
|
|
122
|
-
|
|
123
125
|
[tool.pytest.ini_options]
|
|
124
126
|
asyncio_mode = "auto"
|
|
125
127
|
testpaths = ["tests"]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class AuthType(str, Enum):
|
|
5
|
+
START_AUTH = "START_AUTH"
|
|
6
|
+
CHECK_CODE = "CHECK_CODE"
|
|
7
|
+
REGISTER = "REGISTER"
|
|
8
|
+
RESEND = "RESEND"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ProfileOptions(int, Enum):
|
|
12
|
+
"""Битовые/числовые признаки профиля, связанные с 2FA."""
|
|
13
|
+
|
|
14
|
+
ESIA_VERIFIED_FLAG = 1
|
|
15
|
+
SECOND_FACTOR_PASSWORD_ENABLED = 2
|
|
16
|
+
SECOND_FACTOR_HAS_EMAIL = 3
|
|
17
|
+
SECOND_FACTOR_HAS_HINT = 4
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class TwoFactorAction(int, Enum):
|
|
21
|
+
"""Действия 2FA, передаваемые в expectedCapabilities."""
|
|
22
|
+
|
|
23
|
+
SET_PASSWORD = 0
|
|
24
|
+
UPDATE_PASSWORD = 1
|
|
25
|
+
RESTORE_PASSWORD = 2
|
|
26
|
+
HINT = 3
|
|
27
|
+
EMAIL = 4
|
|
28
|
+
REMOVE_2FA = 5
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
from pydantic import Field
|
|
1
|
+
from pydantic import Field
|
|
2
2
|
|
|
3
3
|
from pymax.api.models import CamelModel
|
|
4
4
|
from pymax.api.session.payloads import MobileUserAgentPayload
|
|
5
5
|
from pymax.types.domain.sync import DEFAULT_CONFIG_HASH, ConfigHash, SyncState
|
|
6
6
|
|
|
7
|
-
from .enums import AuthType,
|
|
7
|
+
from .enums import AuthType, TwoFactorAction
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class RequestCodePayload(CamelModel):
|
|
@@ -115,7 +115,7 @@ class SetHintPayload(CamelModel):
|
|
|
115
115
|
|
|
116
116
|
|
|
117
117
|
class SetTwoFactorPayload(CamelModel):
|
|
118
|
-
expected_capabilities: list[
|
|
118
|
+
expected_capabilities: list[TwoFactorAction]
|
|
119
119
|
track_id: str
|
|
120
120
|
password: str
|
|
121
121
|
hint: str | None = None
|
|
@@ -123,7 +123,11 @@ class SetTwoFactorPayload(CamelModel):
|
|
|
123
123
|
|
|
124
124
|
class RemoveTwoFactorPayload(CamelModel):
|
|
125
125
|
track_id: str
|
|
126
|
-
remove2fa: bool = True
|
|
127
|
-
expected_capabilities: list[
|
|
128
|
-
default_factory=lambda: [
|
|
126
|
+
remove2fa: bool = Field(default=True, alias="remove2fa")
|
|
127
|
+
expected_capabilities: list[TwoFactorAction] = Field(
|
|
128
|
+
default_factory=lambda: [TwoFactorAction.REMOVE_2FA]
|
|
129
129
|
)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class ApproveQrLoginPayload(CamelModel):
|
|
133
|
+
qr_link: str
|
|
@@ -2,7 +2,11 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
|
-
from pymax.api.response import
|
|
5
|
+
from pymax.api.response import (
|
|
6
|
+
payload_item,
|
|
7
|
+
payload_keys,
|
|
8
|
+
require_payload_model,
|
|
9
|
+
)
|
|
6
10
|
from pymax.api.session.enums import DeviceType
|
|
7
11
|
from pymax.auth import EmailCodeProvider
|
|
8
12
|
from pymax.auth.providers import ConsoleEmailCodeProvider
|
|
@@ -17,8 +21,9 @@ from pymax.types.domain.auth import (
|
|
|
17
21
|
)
|
|
18
22
|
from pymax.types.domain.login import LoginResponse
|
|
19
23
|
|
|
20
|
-
from .enums import
|
|
24
|
+
from .enums import ProfileOptions, TwoFactorAction
|
|
21
25
|
from .payloads import (
|
|
26
|
+
ApproveQrLoginPayload,
|
|
22
27
|
CheckPasswordChallengePayload,
|
|
23
28
|
CheckQrPayload,
|
|
24
29
|
ConfirmQrPayload,
|
|
@@ -51,14 +56,18 @@ class AuthService:
|
|
|
51
56
|
async def request_code(self, phone: str) -> StartAuthResponse:
|
|
52
57
|
logger.info("requesting sms code phone_set=%s", bool(phone))
|
|
53
58
|
frame = RequestCodePayload(phone=phone)
|
|
54
|
-
response = await self.app.invoke(
|
|
59
|
+
response = await self.app.invoke(
|
|
60
|
+
Opcode.AUTH_REQUEST, frame.to_payload()
|
|
61
|
+
)
|
|
55
62
|
logger.debug(
|
|
56
63
|
"sms code request accepted payload_keys=%s",
|
|
57
64
|
payload_keys(response),
|
|
58
65
|
)
|
|
59
66
|
return require_payload_model(response, StartAuthResponse)
|
|
60
67
|
|
|
61
|
-
async def send_code(
|
|
68
|
+
async def send_code(
|
|
69
|
+
self, token: str, verify_code: str
|
|
70
|
+
) -> CheckCodeResponse:
|
|
62
71
|
logger.info(
|
|
63
72
|
"sending sms code token_set=%s code_set=%s",
|
|
64
73
|
bool(token),
|
|
@@ -152,14 +161,18 @@ class AuthService:
|
|
|
152
161
|
async def check_qr(self, track_id: str) -> CheckQrResponse:
|
|
153
162
|
frame = CheckQrPayload(track_id=track_id)
|
|
154
163
|
|
|
155
|
-
response = await self.app.invoke(
|
|
164
|
+
response = await self.app.invoke(
|
|
165
|
+
Opcode.GET_QR_STATUS, frame.to_payload()
|
|
166
|
+
)
|
|
156
167
|
|
|
157
168
|
return require_payload_model(response, CheckQrResponse)
|
|
158
169
|
|
|
159
170
|
async def confirm_qr(self, track_id: str) -> CheckCodeResponse:
|
|
160
171
|
frame = ConfirmQrPayload(track_id=track_id)
|
|
161
172
|
|
|
162
|
-
response = await self.app.invoke(
|
|
173
|
+
response = await self.app.invoke(
|
|
174
|
+
Opcode.LOGIN_BY_QR, frame.to_payload()
|
|
175
|
+
)
|
|
163
176
|
|
|
164
177
|
return require_payload_model(response, CheckCodeResponse)
|
|
165
178
|
|
|
@@ -182,11 +195,15 @@ class AuthService:
|
|
|
182
195
|
logger.debug("creating auth track")
|
|
183
196
|
frame = CreateAuthTrackPayload()
|
|
184
197
|
|
|
185
|
-
response = await self.app.invoke(
|
|
198
|
+
response = await self.app.invoke(
|
|
199
|
+
Opcode.AUTH_CREATE_TRACK, frame.to_payload()
|
|
200
|
+
)
|
|
186
201
|
|
|
187
202
|
return payload_item(response, "trackId", str)
|
|
188
203
|
|
|
189
|
-
async def _set_email(
|
|
204
|
+
async def _set_email(
|
|
205
|
+
self, track_id: str, email: str, provider: EmailCodeProvider
|
|
206
|
+
) -> bool:
|
|
190
207
|
logger.info("setting 2fa email email_set=%s", bool(email))
|
|
191
208
|
|
|
192
209
|
frame = RequestEmailCodePayload(
|
|
@@ -225,7 +242,9 @@ class AuthService:
|
|
|
225
242
|
track_id=track_id,
|
|
226
243
|
password=password,
|
|
227
244
|
)
|
|
228
|
-
await self.app.invoke(
|
|
245
|
+
await self.app.invoke(
|
|
246
|
+
Opcode.AUTH_VALIDATE_PASSWORD, frame.to_payload()
|
|
247
|
+
)
|
|
229
248
|
|
|
230
249
|
return True
|
|
231
250
|
|
|
@@ -263,13 +282,13 @@ class AuthService:
|
|
|
263
282
|
await self._set_hint(track_id, str(hint))
|
|
264
283
|
has_hint = True
|
|
265
284
|
|
|
266
|
-
expected_capabilities = [
|
|
285
|
+
expected_capabilities = [TwoFactorAction.SET_PASSWORD]
|
|
267
286
|
|
|
268
287
|
if has_hint:
|
|
269
|
-
expected_capabilities.append(
|
|
288
|
+
expected_capabilities.append(TwoFactorAction.HINT)
|
|
270
289
|
|
|
271
290
|
if has_email:
|
|
272
|
-
expected_capabilities.append(
|
|
291
|
+
expected_capabilities.append(TwoFactorAction.EMAIL)
|
|
273
292
|
|
|
274
293
|
frame = SetTwoFactorPayload(
|
|
275
294
|
track_id=track_id,
|
|
@@ -311,3 +330,47 @@ class AuthService:
|
|
|
311
330
|
await self.app.invoke(Opcode.AUTH_SET_2FA, frame.to_payload())
|
|
312
331
|
|
|
313
332
|
return True
|
|
333
|
+
|
|
334
|
+
async def authorize_qr_login(self, qr_link: str) -> bool:
|
|
335
|
+
logger.info("approving qr login qr_link_set=%s", bool(qr_link))
|
|
336
|
+
|
|
337
|
+
frame = ApproveQrLoginPayload(qr_link=qr_link)
|
|
338
|
+
|
|
339
|
+
await self.app.invoke(Opcode.AUTH_QR_APPROVE, frame.to_payload())
|
|
340
|
+
|
|
341
|
+
return True
|
|
342
|
+
|
|
343
|
+
async def check_2fa(self) -> bool:
|
|
344
|
+
if not self.app.me or not self.app.me.profile_options:
|
|
345
|
+
return False
|
|
346
|
+
|
|
347
|
+
return (
|
|
348
|
+
ProfileOptions.SECOND_FACTOR_PASSWORD_ENABLED
|
|
349
|
+
in self.app.me.profile_options
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
async def change_password(
|
|
353
|
+
self, password_old: str, password_new: str
|
|
354
|
+
) -> bool:
|
|
355
|
+
track_id = await self._get_track_id()
|
|
356
|
+
|
|
357
|
+
if not track_id:
|
|
358
|
+
logger.error("missing track_id in auth create track response")
|
|
359
|
+
raise RuntimeError("Failed to create auth track")
|
|
360
|
+
|
|
361
|
+
await self._check_2fa_password(track_id, password_old)
|
|
362
|
+
|
|
363
|
+
await self._set_password(track_id, password_new)
|
|
364
|
+
|
|
365
|
+
expected_capabilities = [TwoFactorAction.UPDATE_PASSWORD]
|
|
366
|
+
|
|
367
|
+
frame = SetTwoFactorPayload(
|
|
368
|
+
track_id=track_id,
|
|
369
|
+
password=password_new,
|
|
370
|
+
hint=None,
|
|
371
|
+
expected_capabilities=expected_capabilities,
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
await self.app.invoke(Opcode.AUTH_SET_2FA, frame.to_payload())
|
|
375
|
+
logger.info("2fa password set successfully")
|
|
376
|
+
return True
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .service import BotsService
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from pymax.api.response import require_payload_model
|
|
6
|
+
from pymax.logging import get_logger
|
|
7
|
+
from pymax.protocol import Opcode
|
|
8
|
+
from pymax.types.domain import InitData
|
|
9
|
+
|
|
10
|
+
from .payloads import RequestInitDataPayload
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from pymax.app import App
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
logger = get_logger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class BotsService:
|
|
20
|
+
def __init__(self, app: App) -> None:
|
|
21
|
+
self.app = app
|
|
22
|
+
|
|
23
|
+
async def get_init_data(
|
|
24
|
+
self,
|
|
25
|
+
bot_id: int,
|
|
26
|
+
chat_id: int,
|
|
27
|
+
start_param: str | None = None,
|
|
28
|
+
) -> InitData:
|
|
29
|
+
frame = RequestInitDataPayload(
|
|
30
|
+
bot_id=bot_id, chat_id=chat_id, start_param=start_param
|
|
31
|
+
)
|
|
32
|
+
response = await self.app.invoke(
|
|
33
|
+
Opcode.WEB_APP_INIT_DATA, frame.to_payload()
|
|
34
|
+
)
|
|
35
|
+
return require_payload_model(response, InitData)
|
|
@@ -101,3 +101,17 @@ class LeaveChatPayload(CamelModel):
|
|
|
101
101
|
|
|
102
102
|
class FetchChatsPayload(CamelModel):
|
|
103
103
|
marker: int
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class FetchJoinRequests(CamelModel):
|
|
107
|
+
chat_id: int
|
|
108
|
+
type: str = "JOIN_REQUEST" # ENUM!!!!!
|
|
109
|
+
count: int = 100
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class JoinRequestActionPayload(CamelModel):
|
|
113
|
+
chat_id: int
|
|
114
|
+
user_ids: list[int]
|
|
115
|
+
type: str = "JOIN_REQUEST" # TODO: ENUMM!!!
|
|
116
|
+
show_history: bool | None = True
|
|
117
|
+
operation: ChatMemberOperation
|