From 52dce1b2b810fab6eadb2581a37e96f80f6c0f7f Mon Sep 17 00:00:00 2001 From: Arity-T Date: Mon, 2 Feb 2026 21:31:51 +0300 Subject: [PATCH] feat: add polish and fallback handlers - Add fallback handler for unexpected text messages - Remove unused require_states alias - Update TASK.md - all stages complete --- main.py | 6 +++--- src/decorators.py | 3 --- src/handlers.py | 27 +++++++++++++++++++++++++-- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/main.py b/main.py index 057ef61..463dac2 100644 --- a/main.py +++ b/main.py @@ -24,6 +24,7 @@ from src.handlers import ( handle_rerecord_previous, handle_restart_track, handle_save_track, + handle_unexpected_text, handle_voice_message, start_command, ) @@ -76,10 +77,9 @@ def main() -> None: # Message handlers app.add_handler(MessageHandler(filters.VOICE, handle_voice_message)) - app.add_handler( - MessageHandler(filters.TEXT & ~filters.COMMAND, handle_replica_number_input) - ) app.add_handler(MessageHandler(filters.Document.ALL, handle_admin_document)) + app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_replica_number_input)) + app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_unexpected_text)) logger.info("Бот запущен") app.run_polling() diff --git a/src/decorators.py b/src/decorators.py index e2d02b8..34b2d78 100644 --- a/src/decorators.py +++ b/src/decorators.py @@ -71,6 +71,3 @@ def require_state(*states: UserState): return decorator -def require_states(*states: UserState): - """Алиас для require_state с несколькими состояниями.""" - return require_state(*states) diff --git a/src/handlers.py b/src/handlers.py index 4887f03..d8c17b9 100644 --- a/src/handlers.py +++ b/src/handlers.py @@ -630,11 +630,13 @@ async def handle_voice_message( @with_user_and_session -@require_state(UserState.ASK_REPLICA_NUMBER) async def handle_replica_number_input( - update: Update, context: ContextTypes.DEFAULT_TYPE, user: User, session: UserSession + update: Update, context: ContextTypes.DEFAULT_TYPE, user: User, session: UserSession | None ) -> None: """Обработчик ввода номера реплики.""" + if not session or session.state != UserState.ASK_REPLICA_NUMBER: + return # Пропускаем, fallback обработает + text = update.message.text.strip() track_length = get_track_length(session.scenario_id, session.speaker_id) @@ -703,3 +705,24 @@ async def handle_admin_document( ) session.last_bot_message_id = msg_id upsert_user_session(session) + + +# === Fallback handlers === + + +VOICE_EXPECTED_TEXT = "❌ Пожалуйста, отправьте голосовое сообщение с озвучкой реплики." + + +@with_user_and_session +async def handle_unexpected_text( + update: Update, context: ContextTypes.DEFAULT_TYPE, user: User, session: UserSession | None +) -> None: + """Обработчик неожиданных текстовых сообщений.""" + if not session: + await update.message.reply_text("Используйте /start для начала работы с ботом.") + return + + voice_states = {UserState.FIRST_REPLICA, UserState.SHOW_REPLICA, UserState.REPEAT_REPLICA} + if session.state in voice_states: + await update.message.reply_text(VOICE_EXPECTED_TEXT) + # В других состояниях игнорируем текст (например, INTRO, NO_MORE_SCENARIOS)