54 lines
2.0 KiB
Python
54 lines
2.0 KiB
Python
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
|