import re from yuxi.channel.extensions.twitch.config import TwitchAccountConfig from yuxi.channel.extensions.twitch.types import TwitchAccessControlResult, TwitchChatMessage, TwitchRole def check_twitch_access_control( message: TwitchChatMessage, account: TwitchAccountConfig, bot_username: str, ) -> TwitchAccessControlResult: if account.require_mention and not _mentions_bot(message.message, bot_username): return TwitchAccessControlResult( allowed=False, reason="message does not mention the bot", ) if account.allow_from: if not message.user_id: return TwitchAccessControlResult( allowed=False, reason="sender user ID not available", ) if message.user_id not in account.allow_from: return TwitchAccessControlResult( allowed=False, reason=f"user {message.user_id} not in allowlist", ) return TwitchAccessControlResult( allowed=True, match_key=message.user_id, match_source="allowlist", ) if account.allowed_roles: for role in account.allowed_roles: if role == TwitchRole.ALL: return TwitchAccessControlResult( allowed=True, match_key="all", match_source="role", ) if role == TwitchRole.MODERATOR and message.is_mod: return TwitchAccessControlResult(allowed=True, match_key="moderator", match_source="role") if role == TwitchRole.OWNER and message.is_owner: return TwitchAccessControlResult(allowed=True, match_key="owner", match_source="role") if role == TwitchRole.VIP and message.is_vip: return TwitchAccessControlResult(allowed=True, match_key="vip", match_source="role") if role == TwitchRole.SUBSCRIBER and message.is_sub: return TwitchAccessControlResult(allowed=True, match_key="subscriber", match_source="role") return TwitchAccessControlResult( allowed=False, reason="sender does not have required roles", ) return TwitchAccessControlResult(allowed=True) def _mentions_bot(message_text: str, bot_username: str) -> bool: mentions = re.findall(r"@(\w+)", message_text) bot_lower = bot_username.lower() return any(m.lower() == bot_lower for m in mentions)