diff --git a/LichessClientTG_bot/bot.py b/LichessClientTG_bot/bot.py index daba2ca..5b088d6 100644 --- a/LichessClientTG_bot/bot.py +++ b/LichessClientTG_bot/bot.py @@ -340,6 +340,11 @@ class LichessBot: logger.info(f"addgamer_start called for user {user_id}") lang = self.get_user_language_from_update(update) + # Mark that we're awaiting a username right away: the menu below is shown + # so a user typing the name directly (without tapping a button) is handled + # too, instead of being silently ignored by handle_username. + if context and hasattr(context, "user_data"): + context.user_data['awaiting_addgamer_username'] = True try: keyboard = [ [ @@ -365,6 +370,10 @@ class LichessBot: logger.error(f"Error sending addgamer menu: {e}") import traceback logger.error(traceback.format_exc()) + try: + await update.message.reply_text(t('addgamer_menu_error', lang)) + except Exception as e2: + logger.error(f"Failed to send addgamer menu error message: {e2}") # No conversation state returned; handler-based flow return @@ -603,6 +612,14 @@ class LichessBot: # Check if user exists on Lichess user_exists = await self.lichess_api.check_user_exists(username) + if user_exists is None: + # Transient API failure (rate limit, network error, unexpected status) — + # don't tell the user the name is wrong, it may well be valid. + await update.message.reply_text( + t('lichess_temporarily_unavailable', lang) + '\n\n' + t('addgamer_prompt', lang), + parse_mode='HTML' + ) + return if not user_exists: await update.message.reply_text( t('user_not_found', lang, username=username) + '\n\n' + t('addgamer_prompt', lang), diff --git a/LichessClientTG_bot/i18n.py b/LichessClientTG_bot/i18n.py index e6d1ac3..ef4ec94 100644 --- a/LichessClientTG_bot/i18n.py +++ b/LichessClientTG_bot/i18n.py @@ -52,6 +52,7 @@ TRANSLATIONS = { 'addgamer_btn_add': "➕ Add player", 'addgamer_btn_how': "❓ How to add a player?", 'addgamer_prompt': "👤 Enter the Lichess username of the player to track:", + 'addgamer_menu_error': "❌ Something went wrong showing the menu. Please try /addgamer again, or just send the Lichess username directly.", 'addgamer_after_help': ( "Now send the Lichess username of the player you want to track.\n\n" "Example: MagnusCarlsen\n\n" @@ -69,6 +70,7 @@ TRANSLATIONS = { 'token_username_error': "❌ Failed to get username from token. Please try again.", 'empty_username': "❌ Username cannot be empty. Please try again.", 'user_not_found': "❌ Player {username} not found on Lichess. Check the spelling of the name.", + 'lichess_temporarily_unavailable': "⚠️ Lichess is temporarily unavailable. Please try again in a minute.", 'gamer_already_added': "ℹ️ Player {username} is already being tracked.\n\nTo add another player, use /addgamer", # Get gamers @@ -189,6 +191,7 @@ TRANSLATIONS = { 'addgamer_btn_add': "➕ Добавить игрока", 'addgamer_btn_how': "❓ Как добавить игрока?", 'addgamer_prompt': "👤 Введите username игрока Lichess для отслеживания:", + 'addgamer_menu_error': "❌ Не удалось показать меню. Попробуйте /addgamer ещё раз, либо просто отправьте username игрока Lichess напрямую.", 'addgamer_after_help': ( "Теперь отправьте username игрока Lichess, которого хотите отслеживать.\n\n" "Пример: MagnusCarlsen\n\n" @@ -206,6 +209,7 @@ TRANSLATIONS = { 'token_username_error': "❌ Не удалось получить username из токена. Попробуйте еще раз.", 'empty_username': "❌ Username не может быть пустым. Попробуйте еще раз.", 'user_not_found': "❌ Игрок {username} не найден на Lichess. Проверьте правильность написания имени.", + 'lichess_temporarily_unavailable': "⚠️ Lichess временно недоступен. Попробуйте, пожалуйста, через минуту.", 'gamer_already_added': "ℹ️ Игрок {username} уже отслеживается.\n\nДля добавления следующего игрока воспользуйтесь /addgamer", # Get gamers diff --git a/LichessClientTG_bot/lichess_api.py b/LichessClientTG_bot/lichess_api.py index 8271403..7c9c522 100644 --- a/LichessClientTG_bot/lichess_api.py +++ b/LichessClientTG_bot/lichess_api.py @@ -145,8 +145,15 @@ class LichessAPI: logger.error(f"Error getting puzzles period: {e}") return None - async def check_user_exists(self, username: str) -> bool: - """Check if user exists on Lichess""" + async def check_user_exists(self, username: str) -> Optional[bool]: + """ + Check if user exists on Lichess. + + Returns True/False for a definitive answer (200/404), or None if the + check itself failed (rate limit, network error, unexpected status) — + callers must not treat None as "not found", since the username may + well be valid. + """ await self.rate_limiter.wait_if_needed() try: async with aiohttp.ClientSession() as session: @@ -160,10 +167,10 @@ class LichessAPI: return False else: logger.error(f"Failed to check user existence: {response.status}") - return False + return None except Exception as e: logger.error(f"Error checking user existence: {e}") - return False + return None async def get_user_ratings(self, username: str) -> Optional[Dict[str, Any]]: """Get user ratings from Lichess API"""