python-trueconf-bot 1.0.0__tar.gz → 1.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.
- python_trueconf_bot-1.1.1/.github/workflows/docs.yml +72 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/.github/workflows/release.yml +9 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/PKG-INFO +12 -1
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/README-PyPI.md +7 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/README-ru.md +7 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/README.md +9 -3
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/en/examples/multibot.md +1 -1
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/en/index.md +1 -1
- python_trueconf_bot-1.1.1/docs/en/learn/files.md +143 -0
- python_trueconf_bot-1.1.1/docs/en/learn/filters.md +255 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/en/learn/getting-started.md +4 -11
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/en/reference/Types.md +41 -0
- python_trueconf_bot-1.1.1/docs/en/release_notes.md +56 -0
- python_trueconf_bot-1.1.1/docs/overrides/main.html +8 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/ru/examples/multibot.md +1 -1
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/ru/index.md +1 -1
- python_trueconf_bot-1.1.1/docs/ru/learn/files.md +140 -0
- python_trueconf_bot-1.1.1/docs/ru/learn/filters.md +238 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/ru/learn/getting-started.md +4 -11
- python_trueconf_bot-1.1.1/docs/ru/release_notes.md +45 -0
- python_trueconf_bot-1.1.1/examples/README-ru.md +12 -0
- python_trueconf_bot-1.1.1/examples/README.md +12 -0
- python_trueconf_bot-1.1.1/examples/filters.py +117 -0
- python_trueconf_bot-1.1.1/examples/update_token.py +34 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/mkdocs.yml +11 -2
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/pyproject.toml +7 -1
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/python_trueconf_bot.egg-info/PKG-INFO +12 -1
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/python_trueconf_bot.egg-info/SOURCES.txt +16 -0
- python_trueconf_bot-1.1.1/python_trueconf_bot.egg-info/requires.txt +10 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/requirements-docs.txt +6 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/requirements.txt +10 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/_version.py +3 -3
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/client/bot.py +349 -159
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/client/session.py +3 -10
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/dispatcher/router.py +52 -12
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/enums/incoming_update_method.py +2 -0
- python_trueconf_bot-1.1.1/trueconf/exceptions.py +21 -0
- python_trueconf_bot-1.1.1/trueconf/filters/command.py +103 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/add_participant_to_chat.py +3 -1
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/base.py +4 -14
- python_trueconf_bot-1.1.1/trueconf/methods/change_participant_role.py +25 -0
- python_trueconf_bot-1.1.1/trueconf/methods/create_favorites_chat.py +16 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/send_file.py +6 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/__init__.py +11 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/chat_participant.py +1 -1
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/content/document.py +4 -2
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/content/photo.py +4 -2
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/content/sticker.py +4 -2
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/content/video.py +4 -2
- python_trueconf_bot-1.1.1/trueconf/types/input_file.py +402 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/message.py +38 -1
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/parser.py +8 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/requests/__init__.py +2 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/requests/added_chat_participant.py +1 -1
- python_trueconf_bot-1.1.1/trueconf/types/requests/changed_participant_role.py +40 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/requests/created_channel.py +1 -1
- python_trueconf_bot-1.1.1/trueconf/types/requests/created_favorites_chat.py +42 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/requests/created_group_chat.py +1 -1
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/requests/created_personal_chat.py +1 -1
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/requests/edited_message.py +1 -1
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/requests/removed_chat.py +1 -1
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/requests/removed_chat_participant.py +1 -1
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/requests/removed_message.py +1 -1
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/requests/uploading_progress.py +1 -1
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/__init__.py +3 -1
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/api_error.py +13 -2
- python_trueconf_bot-1.1.1/trueconf/types/responses/change_participant_role_response.py +8 -0
- python_trueconf_bot-1.1.1/trueconf/types/responses/create_favorites_chat_response.py +8 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/utils/token.py +2 -2
- python_trueconf_bot-1.0.0/.github/workflows/docs.yml +0 -37
- python_trueconf_bot-1.0.0/docs/en/learn/filters.md +0 -144
- python_trueconf_bot-1.0.0/docs/ru/learn/filters.md +0 -141
- python_trueconf_bot-1.0.0/python_trueconf_bot.egg-info/requires.txt +0 -5
- python_trueconf_bot-1.0.0/trueconf/exceptions.py +0 -17
- python_trueconf_bot-1.0.0/trueconf/filters/command.py +0 -32
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/.github/workflows/release-test.yml +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/.gitignore +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/LICENSE +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/assets/head_en.png +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/assets/head_ru.png +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/assets/logo-cyrillic.svg +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/assets/logo.svg +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/en/examples/echo_bot.md +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/en/features.md +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/en/img/head.png +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/en/learn/enums.md +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/en/learn/parse-messages.md +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/en/learn/types.md +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/en/reference/Bot.md +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/en/reference/Dispatcher.md +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/en/reference/Enums.md +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/en/reference/Router.md +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/en/reference/index.md +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/img/chatbot.svg +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/img/favicon.ico +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/img/logo.svg +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/ru/examples/echo_bot.md +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/ru/features.md +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/ru/img/head.png +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/ru/learn/enums.md +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/ru/learn/parse-messages.md +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/ru/learn/types.md +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/docs/stylesheets/extra.css +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/python_trueconf_bot.egg-info/dependency_links.txt +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/python_trueconf_bot.egg-info/top_level.txt +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/setup.cfg +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/__init__.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/client/__init__.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/client/context_controller.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/dispatcher/__init__.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/dispatcher/dispatcher.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/enums/__init__.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/enums/aouth_error.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/enums/chat_participant_role.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/enums/chat_type.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/enums/envelope_author_type.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/enums/file_ready_state.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/enums/message_type.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/enums/parse_mode.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/enums/survey_type.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/enums/update_type.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/filters/__init__.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/filters/base.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/filters/instance_of.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/filters/message.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/filters/method.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/loggers.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/__init__.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/auth.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/create_channel.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/create_group_chat.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/create_p2p_chat.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/edit_message.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/edit_survey.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/forward_message.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/get_chat_by_id.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/get_chat_history.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/get_chat_participants.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/get_chats.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/get_file_info.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/get_message_by_id.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/get_user_display_name.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/has_chat_participant.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/remove_chat.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/remove_message.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/remove_participant_from_chat.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/send_message.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/send_survey.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/subscribe_file_progress.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/unsubscribe_file_progress.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/methods/upload_file.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/py.typed +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/author_box.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/content/__init__.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/content/attachment.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/content/base.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/content/chat_created.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/content/forward_message.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/content/remove_participant.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/content/survey.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/content/text.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/last_message.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/add_chat_participant_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/auth_response_payload.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/create_channel_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/create_group_chat_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/create_p2p_chat_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/edit_message_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/edit_survey_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/forward_message_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/get_chat_by_id_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/get_chat_history_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/get_chat_participants_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/get_chats_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/get_file_info_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/get_message_by_id_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/get_user_display_name_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/has_chat_participant_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/remove_chat_participant_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/remove_chat_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/remove_message_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/send_file_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/send_message_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/send_survey_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/subscribe_file_progress_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/unsubscribe_file_progress_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/responses/upload_file_response.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/types/update.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/utils/__init__.py +0 -0
- {python_trueconf_bot-1.0.0 → python_trueconf_bot-1.1.1}/trueconf/utils/generate_secret_for_survey.py +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'docs/*'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
deploy-docs:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
with:
|
|
19
|
+
fetch-depth: 0
|
|
20
|
+
persist-credentials: true
|
|
21
|
+
|
|
22
|
+
- name: Set up Python
|
|
23
|
+
uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.10"
|
|
26
|
+
|
|
27
|
+
- name: Install docs dependencies
|
|
28
|
+
run: |
|
|
29
|
+
python -m pip install --upgrade pip
|
|
30
|
+
if [ -f requirements-docs.txt ]; then pip install -r requirements-docs.txt; fi
|
|
31
|
+
|
|
32
|
+
- name: Preflight check (mkdocs.yml has mike plugin)
|
|
33
|
+
run: |
|
|
34
|
+
if ! grep -q '^ *- *mike *$' mkdocs.yml && ! grep -q 'plugins:.*mike' mkdocs.yml; then
|
|
35
|
+
echo "::error::Plugin 'mike' is not enabled in mkdocs.yml (add under plugins: - mike)"
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
- name: Configure Git
|
|
40
|
+
run: |
|
|
41
|
+
git config user.name "github-actions[bot]"
|
|
42
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
43
|
+
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
|
44
|
+
|
|
45
|
+
- name: Determine version label
|
|
46
|
+
id: ver
|
|
47
|
+
env:
|
|
48
|
+
INPUT_VERSION: ${{ github.event.inputs.version }}
|
|
49
|
+
run: |
|
|
50
|
+
if [ -n "$INPUT_VERSION" ]; then
|
|
51
|
+
VERSION="$INPUT_VERSION"
|
|
52
|
+
else
|
|
53
|
+
# Например, docs/v1.0.0 -> v1.0.0
|
|
54
|
+
VERSION="${GITHUB_REF_NAME#docs/}"
|
|
55
|
+
fi
|
|
56
|
+
echo "Using version: $VERSION"
|
|
57
|
+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
58
|
+
|
|
59
|
+
- name: Deploy docs with mike (update latest alias)
|
|
60
|
+
if: ${{ github.event.inputs.alias_latest != 'false' }}
|
|
61
|
+
env:
|
|
62
|
+
VERSION: ${{ steps.ver.outputs.version }}
|
|
63
|
+
run: |
|
|
64
|
+
mike deploy --push --branch gh-pages --update-aliases "$VERSION" latest
|
|
65
|
+
mike set-default --push --branch gh-pages latest
|
|
66
|
+
|
|
67
|
+
- name: Deploy docs with mike (no alias update)
|
|
68
|
+
if: ${{ github.event.inputs.alias_latest == 'false' }}
|
|
69
|
+
env:
|
|
70
|
+
VERSION: ${{ steps.ver.outputs.version }}
|
|
71
|
+
run: |
|
|
72
|
+
mike deploy --push --branch gh-pages "$VERSION"
|
|
@@ -22,6 +22,15 @@ jobs:
|
|
|
22
22
|
fetch-tags: true
|
|
23
23
|
ref: ${{ github.event.inputs.tag }}
|
|
24
24
|
|
|
25
|
+
- name: Show current commit
|
|
26
|
+
run: git describe --tags --always
|
|
27
|
+
|
|
28
|
+
- name: Set version from tag
|
|
29
|
+
run: |
|
|
30
|
+
TAG="${{ github.event.inputs.tag }}"
|
|
31
|
+
VERSION="${TAG#v}"
|
|
32
|
+
sed -i "s/^version = .*/version = \"${VERSION}\"/" pyproject.toml
|
|
33
|
+
|
|
25
34
|
- name: Set up Python
|
|
26
35
|
uses: actions/setup-python@v5
|
|
27
36
|
with:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-trueconf-bot
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.1
|
|
4
4
|
Summary: Lightweight and powerful framework for the TrueConf Server Chatbot API
|
|
5
5
|
Author-email: TrueConf LLC <info@trueconf.com>, Anton Baadzhi <baadzhianton@gmail.com>
|
|
6
6
|
License-Expression: BSD-3-Clause-Clear
|
|
@@ -28,6 +28,10 @@ Requires-Dist: httpx
|
|
|
28
28
|
Requires-Dist: mashumaro
|
|
29
29
|
Requires-Dist: aiofiles
|
|
30
30
|
Requires-Dist: magic-filter
|
|
31
|
+
Requires-Dist: aiohttp
|
|
32
|
+
Requires-Dist: async-property
|
|
33
|
+
Provides-Extra: python-magic
|
|
34
|
+
Requires-Dist: python-magic>=0.4.27; extra == "python-magic"
|
|
31
35
|
Dynamic: license-file
|
|
32
36
|
|
|
33
37
|
<p align="center">
|
|
@@ -44,6 +48,12 @@ Dynamic: license-file
|
|
|
44
48
|
<p align="center">This is a lightweight and powerful wrapper for the <a href="https://trueconf.com/docs/chatbot-connector/en/overview/">TrueConf Server Chatbot API</a> which enables quick integration of chatbots into TrueConf solutions.</p>
|
|
45
49
|
|
|
46
50
|
<p align="center">
|
|
51
|
+
<a href="https://pypi.org/project/python-trueconf-bot/">
|
|
52
|
+
<img src="https://img.shields.io/pypi/v/python-trueconf-bot">
|
|
53
|
+
</a>
|
|
54
|
+
<a href="https://pypi.org/project/python-trueconf-bot/">
|
|
55
|
+
<img src="https://img.shields.io/pypi/pyversions/python-trueconf-bot">
|
|
56
|
+
</a>
|
|
47
57
|
<a href="https://t.me/trueconf_chat" target="_blank">
|
|
48
58
|
<img src="https://img.shields.io/badge/telegram-group-blue?style=flat-square&logo=telegram" />
|
|
49
59
|
</a>
|
|
@@ -107,6 +117,7 @@ if __name__ == "__main__":
|
|
|
107
117
|
|
|
108
118
|
1. [TrueConf Server Chatbot API Documentation](https://trueconf.com/docs/chatbot-connector/en/overview/)
|
|
109
119
|
2. [python-trueconf-bot Documentation](https://trueconf.github.io/python-trueconf-bot/)
|
|
120
|
+
3. [Examples](examples/README.md)
|
|
110
121
|
|
|
111
122
|
All updates and releases are available in the repository. Track the build status and test coverage.
|
|
112
123
|
|
|
@@ -12,6 +12,12 @@
|
|
|
12
12
|
<p align="center">This is a lightweight and powerful wrapper for the <a href="https://trueconf.com/docs/chatbot-connector/en/overview/">TrueConf Server Chatbot API</a> which enables quick integration of chatbots into TrueConf solutions.</p>
|
|
13
13
|
|
|
14
14
|
<p align="center">
|
|
15
|
+
<a href="https://pypi.org/project/python-trueconf-bot/">
|
|
16
|
+
<img src="https://img.shields.io/pypi/v/python-trueconf-bot">
|
|
17
|
+
</a>
|
|
18
|
+
<a href="https://pypi.org/project/python-trueconf-bot/">
|
|
19
|
+
<img src="https://img.shields.io/pypi/pyversions/python-trueconf-bot">
|
|
20
|
+
</a>
|
|
15
21
|
<a href="https://t.me/trueconf_chat" target="_blank">
|
|
16
22
|
<img src="https://img.shields.io/badge/telegram-group-blue?style=flat-square&logo=telegram" />
|
|
17
23
|
</a>
|
|
@@ -75,6 +81,7 @@ if __name__ == "__main__":
|
|
|
75
81
|
|
|
76
82
|
1. [TrueConf Server Chatbot API Documentation](https://trueconf.com/docs/chatbot-connector/en/overview/)
|
|
77
83
|
2. [python-trueconf-bot Documentation](https://trueconf.github.io/python-trueconf-bot/)
|
|
84
|
+
3. [Examples](examples/README.md)
|
|
78
85
|
|
|
79
86
|
All updates and releases are available in the repository. Track the build status and test coverage.
|
|
80
87
|
|
|
@@ -12,6 +12,12 @@
|
|
|
12
12
|
<p align="center">Это легкая и мощная обертка для <a href="hhttps://trueconf.ru/docs/chatbot-connector/ru/overview/">API чат-ботов TrueConf Server</a>, позволяющая быстро интегрировать чат-ботов с API TrueConf.</p>
|
|
13
13
|
|
|
14
14
|
<p align="center">
|
|
15
|
+
<a href="https://pypi.org/project/python-trueconf-bot/">
|
|
16
|
+
<img src="https://img.shields.io/pypi/v/python-trueconf-bot">
|
|
17
|
+
</a>
|
|
18
|
+
<a href="https://pypi.org/project/python-trueconf-bot/">
|
|
19
|
+
<img src="https://img.shields.io/pypi/pyversions/python-trueconf-bot">
|
|
20
|
+
</a>
|
|
15
21
|
<a href="https://t.me/trueconf_chat" target="_blank">
|
|
16
22
|
<img src="https://img.shields.io/badge/telegram-group-blue?style=flat-square&logo=telegram" />
|
|
17
23
|
</a>
|
|
@@ -79,6 +85,7 @@ if __name__ == "__main__":
|
|
|
79
85
|
|
|
80
86
|
1. [Документация API чат-ботов TrueConf Server](https://trueconf.ru/docs/chatbot-connector/ru/overview/)
|
|
81
87
|
2. [Документация python-trueconf-bot](https://trueconf.github.io/python-trueconf-bot/ru/)
|
|
88
|
+
3. [Примеры](examples/README-ru.md)
|
|
82
89
|
|
|
83
90
|
Все обновления и релизы доступны в репозитории. Следите за статусом сборок и покрытием тестами.
|
|
84
91
|
|
|
@@ -12,6 +12,12 @@
|
|
|
12
12
|
<p align="center">This is a lightweight and powerful wrapper for the <a href="https://trueconf.com/docs/chatbot-connector/en/overview/">TrueConf Server Chatbot API</a> which enables quick integration of chatbots into TrueConf solutions.</p>
|
|
13
13
|
|
|
14
14
|
<p align="center">
|
|
15
|
+
<a href="https://pypi.org/project/python-trueconf-bot/">
|
|
16
|
+
<img src="https://img.shields.io/pypi/v/python-trueconf-bot">
|
|
17
|
+
</a>
|
|
18
|
+
<a href="https://pypi.org/project/python-trueconf-bot/">
|
|
19
|
+
<img src="https://img.shields.io/pypi/pyversions/python-trueconf-bot">
|
|
20
|
+
</a>
|
|
15
21
|
<a href="https://t.me/trueconf_chat" target="_blank">
|
|
16
22
|
<img src="https://img.shields.io/badge/telegram-group-blue?style=flat-square&logo=telegram" />
|
|
17
23
|
</a>
|
|
@@ -33,12 +39,11 @@
|
|
|
33
39
|
</p>
|
|
34
40
|
|
|
35
41
|
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
42
|
> [!TIP]
|
|
40
43
|
> We were inspired by the popular [aiogram](https://github.com/aiogram/aiogram/) library, so, the transition will be **simple** for developers already familiar with this library.
|
|
41
44
|
|
|
45
|
+
---
|
|
46
|
+
|
|
42
47
|
## 📌 Key Features
|
|
43
48
|
|
|
44
49
|
* Easy integration with the [TrueConf Server Chatbot API](https://trueconf.com/docs/chatbot-connector/en/overview/)
|
|
@@ -82,6 +87,7 @@ if __name__ == "__main__":
|
|
|
82
87
|
|
|
83
88
|
1. [TrueConf Server Chatbot API Documentation](https://trueconf.com/docs/chatbot-connector/en/overview/)
|
|
84
89
|
2. [python-trueconf-bot Documentation](https://trueconf.github.io/python-trueconf-bot/)
|
|
90
|
+
3. [Examples](examples/README.md)
|
|
85
91
|
|
|
86
92
|
All updates and releases are available in the repository. Track the build status and test coverage.
|
|
87
93
|
|
|
@@ -8,4 +8,4 @@ The TrueConf team has prepared an example that demonstrates the use of four bots
|
|
|
8
8
|
- GPT bot that runs a local LLM model in the background
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
[View repository :fontawesome-solid-arrow-right:](github.com/TrueConf){ .md-button }
|
|
11
|
+
[View repository :fontawesome-solid-arrow-right:](https://github.com/TrueConf/trueconf-chatbot-example){ .md-button }
|
|
@@ -25,7 +25,7 @@ This library is designed to simplify the development of chatbots by providing re
|
|
|
25
25
|
### Installation using pip
|
|
26
26
|
|
|
27
27
|
```shell
|
|
28
|
-
pip install
|
|
28
|
+
pip install {{product_name}}
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
## Comparison with aiogram
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Working with files
|
|
3
|
+
icon:
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Working with Files
|
|
7
|
+
|
|
8
|
+
{{product_chatbot}} does not impose any restrictions on uploading files to the
|
|
9
|
+
server. However, starting from version {{product_server}} 5.5.2 and above, the
|
|
10
|
+
administrator can set limits on the maximum file size and allowable formats
|
|
11
|
+
(extensions).
|
|
12
|
+
|
|
13
|
+
The **{{product_name}}** library offers convenient tools for file handling, both
|
|
14
|
+
for sending and uploading. To send a file, use one of the InputFile subclasses,
|
|
15
|
+
depending on the data source.
|
|
16
|
+
|
|
17
|
+
Three built-in classes are available for file transfer:
|
|
18
|
+
|
|
19
|
+
- FSInputFile — uploading a file from the local file system
|
|
20
|
+
- BufferedInputFile — loading from a byte buffer
|
|
21
|
+
- URLInputFile — uploading a file from a remote URL
|
|
22
|
+
|
|
23
|
+
All classes are located in the [trueconf.types](../reference/Types.md) module.
|
|
24
|
+
|
|
25
|
+
You can use these classes in methods:
|
|
26
|
+
|
|
27
|
+
- bot.send_document(...)
|
|
28
|
+
- bot.send_photo(...)
|
|
29
|
+
- bot.send_sticker(...)
|
|
30
|
+
|
|
31
|
+
## How to send a file?
|
|
32
|
+
|
|
33
|
+
### 🗂️ FSInputFile
|
|
34
|
+
|
|
35
|
+
It is used for uploading files from the local file system. It is recommended to
|
|
36
|
+
use this when you have a file path.
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from trueconf.types import FSInputFile
|
|
40
|
+
|
|
41
|
+
await bot.send_document(
|
|
42
|
+
chat_id="a1b2c3d4",
|
|
43
|
+
file=FSInputFile("docs/report.pdf"),
|
|
44
|
+
caption="📄 Annual report for **2025**",
|
|
45
|
+
parse_mode=ParseMode.MARKDOWN
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
await bot.send_sticker(
|
|
49
|
+
chat_id="a1b2c3d4",
|
|
50
|
+
file=FSInputFile("stickers/cat.webp")
|
|
51
|
+
)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 🧠 BufferedInputFile
|
|
55
|
+
|
|
56
|
+
Used when the file is already in memory (for example, received from an API,
|
|
57
|
+
loaded into RAM, or from a database).
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from trueconf.types import BufferedInputFile
|
|
61
|
+
|
|
62
|
+
image_bytes = open("image.jpg", "rb").read()
|
|
63
|
+
preview_bytes = open("preview.jpg", "rb").read()
|
|
64
|
+
|
|
65
|
+
await bot.send_photo(
|
|
66
|
+
chat_id="a1b2c3d4",
|
|
67
|
+
file=BufferedInputFile(
|
|
68
|
+
file=image_bytes,
|
|
69
|
+
filename="image.jpg"
|
|
70
|
+
),
|
|
71
|
+
preview=BufferedInputFile(
|
|
72
|
+
file=preview_bytes,
|
|
73
|
+
filename="preview.jpg"
|
|
74
|
+
),
|
|
75
|
+
caption="This is my photo"
|
|
76
|
+
)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The convenient method `from_file()` is also available:
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
file = BufferedInputFile.from_file("archive.zip")
|
|
83
|
+
await bot.send_document(chat_id="...", file=file)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 🌐 URLInputFile
|
|
87
|
+
|
|
88
|
+
If the file is available online, you can provide a link, and the bot will
|
|
89
|
+
download it automatically.
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from trueconf.types import URLInputFile
|
|
93
|
+
|
|
94
|
+
file = URLInputFile(
|
|
95
|
+
url="https://example.com/image.png",
|
|
96
|
+
filename="image.png", # optional — it will be determined automatically
|
|
97
|
+
)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Recommendations
|
|
101
|
+
|
|
102
|
+
- **MIME type**: determined automatically. If the
|
|
103
|
+
[python-magic](https://pypi.org/project/python-magic) package is installed,
|
|
104
|
+
the MIME type will be calculated based on the file's content (bytes), which is
|
|
105
|
+
significantly more accurate than determining it by extension. Install it with
|
|
106
|
+
dependencies as follows:
|
|
107
|
+
|
|
108
|
+
```shell
|
|
109
|
+
pip install python-trueconf-bot[python-magic]
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
- **clone()**: each file type supports the `.clone()` method, which creates a new
|
|
113
|
+
copy of the object with a different `id(object)`.
|
|
114
|
+
|
|
115
|
+
## How to download a file?
|
|
116
|
+
|
|
117
|
+
To easily download incoming media files, such as images (`message.photo`) or
|
|
118
|
+
documents (`message.document`), the library provides the shortcut method
|
|
119
|
+
`.download()`. This is syntactic sugar over the `bot.download_file_by_id(...)`
|
|
120
|
+
method, simplifying the handling of attachments.
|
|
121
|
+
|
|
122
|
+
It is recommended to use `.download()` because it:
|
|
123
|
+
|
|
124
|
+
- automatically retrieves file_id from the object;
|
|
125
|
+
- uses the current bot instance;
|
|
126
|
+
- minimizes the amount of code.
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
@router.message(F.document)
|
|
130
|
+
async def handle_doc(msg: Message):
|
|
131
|
+
await msg.document.download(dest_path="document.pdf")
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
!!! Notes The `dest_path` can be either relative or absolute.
|
|
135
|
+
|
|
136
|
+
The method `download_file_by_id(...)` is also available for more flexible control:
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
await bot.download_file_by_id(
|
|
140
|
+
file_id=msg.document.file_id,
|
|
141
|
+
dest_path="document.pdf"
|
|
142
|
+
)
|
|
143
|
+
```
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Filters
|
|
3
|
+
icon:
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Filters
|
|
7
|
+
|
|
8
|
+
Filters are necessary for routing incoming events (updates) to the correct
|
|
9
|
+
handlers. The search for a handler always stops at the first match with a set of
|
|
10
|
+
filters. By default, all handlers have an empty set of filters, so all updates
|
|
11
|
+
will be passed to the first handler with an empty set of filters. In the current
|
|
12
|
+
implementation, two main approaches for filtering text messages are available:
|
|
13
|
+
|
|
14
|
+
- **Command** — a filter for processing commands in the format /command
|
|
15
|
+
\[arguments].
|
|
16
|
+
- **MagicFilter** is a universal declarative filter (from the magic-filter
|
|
17
|
+
library) for event field validation.
|
|
18
|
+
|
|
19
|
+
These two approaches are often used together: **Command** checks the command
|
|
20
|
+
format and extracts arguments, while **MagicFilter** imposes additional
|
|
21
|
+
conditions on arguments or other message fields.
|
|
22
|
+
|
|
23
|
+
!!! Tip
|
|
24
|
+
Below you can find examples of using filters, but if that's not enough, check out [examples in the repository](https://github.com/TrueConf/python-trueconf-bot/tree/master/examples).
|
|
25
|
+
|
|
26
|
+
## Command
|
|
27
|
+
|
|
28
|
+
**Command** — a convenient filter for parsing and processing commands in message
|
|
29
|
+
text.
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
Command(*commands: str | Pattern[str], prefix: str = "/", ignore_case: bool = False, magic: MagicFilter | None = None)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
!!! note "Capabilities"
|
|
36
|
+
- Accept one or more commands: `Command("start")`, `Command("info", "about")`.
|
|
37
|
+
- Support regular expression patterns: `Command(re.compile(r"echo_\d+"))`.
|
|
38
|
+
- Support different prefixes (default is `/`), for example `prefix="!/"` — then `!cmd` and `/cmd` will be valid.
|
|
39
|
+
- Ignore case for string commands (`ignore_case=True`).
|
|
40
|
+
- Accept optional `magic` — **MagicFilter**, which additionally validates the `CommandObject` (see [below](#commandobject)).
|
|
41
|
+
|
|
42
|
+
The **Command** filter operates as follows:
|
|
43
|
+
|
|
44
|
+
1. Checks that the message is a `Message` and that it is of type `PLAIN_MESSAGE`.
|
|
45
|
+
1. Checks if the text begins with the specified prefix (default is `/`).
|
|
46
|
+
1. Splits the string into a command and arguments (if any).
|
|
47
|
+
1. Compares the command with the specified ones (including support for
|
|
48
|
+
`re.Pattern`).
|
|
49
|
+
1. If `magic` is passed, `MagicFilter` is applied to the `CommandObject`.
|
|
50
|
+
1. If the `magic` filter is triggered, it returns a dictionary
|
|
51
|
+
`{"command": command_obj}`.
|
|
52
|
+
|
|
53
|
+
### CommandObject
|
|
54
|
+
|
|
55
|
+
If the filter is triggered, the handler can receive a **CommandObject** (passed
|
|
56
|
+
as the `command` parameter):
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
@dataclass(frozen=True)
|
|
60
|
+
class CommandObject:
|
|
61
|
+
prefix: str
|
|
62
|
+
command: str
|
|
63
|
+
args: str | None
|
|
64
|
+
regexp_match: Match[str] | None = None
|
|
65
|
+
magic_result: Any | None = None
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
!!! Note "Fields"
|
|
69
|
+
- `prefix` — the prefix character (`/`, `!`, etc.).
|
|
70
|
+
- `command` — the command name without the prefix.
|
|
71
|
+
- `args` — the argument string (everything after the space).
|
|
72
|
+
- `regexp_match` — the result of `re.Match` if the command was specified as a regular expression.
|
|
73
|
+
- `magic_result` — optional data returned by `magic` (if applicable).
|
|
74
|
+
|
|
75
|
+
### Examples
|
|
76
|
+
|
|
77
|
+
**Basic handler:**
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
@r.message(Command("ping"))
|
|
81
|
+
async def handle_ping(message: Message):
|
|
82
|
+
await bot.send_message(chat_id=message.chat_id, text="pong")
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Multiple commands:**
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
@r.message(Command("info", "about", "whoami"))
|
|
89
|
+
async def handle_info(message: Message, command: CommandObject):
|
|
90
|
+
await bot.send_message(chat_id=message.chat_id, text=f"Used /{command.command}")
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Command with prefix:**
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
@r.message(Command(re.compile(r"echo_\d+")))
|
|
97
|
+
async def handle_echo_numbered(message: Message, command: CommandObject):
|
|
98
|
+
await bot.send_message(chat_id=message.chat_id, text=f"Echo: {command.command} {command.args or ''}")
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## MagicFilter
|
|
102
|
+
|
|
103
|
+
**MagicFilter** is a declarative, chainable filter from the **magic-filter**
|
|
104
|
+
package. It allows you to express checks on event fields using chains and
|
|
105
|
+
operators. Instead of manually checking update fields within the handler,
|
|
106
|
+
conditions can be set directly in the decorator.
|
|
107
|
+
|
|
108
|
+
The filter works "lazily": when a handler is declared, only the chain of checks
|
|
109
|
+
is stored, not the result. The actual evaluation happens only when a new event
|
|
110
|
+
arrives, so filters can be easily combined and remain readable. This approach
|
|
111
|
+
makes the code shorter and clearer, showing exactly which updates will be
|
|
112
|
+
processed by a given handler.
|
|
113
|
+
|
|
114
|
+
The idea behind **MagicFilter** is simple: describe an attribute chain and a
|
|
115
|
+
condition, then apply it to an object. Imagine you have an object with nested
|
|
116
|
+
fields. Instead of manually checking something like
|
|
117
|
+
`if obj.foo.bar.baz == "spam": ...`, you can construct the filter declaratively:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
F.foo.bar.baz == "spam"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The resulting filter is not an immediate check, but an object that "remembers"
|
|
124
|
+
the condition. When processing an update, this filter is automatically applied
|
|
125
|
+
to the object (the router handles the check under the hood). Technically, the
|
|
126
|
+
`.resolve(obj)` method is used for this, but you don't need to call it manually
|
|
127
|
+
— just define the condition in the decorator, and it will be executed during
|
|
128
|
+
routing.
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
@r.message(F.text == "ping")
|
|
132
|
+
async def ping_handler(message):
|
|
133
|
+
await message.answer("pong")
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Here, the filter `F.text == "ping"` will be automatically checked for each
|
|
137
|
+
incoming message. If the condition matches, the handler will be triggered.
|
|
138
|
+
|
|
139
|
+
### Examples
|
|
140
|
+
|
|
141
|
+
The **MagicFilter** object supports basic logical operations on object attributes.
|
|
142
|
+
|
|
143
|
+
**Existence Check:**
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
F.photo # lambda message: message.photo
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Equality:**
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
F.text == "hello" # lambda message: message.text == "hello"
|
|
153
|
+
F.from_user.id == 42 # lambda message: message.from_user.id == 42
|
|
154
|
+
F.text != "spam" # lambda message: message.text != "spam"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Set membership:**
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
# lambda query: query.from_user.id in {42, 1000, 123123}
|
|
161
|
+
F.from_user.id.in_({42, 1000, 123123})
|
|
162
|
+
|
|
163
|
+
# lambda query: query.data in {"foo", "bar", "baz"}
|
|
164
|
+
F.data.in_({"foo", "bar", "baz"})
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Contains:**
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
F.text.contains("foo") # lambda message: "foo" in message.text
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Starts/ends with the string:**
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
F.text.startswith("foo") # lambda message: message.text.startswith("foo")
|
|
177
|
+
F.text.endswith("bar") # lambda message: message.text.endswith("bar")
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Regular Expressions:**
|
|
181
|
+
|
|
182
|
+
```python
|
|
183
|
+
F.text.regexp(r"Hello, .+") # lambda message: re.match(r"Hello, .+", message.text)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Custom Function:**
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
# lambda message: (lambda chat: chat.id == -42)(message.chat)
|
|
190
|
+
F.chat.func(lambda chat: chat.id == -42)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Inversion of result:**
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
~F.text # not message.text
|
|
197
|
+
~F.text.startswith("spam") #not message.text.startswith("spam")
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Combining conditions:**
|
|
201
|
+
|
|
202
|
+
```python
|
|
203
|
+
(F.from_user.id == 42) & (F.text == "admin")
|
|
204
|
+
|
|
205
|
+
F.text.startswith("a") | F.text.endswith("b")
|
|
206
|
+
|
|
207
|
+
(F.from_user.id.in_({42, 777, 911})) & (F.text.startswith("!") | F.text.startswith("/")) & F.text.contains("ban")
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Attribute Modifiers (Strings):**
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
F.text.lower() == "test" # message.text.lower() == "test"
|
|
214
|
+
F.text.upper().in_({"FOO", "BAR"}) # message.text.upper() in {"FOO", "BAR"}
|
|
215
|
+
F.text.len() == 5 # len(message.text) == 5
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Combining Filters
|
|
219
|
+
|
|
220
|
+
Combining **Command** and **MagicFilter** is a common and recommended practice:
|
|
221
|
+
**Command** parses the command and creates a **CommandObject**, while `magic`
|
|
222
|
+
allows you to impose additional conditions on `args` or other parts of the
|
|
223
|
+
**CommandObject**.
|
|
224
|
+
|
|
225
|
+
**Filter the /echo command only if arguments are present:**
|
|
226
|
+
|
|
227
|
+
```python
|
|
228
|
+
@r.message(Command("echo", magic=F.args.is_not(None)))
|
|
229
|
+
async def handle_echo(message: Message, command: CommandObject):
|
|
230
|
+
await bot.send_message(chat_id=message.chat_id, text=command.args)
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**Additional argument length check:**
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
@r.message(Command("upper", magic=F.args.len() > 3))
|
|
237
|
+
async def handle_upper(message: Message, command: CommandObject):
|
|
238
|
+
await bot.send_message(chat_id=message.chat_id, text=(command.args or "").upper())
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Check with func — single word:**
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
@r.message(Command("repeat", magic=F.args.func(lambda x: isinstance(x, str) and len(x.split()) == 1)))
|
|
245
|
+
async def handle_repeat(message: Message, command: CommandObject):
|
|
246
|
+
await bot.send_message(chat_id=message.chat_id, text=f"{command.args} {command.args}")
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**Combining regexp and magic:**
|
|
250
|
+
|
|
251
|
+
```python
|
|
252
|
+
@r.message(Command(re.compile(r"echo_\\d+"), magic=F.args))
|
|
253
|
+
async def handle_special_echo(message: Message, command: CommandObject):
|
|
254
|
+
await bot.send_message(chat_id=message.chat_id, text=f"Special: {command.command} -> {command.args}")
|
|
255
|
+
```
|
|
@@ -10,18 +10,11 @@ source .venv/bin/activate # Linux / macOS
|
|
|
10
10
|
|
|
11
11
|
## Installing {{product_name}}
|
|
12
12
|
|
|
13
|
-
To
|
|
13
|
+
To begin working with {{product_name}}, install the package from the global PyPI repository:
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
pip install {{product_name}}
|
|
19
|
-
```
|
|
20
|
-
2. From a locally built package (.whl):
|
|
21
|
-
|
|
22
|
-
```shell
|
|
23
|
-
pip install {{product_name}}.whl
|
|
24
|
-
```
|
|
15
|
+
```shell
|
|
16
|
+
pip install {{product_name}}
|
|
17
|
+
```
|
|
25
18
|
|
|
26
19
|
!!! info
|
|
27
20
|
Upon installation, dependencies will be automatically pulled in: `websockets`, `httpx`, `mashumaro`, `pillow`, `aiofiles`, `magic-filter`.
|