python-trueconf-bot 1.2.0b3__tar.gz → 1.2.2__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.2.0b3 → python_trueconf_bot-1.2.2}/PKG-INFO +19 -11
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/README-PyPI.md +17 -10
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/README-ru.md +18 -10
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/README.md +16 -9
- python_trueconf_bot-1.2.2/docs/en/examples/index.md +245 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/index.md +5 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/learn/files.md +46 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/learn/filters.md +82 -0
- python_trueconf_bot-1.2.2/docs/hooks/llms_txt.py +573 -0
- python_trueconf_bot-1.2.2/docs/ru/examples/index.md +244 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/ru/index.md +4 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/ru/learn/filters.md +86 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/mkdocs.yml +10 -4
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/pyproject.toml +2 -1
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/python_trueconf_bot.egg-info/PKG-INFO +19 -11
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/python_trueconf_bot.egg-info/SOURCES.txt +16 -6
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/python_trueconf_bot.egg-info/requires.txt +1 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/_version.py +3 -3
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/client/bot.py +250 -45
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/dispatcher/router.py +133 -2
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/enums/incoming_update_method.py +2 -0
- python_trueconf_bot-1.2.2/trueconf/exceptions.py +113 -0
- python_trueconf_bot-1.2.2/trueconf/loggers.py +19 -0
- python_trueconf_bot-1.2.2/trueconf/methods/clear_chat_history.py +22 -0
- python_trueconf_bot-1.2.2/trueconf/methods/edit_chat_avatar.py +22 -0
- python_trueconf_bot-1.2.2/trueconf/methods/get_chat_participant.py +22 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/content/base.py +0 -1
- python_trueconf_bot-1.2.2/trueconf/types/content/edit_chat_title.py +8 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/input_file.py +1 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/last_message.py +12 -1
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/message.py +2 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/parser.py +8 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/requests/changed_file_upload_limits.py +2 -1
- python_trueconf_bot-1.2.2/trueconf/types/requests/cleared_chat_history.py +9 -0
- python_trueconf_bot-1.2.2/trueconf/types/requests/edited_chat_avatar.py +9 -0
- python_trueconf_bot-1.2.2/trueconf/types/responses/clear_chat_history_response.py +8 -0
- python_trueconf_bot-1.2.2/trueconf/types/responses/edit_chat_avatar_response.py +8 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/get_chat_by_id_response.py +1 -0
- python_trueconf_bot-1.2.2/trueconf/types/responses/get_chat_participant_response.py +12 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/get_file_info_response.py +10 -2
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/send_file_response.py +1 -0
- python_trueconf_bot-1.2.2/trueconf/utils/__init__.py +1 -0
- python_trueconf_bot-1.2.0b3/trueconf/utils/generate_secret_for_survey.py → python_trueconf_bot-1.2.2/trueconf/utils/_generate_secret_for_survey.py +1 -1
- python_trueconf_bot-1.2.0b3/trueconf/utils/token.py → python_trueconf_bot-1.2.2/trueconf/utils/_token.py +2 -2
- python_trueconf_bot-1.2.2/trueconf/utils/_version_checker.py +60 -0
- python_trueconf_bot-1.2.2/trueconf/utils/split_text.py +603 -0
- python_trueconf_bot-1.2.0b3/docs/en/examples/echo_bot.md +0 -28
- python_trueconf_bot-1.2.0b3/docs/en/examples/multibot.md +0 -11
- python_trueconf_bot-1.2.0b3/docs/ru/examples/echo_bot.md +0 -28
- python_trueconf_bot-1.2.0b3/docs/ru/examples/multibot.md +0 -10
- python_trueconf_bot-1.2.0b3/trueconf/exceptions.py +0 -21
- python_trueconf_bot-1.2.0b3/trueconf/loggers.py +0 -4
- python_trueconf_bot-1.2.0b3/trueconf/utils/__init__.py +0 -3
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/.github/workflows/docs.yml +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/.github/workflows/release-test.yml +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/.github/workflows/release.yml +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/.gitignore +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/LICENSE +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/assets/head_en.png +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/assets/head_ru.png +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/assets/logo.svg +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/features.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/img/head.png +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/img/router_scheme_en.svg +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/learn/enums.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/learn/getting-started.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/learn/parse-messages.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/learn/types.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/reference/Bot.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/reference/Dispatcher.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/reference/Enums.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/reference/Responses.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/reference/Router.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/reference/Types.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/reference/index.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/en/release_notes.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/img/chatbot.svg +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/img/favicon.ico +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/img/logo.svg +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/overrides/main.html +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/ru/features.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/ru/img/head.png +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/ru/img/router_scheme_ru.svg +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/ru/learn/enums.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/ru/learn/files.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/ru/learn/getting-started.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/ru/learn/parse-messages.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/ru/learn/types.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/ru/release_notes.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/docs/stylesheets/extra.css +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/examples/README-ru.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/examples/README.md +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/examples/add_big_list_users_to_channel.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/examples/filters.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/examples/report_bot.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/examples/update_token.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/examples/webhook.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/python_trueconf_bot.egg-info/dependency_links.txt +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/python_trueconf_bot.egg-info/top_level.txt +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/requirements-docs.txt +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/requirements.txt +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/setup.cfg +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/__init__.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/client/__init__.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/client/context_controller.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/client/session.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/dispatcher/__init__.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/dispatcher/dispatcher.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/enums/__init__.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/enums/aouth_error.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/enums/chat_participant_role.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/enums/chat_type.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/enums/envelope_author_type.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/enums/file_ready_state.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/enums/message_type.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/enums/parse_mode.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/enums/survey_type.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/enums/update_type.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/filters/__init__.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/filters/base.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/filters/command.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/filters/instance_of.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/filters/message.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/filters/method.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/__init__.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/add_participant_to_chat.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/auth.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/base.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/change_participant_role.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/create_channel.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/create_favorites_chat.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/create_group_chat.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/create_p2p_chat.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/edit_chat_title.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/edit_message.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/edit_survey.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/forward_message.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/get_chat_by_id.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/get_chat_history.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/get_chat_participants.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/get_chats.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/get_file_info.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/get_file_upload_limits.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/get_message_by_id.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/get_user_display_name.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/has_chat_participant.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/remove_chat.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/remove_message.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/remove_participant_from_chat.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/send_file.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/send_message.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/send_survey.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/subscribe_file_progress.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/unsubscribe_file_progress.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/methods/upload_file.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/py.typed +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/__init__.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/author_box.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/chat_participant.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/content/__init__.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/content/attachment.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/content/chat_created.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/content/document.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/content/forward_message.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/content/location.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/content/photo.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/content/remove_participant.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/content/sticker.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/content/survey.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/content/text.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/content/video.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/requests/__init__.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/requests/added_chat_participant.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/requests/changed_participant_role.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/requests/created_channel.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/requests/created_favorites_chat.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/requests/created_group_chat.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/requests/created_personal_chat.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/requests/edited_chat_title.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/requests/edited_message.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/requests/removed_chat.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/requests/removed_chat_participant.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/requests/removed_message.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/requests/uploading_progress.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/__init__.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/add_chat_participant_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/api_error.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/auth_response_payload.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/change_participant_role_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/create_channel_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/create_favorites_chat_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/create_group_chat_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/create_p2p_chat_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/edit_chat_title_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/edit_message_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/edit_survey_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/forward_message_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/get_chat_history_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/get_chat_participants_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/get_chats_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/get_file_upload_limits_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/get_message_by_id_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/get_user_display_name_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/has_chat_participant_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/remove_chat_participant_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/remove_chat_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/remove_message_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/send_message_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/send_survey_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/subscribe_file_progress_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/unsubscribe_file_progress_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/responses/upload_file_response.py +0 -0
- {python_trueconf_bot-1.2.0b3 → python_trueconf_bot-1.2.2}/trueconf/types/update.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-trueconf-bot
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
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
|
|
@@ -34,6 +34,7 @@ Requires-Dist: typing_extensions>=4.15.0
|
|
|
34
34
|
Requires-Dist: python-magic>=0.4.27; sys_platform != "win32"
|
|
35
35
|
Requires-Dist: python-magic-bin==0.4.14; sys_platform == "win32"
|
|
36
36
|
Requires-Dist: filetype
|
|
37
|
+
Requires-Dist: packaging
|
|
37
38
|
Dynamic: license-file
|
|
38
39
|
|
|
39
40
|
<p align="center">
|
|
@@ -77,23 +78,30 @@ Dynamic: license-file
|
|
|
77
78
|
> 💡TIP
|
|
78
79
|
>
|
|
79
80
|
> 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.
|
|
80
|
-
|
|
81
81
|
---
|
|
82
82
|
|
|
83
|
+
## ⚙️ Install
|
|
84
|
+
|
|
85
|
+
You can install `python-trueconf-bot` using `pip`:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
pip install python-trueconf-bot
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Or with `uv` (recommended):
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
uv add python-trueconf-bot
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
|
|
83
98
|
## 📦 Version Compatibility
|
|
84
99
|
|
|
85
100
|
| TrueConf Server Version | Required Library Version |
|
|
86
101
|
|:------------------------|:-------------------------|
|
|
87
|
-
| < 5.5.0 | ❌ Not supported
|
|
102
|
+
| < 5.5.0 | ❌ Not supported |
|
|
88
103
|
| 5.5.0 — 5.5.2 | v1.1.x |
|
|
89
|
-
| >= 5.5.3 | **v1.2.
|
|
90
|
-
|
|
91
|
-
> ⚠️ IMPORTANT
|
|
92
|
-
>
|
|
93
|
-
> If you are using server version **5.5.3** or higher, you must upgrade the library. If the stable release is not yet available, install the latest beta:
|
|
94
|
-
> ```bash
|
|
95
|
-
> uv pip install --pre "python-trueconf-bot>=1.2.0b0"
|
|
96
|
-
> ```
|
|
104
|
+
| >= 5.5.3 | **v1.2.1** (or higher) |
|
|
97
105
|
|
|
98
106
|
## 📌 Key Features
|
|
99
107
|
|
|
@@ -39,23 +39,30 @@
|
|
|
39
39
|
> 💡TIP
|
|
40
40
|
>
|
|
41
41
|
> 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.
|
|
42
|
-
|
|
43
42
|
---
|
|
44
43
|
|
|
44
|
+
## ⚙️ Install
|
|
45
|
+
|
|
46
|
+
You can install `python-trueconf-bot` using `pip`:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install python-trueconf-bot
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Or with `uv` (recommended):
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
uv add python-trueconf-bot
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
|
|
45
59
|
## 📦 Version Compatibility
|
|
46
60
|
|
|
47
61
|
| TrueConf Server Version | Required Library Version |
|
|
48
62
|
|:------------------------|:-------------------------|
|
|
49
|
-
| < 5.5.0 | ❌ Not supported
|
|
63
|
+
| < 5.5.0 | ❌ Not supported |
|
|
50
64
|
| 5.5.0 — 5.5.2 | v1.1.x |
|
|
51
|
-
| >= 5.5.3 | **v1.2.
|
|
52
|
-
|
|
53
|
-
> ⚠️ IMPORTANT
|
|
54
|
-
>
|
|
55
|
-
> If you are using server version **5.5.3** or higher, you must upgrade the library. If the stable release is not yet available, install the latest beta:
|
|
56
|
-
> ```bash
|
|
57
|
-
> uv pip install --pre "python-trueconf-bot>=1.2.0b0"
|
|
58
|
-
> ```
|
|
65
|
+
| >= 5.5.3 | **v1.2.1** (or higher) |
|
|
59
66
|
|
|
60
67
|
## 📌 Key Features
|
|
61
68
|
|
|
@@ -43,19 +43,27 @@
|
|
|
43
43
|
> знакомым с ней, переход будет **простым** и **безболезненным**.
|
|
44
44
|
|
|
45
45
|
---
|
|
46
|
+
## ⚙️ Устнановка
|
|
47
|
+
|
|
48
|
+
Вы можете установить `python-trueconf-bot` с помощью `pip`:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install python-trueconf-bot
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
или с помощью `uv` (предпочтительно):
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
uv add python-trueconf-bot
|
|
58
|
+
```
|
|
59
|
+
|
|
46
60
|
|
|
47
61
|
## 📦 Совместимость версий
|
|
48
62
|
| Версия сервера TrueConf | Требуемая версия библиотеки |
|
|
49
|
-
|
|
50
|
-
| < 5.5.0 | ❌ Не поддерживается
|
|
51
|
-
| 5.5.0 — 5.5.2 | v1.1.x
|
|
52
|
-
| \>= 5.5.3 | **v1.2.
|
|
53
|
-
|
|
54
|
-
> [!IMPORTANT]
|
|
55
|
-
> Если вы используете сервер версии **5.5.3** или выше, вам необходимо обновить библиотеку. Если стабильный релиз еще не доступен, установите последнюю бету:
|
|
56
|
-
> ```bash
|
|
57
|
-
> uv pip install --pre "python-trueconf-bot>=1.2.0b0"
|
|
58
|
-
> ```
|
|
63
|
+
|:------------------------|:----------------------------|
|
|
64
|
+
| < 5.5.0 | ❌ Не поддерживается |
|
|
65
|
+
| 5.5.0 — 5.5.2 | v1.1.x |
|
|
66
|
+
| \>= 5.5.3 | **v1.2.1** (или выше) |
|
|
59
67
|
|
|
60
68
|
## 📌 Ключевые возможности
|
|
61
69
|
|
|
@@ -46,20 +46,27 @@
|
|
|
46
46
|
> 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.
|
|
47
47
|
|
|
48
48
|
---
|
|
49
|
+
## ⚙️ Install
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
You can install `python-trueconf-bot` using `pip`:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install python-trueconf-bot
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Or with `uv` (recommended):
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
uv add python-trueconf-bot
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## 📦 Compatibility
|
|
51
64
|
|
|
52
65
|
| TrueConf Server Version | Required Library Version |
|
|
53
66
|
|:------------------------|:-------------------------|
|
|
54
|
-
| < 5.5.0 | ❌ Not supported
|
|
67
|
+
| < 5.5.0 | ❌ Not supported |
|
|
55
68
|
| 5.5.0 — 5.5.2 | v1.1.x |
|
|
56
|
-
| >= 5.5.3 | **v1.2.
|
|
57
|
-
|
|
58
|
-
> [!IMPORTANT]
|
|
59
|
-
> If you are using server version **5.5.3** or higher, you must upgrade the library. If the stable release is not yet available, install the latest beta:
|
|
60
|
-
> ```bash
|
|
61
|
-
> uv pip install --pre "python-trueconf-bot>=1.2.0b0"
|
|
62
|
-
> ```
|
|
69
|
+
| >= 5.5.3 | **v1.2.1** (or higher) |
|
|
63
70
|
|
|
64
71
|
## 📌 Key Features
|
|
65
72
|
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
## Echo bot
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
import asyncio
|
|
7
|
+
from trueconf import Bot, Dispatcher, Router, Message, F, ParseMode
|
|
8
|
+
from os import getenv
|
|
9
|
+
|
|
10
|
+
router = Router()
|
|
11
|
+
dp = Dispatcher()
|
|
12
|
+
dp.include_router(router)
|
|
13
|
+
|
|
14
|
+
TOKEN = getenv("TOKEN")
|
|
15
|
+
|
|
16
|
+
bot = Bot(server="video.example.com", token=TOKEN, dispatcher=dp)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@router.message(F.text)
|
|
20
|
+
async def echo(msg: Message):
|
|
21
|
+
await msg.answer(f"You says: **{msg.text}**", parse_mode=ParseMode.MARKDOWN)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
async def main():
|
|
25
|
+
await bot.run()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
if __name__ == "__main__":
|
|
29
|
+
asyncio.run(main())
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Webhook (e.g., for Zabbix)
|
|
33
|
+
|
|
34
|
+
In this example, you can see how easy it is to set up a webhook using FastAPI to receive requests from external systems, such as Zabbix.
|
|
35
|
+
|
|
36
|
+
You can also protect your webhook with authentication or allow requests only from specific IP addresses. All of this can be configured in [FastAPI](https://fastapi.tiangolo.com/).
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
import asyncio
|
|
40
|
+
import logging
|
|
41
|
+
import os
|
|
42
|
+
from typing import Any
|
|
43
|
+
from trueconf import Bot
|
|
44
|
+
from contextlib import asynccontextmanager
|
|
45
|
+
from fastapi import FastAPI
|
|
46
|
+
import uvicorn
|
|
47
|
+
|
|
48
|
+
os.makedirs("logs", exist_ok=True)
|
|
49
|
+
|
|
50
|
+
logging.basicConfig(
|
|
51
|
+
level=logging.DEBUG,
|
|
52
|
+
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
|
|
53
|
+
filename="logs/bot.log",
|
|
54
|
+
encoding="utf-8",
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
@asynccontextmanager
|
|
58
|
+
async def lifespan(app: FastAPI):
|
|
59
|
+
bot_task = asyncio.create_task(bot.run())
|
|
60
|
+
yield
|
|
61
|
+
|
|
62
|
+
app = FastAPI(lifespan=lifespan)
|
|
63
|
+
bot = Bot.from_credentials(
|
|
64
|
+
server="10.140.1.255",
|
|
65
|
+
username="echo_bot",
|
|
66
|
+
password="123tr",
|
|
67
|
+
verify_ssl=False)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@app.post("/send")
|
|
71
|
+
async def read_root(data: dict[str, Any]):
|
|
72
|
+
r = await bot.create_personal_chat(user_id="user")
|
|
73
|
+
r = await bot.send_message(chat_id = r.chat_id, text=str(data))
|
|
74
|
+
print(r.message_id)
|
|
75
|
+
|
|
76
|
+
if __name__ == "__main__":
|
|
77
|
+
uvicorn.run(app, host="0.0.0.0", port=8000)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Bulk add users to a channel
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from trueconf import Bot
|
|
84
|
+
from trueconf.exceptions import ApiErrorException
|
|
85
|
+
import asyncio
|
|
86
|
+
import logging
|
|
87
|
+
from pathlib import Path
|
|
88
|
+
|
|
89
|
+
SERVER_ADDR = ""
|
|
90
|
+
BOT_USERNAME = ""
|
|
91
|
+
BOT_PASSWORD = ""
|
|
92
|
+
PATH_LIST_USERS = ""
|
|
93
|
+
CHANNEL_NAME = ""
|
|
94
|
+
|
|
95
|
+
bot = Bot.from_credentials(
|
|
96
|
+
server=SERVER_ADDR,
|
|
97
|
+
username=BOT_USERNAME,
|
|
98
|
+
password=BOT_PASSWORD,
|
|
99
|
+
verify_ssl=False,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
Path("logs").mkdir(parents=True, exist_ok=True)
|
|
103
|
+
|
|
104
|
+
logging.basicConfig(
|
|
105
|
+
level=logging.DEBUG,
|
|
106
|
+
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
|
|
107
|
+
filename="logs/bot.log",
|
|
108
|
+
encoding="utf-8",
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
async def main():
|
|
112
|
+
await bot.start()
|
|
113
|
+
await bot.connected_event.wait()
|
|
114
|
+
await bot.authorized_event.wait()
|
|
115
|
+
|
|
116
|
+
resp = await bot.create_channel(title=CHANNEL_NAME)
|
|
117
|
+
with open(PATH_LIST_USERS, "r") as file:
|
|
118
|
+
for line in file:
|
|
119
|
+
user_id = line.strip()
|
|
120
|
+
if user_id:
|
|
121
|
+
try:
|
|
122
|
+
await bot.add_participant_to_chat(resp.chat_id, user_id=user_id, display_history=True)
|
|
123
|
+
except ApiErrorException as e:
|
|
124
|
+
if e.code == 309:
|
|
125
|
+
continue
|
|
126
|
+
|
|
127
|
+
await bot.shutdown()
|
|
128
|
+
|
|
129
|
+
if __name__ == "__main__":
|
|
130
|
+
asyncio.run(main())
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Multibot
|
|
134
|
+
|
|
135
|
+
The TrueConf team has prepared an example that demonstrates the use of four bots at once (all-in-one):
|
|
136
|
+
|
|
137
|
+
- Echo bot
|
|
138
|
+
- Sick-leave bot that forwards messages to an HR group
|
|
139
|
+
- Monitoring bot for external service statistics (TrueConf Server)
|
|
140
|
+
- GPT bot that runs a local LLM model in the background
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
[View repository :fontawesome-solid-arrow-right:](https://github.com/TrueConf/trueconf-chatbot-example){ .md-button }
|
|
144
|
+
|
|
145
|
+
## Support Reporting Bot
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
"""
|
|
149
|
+
Below is the initial scaffold for a bot that collects support reports.
|
|
150
|
+
|
|
151
|
+
- /report creates a router/state to capture and parse messages from a specific user.
|
|
152
|
+
- /cancel cancels the ticket and removes the user from this state.
|
|
153
|
+
- /send emails the collected messages — this is where you implement the logic to assemble the email (body + attachments) and send it.
|
|
154
|
+
You can use built-in modules, and third-party libraries if needed.
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
import asyncio
|
|
158
|
+
import uuid
|
|
159
|
+
import trueconf
|
|
160
|
+
from trueconf import *
|
|
161
|
+
from trueconf.filters import Command
|
|
162
|
+
|
|
163
|
+
r1 = Router()
|
|
164
|
+
dp = Dispatcher()
|
|
165
|
+
dp.include_router(r1)
|
|
166
|
+
|
|
167
|
+
router_list_for_report = {}
|
|
168
|
+
list_message_for_report = {}
|
|
169
|
+
|
|
170
|
+
bot = trueconf.Bot.from_credentials(
|
|
171
|
+
server="10.110.2.241",
|
|
172
|
+
username="report_bot",
|
|
173
|
+
password="123tr",
|
|
174
|
+
dispatcher=dp,
|
|
175
|
+
https=True,
|
|
176
|
+
verify_ssl=False)
|
|
177
|
+
|
|
178
|
+
async def handle_report(msg: Message):
|
|
179
|
+
if msg.from_user.id in router_list_for_report.keys():
|
|
180
|
+
list_message_for_report[msg.from_user.id].append(msg)
|
|
181
|
+
await msg.answer("The message has been added to the report.")
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
@r1.message(Command("report"))
|
|
185
|
+
async def on_report(msg: Message):
|
|
186
|
+
number = uuid.uuid4() # генерация номера обращения с помощью uuid
|
|
187
|
+
await msg.answer(f"Your ticket number is {number}. All subsequent messages will be added to this ticket.")
|
|
188
|
+
r = Router(name=str(number))
|
|
189
|
+
dp.include_router(r)
|
|
190
|
+
r.message(F.from_user.id == msg.from_user.id)(handle_report)
|
|
191
|
+
router_list_for_report.update({msg.from_user.id: r})
|
|
192
|
+
list_message_for_report.update({msg.from_user.id: []})
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
@r1.message(Command("cancel"))
|
|
196
|
+
async def on_cancel(msg: Message):
|
|
197
|
+
if msg.from_user.id in router_list_for_report.keys():
|
|
198
|
+
for router in dp.routers:
|
|
199
|
+
if router.name == router_list_for_report[msg.from_user.id].name:
|
|
200
|
+
dp.routers.remove(router)
|
|
201
|
+
router_list_for_report.pop(msg.from_user.id)
|
|
202
|
+
list_message_for_report.pop(msg.from_user.id)
|
|
203
|
+
await msg.answer("The report has been cancelled.")
|
|
204
|
+
break
|
|
205
|
+
else:
|
|
206
|
+
await msg.answer("You don’t have an active report.")
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def build_message_and_send_email(messages:list):
|
|
210
|
+
"""
|
|
211
|
+
In Python, there are built-in libraries for working with email messages:
|
|
212
|
+
https://docs.python.org/3/library/email.examples.html
|
|
213
|
+
|
|
214
|
+
Here, you need to take the data from list_message_for_report[msg.from_user.id]
|
|
215
|
+
and build an email-ready representation:
|
|
216
|
+
|
|
217
|
+
for msg in message:
|
|
218
|
+
match msg.content_type:
|
|
219
|
+
case MessageType.TEXT:
|
|
220
|
+
# You can put the text into the email body
|
|
221
|
+
case MessageType.ATTACHMENT:
|
|
222
|
+
# Download the files from TrueConf Server via:
|
|
223
|
+
# msg.download(dest_path="path/to/file")
|
|
224
|
+
|
|
225
|
+
Once the email is assembled correctly, send it using the smtplib module:
|
|
226
|
+
https://docs.python.org/3/library/smtplib.html#smtp-example
|
|
227
|
+
"""
|
|
228
|
+
|
|
229
|
+
@r1.message(Command("send"))
|
|
230
|
+
async def send_report(msg: Message):
|
|
231
|
+
if msg.from_user.id in router_list_for_report.keys():
|
|
232
|
+
if build_message_and_send_email(list_message_for_report[msg.from_user.id]):
|
|
233
|
+
await msg.answer("Your request has been successfully submitted to Technical Support.")
|
|
234
|
+
else:
|
|
235
|
+
await msg.answer("An error occurred. Please contact the bot developer.")
|
|
236
|
+
else:
|
|
237
|
+
await msg.answer("You don’t have an active report.")
|
|
238
|
+
return
|
|
239
|
+
|
|
240
|
+
if __name__ == "__main__":
|
|
241
|
+
asyncio.run(bot.run())
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
|
|
@@ -41,3 +41,8 @@ pip install {{product_name}}
|
|
|
41
41
|
| JSON → Python | Pydantic models | Mashumaro dataclasses |
|
|
42
42
|
| Transport | HTTPS + long polling / webhook | Asynchronous WebSocket |
|
|
43
43
|
| Working with files | `bot.get_file(...)` + `bot.download_file(...)` | `message.photo.download()`, `message.document.download()`, `bot.download_file_by_id(...)` |
|
|
44
|
+
|
|
45
|
+
## LLM Files
|
|
46
|
+
|
|
47
|
+
- [llms.txt](llms.txt)
|
|
48
|
+
- [llms-full.txt](llms-full.txt)
|
|
@@ -141,3 +141,49 @@ await bot.download_file_by_id(
|
|
|
141
141
|
dest_path="document.pdf"
|
|
142
142
|
)
|
|
143
143
|
```
|
|
144
|
+
|
|
145
|
+
## MIME Type Detection with python-magic
|
|
146
|
+
|
|
147
|
+
A file’s MIME type can be detected automatically. The library supports two approaches:
|
|
148
|
+
|
|
149
|
+
* **By file extension** — works without additional dependencies, but may be inaccurate.
|
|
150
|
+
* **By file content (bytes)** — significantly more accurate, but requires `python-magic`.
|
|
151
|
+
|
|
152
|
+
### How It Works
|
|
153
|
+
|
|
154
|
+
The `python-magic` package does not determine MIME types on its own. It is a Python wrapper around the native **libmagic** library written in C, which is what actually identifies a file type based on its contents.
|
|
155
|
+
|
|
156
|
+
That is why `python-magic` may not work out of the box on some systems: the Python package is installed via `pip`, but the system library `libmagic` must be installed separately.
|
|
157
|
+
|
|
158
|
+
If `libmagic` is missing, importing `magic` may fail with an error such as:
|
|
159
|
+
|
|
160
|
+
* `ImportError: failed to find libmagic. Check your installation`
|
|
161
|
+
|
|
162
|
+
### Installation
|
|
163
|
+
|
|
164
|
+
Install the system dependencies:
|
|
165
|
+
|
|
166
|
+
* **macOS (Homebrew):**
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
brew install libmagic
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
* **Linux (Debian/Ubuntu):**
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
sudo apt install libmagic1
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
* **Windows:**
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
pip install python-magic-bin
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
We also recommend reviewing the repository: [https://github.com/ahupp/python-magic](https://github.com/ahupp/python-magic).
|
|
185
|
+
|
|
186
|
+
### Notes
|
|
187
|
+
|
|
188
|
+
* When `python-magic` is available, the MIME type is detected **from the file bytes**, which is usually more accurate than detecting it by filename or extension.
|
|
189
|
+
|
|
@@ -215,8 +215,90 @@ F.text.upper().in_({"FOO", "BAR"}) # message.text.upper() in {"FOO", "BAR"}
|
|
|
215
215
|
F.text.len() == 5 # len(message.text) == 5
|
|
216
216
|
```
|
|
217
217
|
|
|
218
|
+
## Building Custom Filters
|
|
219
|
+
|
|
220
|
+
You can build custom filters to fine-tune your event-handling logic. This allows you to move condition checks—such as verifying whether a user exists in the database or checking access permissions—into a separate, reusable component.
|
|
221
|
+
|
|
222
|
+
**Implementation requirements:**
|
|
223
|
+
|
|
224
|
+
* **Class-based structure:** A custom filter must be implemented as a class. This makes it possible to preserve state, such as filter settings, when the filter is initialized.
|
|
225
|
+
* **`__call__` method:** The class must implement a `__call__` method. Without it, the class instance will not be considered callable, and the filter will not work.
|
|
226
|
+
* **Return value:** The `__call__` method must return `True` if the event matches the filter conditions, or `False` if the event should be ignored by the handler.
|
|
227
|
+
|
|
228
|
+
```python
|
|
229
|
+
from typing import Any
|
|
230
|
+
|
|
231
|
+
class MyFilter:
|
|
232
|
+
"""
|
|
233
|
+
This filter checks whether a user belongs
|
|
234
|
+
to the specified group via the server API.
|
|
235
|
+
"""
|
|
236
|
+
|
|
237
|
+
def __init__(self, target_group: str):
|
|
238
|
+
# Store the required group when creating the instance
|
|
239
|
+
self.target_group = target_group
|
|
240
|
+
|
|
241
|
+
async def __call__(self, event: Any) -> bool:
|
|
242
|
+
user = getattr(event, "from_user", None)
|
|
243
|
+
if not user:
|
|
244
|
+
return False
|
|
245
|
+
|
|
246
|
+
user_id = user.id
|
|
247
|
+
# Perform the check, for example via an API call
|
|
248
|
+
user_info: dict = await server_api.get_user(user_id)
|
|
249
|
+
groups = user_info.get("groups", [])
|
|
250
|
+
|
|
251
|
+
# Make sure to return True or False
|
|
252
|
+
return any(group.get("id") == self.target_group for group in groups)
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Once the filter class is defined, you can use it in handler decorators exactly the same way as the built-in **Command** or **F** filters. When registering a handler, simply pass an instance of your class as an argument.
|
|
256
|
+
|
|
257
|
+
```python hl_lines="8"
|
|
258
|
+
from aiogram import Router, Message
|
|
259
|
+
# Import your filter class
|
|
260
|
+
from my_filters import MyFilter
|
|
261
|
+
|
|
262
|
+
router = Router()
|
|
263
|
+
|
|
264
|
+
# Attach the filter in the same way as Command or F
|
|
265
|
+
@router.message(MyFilter(target_group="0032"))
|
|
266
|
+
async def my_handler(message: Message):
|
|
267
|
+
await message.answer("Access granted: you belong to the required group!")
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
When a message is received, the bot will use the class instance, call its `__call__` method, and, if it returns `True`, execute the handler code.
|
|
271
|
+
|
|
218
272
|
## Combining Filters
|
|
219
273
|
|
|
274
|
+
In **python-trueconf-bot**, you can combine multiple filters within a single handler. By default, when filters are separated by commas, they use **AND** logic—the handler will run only if **all** filters return `True`.
|
|
275
|
+
|
|
276
|
+
**Command and a custom filter**
|
|
277
|
+
|
|
278
|
+
You can restrict access to a specific command by using your own filter. The handler will run only if the message is the specified command **and** your filter returns `True`.
|
|
279
|
+
|
|
280
|
+
```python
|
|
281
|
+
# Triggers if the /admin command is received
|
|
282
|
+
# AND the user belongs to group "0032"
|
|
283
|
+
@r.message(Command("admin"), InGroupFilter(target_group="0032"))
|
|
284
|
+
async def admin_panel(message: Message):
|
|
285
|
+
await message.answer("Welcome to the admin panel!")
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**MagicFilter (F) and a custom filter**
|
|
289
|
+
|
|
290
|
+
Combine message-content checks with your own access rules. For example, you can react to a specific word in the text only for users from certain groups:
|
|
291
|
+
|
|
292
|
+
```python
|
|
293
|
+
# Triggers if the text contains "help"
|
|
294
|
+
# AND the user belongs to the "support" group
|
|
295
|
+
@r.message(F.text.contains("help"), InGroupFilter(target_group="0003"))
|
|
296
|
+
async def support_handler(message: Message):
|
|
297
|
+
await message.answer("The support team has been notified of your request.")
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Combining Command Arguments and MagicFilter
|
|
301
|
+
|
|
220
302
|
Combining **Command** and **MagicFilter** is a common and recommended practice:
|
|
221
303
|
**Command** parses the command and creates a **CommandObject**, while `magic`
|
|
222
304
|
allows you to impose additional conditions on `args` or other parts of the
|