import logging from aiogram.exceptions import TelegramAPIError, TelegramBadRequest, TelegramForbiddenError logger = logging.getLogger(__name__) # Errors that mean the user is definitively NOT in the chat _NOT_MEMBER_PHRASES = ( "user not found", "participant not found", "user_not_participant", "chat not found", "bot was kicked", "bot is not a member", ) # Errors that mean we simply can't verify (privacy / anonymous mode) - allow through _UNVERIFIABLE_PHRASES = ( "user_id_invalid", "have no rights", "not enough rights", "administrators only", ) async def check_membership(chat_id: int, user_id: int) -> bool: """Check if a user is an active member of a Telegram chat. Returns True when membership is confirmed OR when the check cannot be performed due to anonymous/privacy settings (bot has admin rights but Telegram hides the member - treat as verified to avoid false rejections). """ from app.bot.router import bot try: member = await bot.get_chat_member(chat_id, user_id) return member.status in ("member", "administrator", "creator", "restricted") except TelegramBadRequest as e: msg = str(e).lower() if any(p in msg for p in _NOT_MEMBER_PHRASES): return False if any(p in msg for p in _UNVERIFIABLE_PHRASES): logger.debug("Membership unverifiable for user %s in chat %s (%s) - allowing", user_id, chat_id, e) return True # Unknown bad request - conservative deny logger.warning("getChatMember bad request for user %s in chat %s: %s", user_id, chat_id, e) return False except TelegramForbiddenError as e: # Bot removed from chat or no rights at all logger.warning("getChatMember forbidden for chat %s: %s", chat_id, e) return False except TelegramAPIError as e: logger.warning("getChatMember error for user %s in chat %s: %s", user_id, chat_id, e) return False