from __future__ import annotations import logging from typing import Any logger = logging.getLogger(__name__) class TelegramChat: def __init__(self, outbound): self._outbound = outbound async def _call(self, token: str, method: str, payload: dict) -> dict | list | int | None: return await self._outbound._api_call(token, method, payload) async def get_chat(self, account_id: str, chat_id: str) -> dict | None: token = await self._resolve_token(account_id) if not token: return None result = await self._call(token, "getChat", {"chat_id": chat_id}) return result if isinstance(result, dict) else None async def get_chat_member( self, account_id: str, chat_id: str, user_id: int, ) -> dict | None: token = await self._resolve_token(account_id) if not token: return None result = await self._call( token, "getChatMember", {"chat_id": chat_id, "user_id": user_id}, ) return result if isinstance(result, dict) else None async def get_chat_member_count(self, account_id: str, chat_id: str) -> int | None: token = await self._resolve_token(account_id) if not token: return None result = await self._call(token, "getChatMemberCount", {"chat_id": chat_id}) return result if isinstance(result, int) else None async def get_chat_administrators(self, account_id: str, chat_id: str) -> list[dict] | None: token = await self._resolve_token(account_id) if not token: return None result = await self._call(token, "getChatAdministrators", {"chat_id": chat_id}) return result if isinstance(result, list) else None async def get_user_profile_photos( self, account_id: str, user_id: int, *, limit: int = 100, ) -> dict | None: token = await self._resolve_token(account_id) if not token: return None result = await self._call( token, "getUserProfilePhotos", {"user_id": user_id, "limit": limit}, ) return result if isinstance(result, dict) else None async def pin_message( self, account_id: str, chat_id: str, message_id: int, *, disable_notification: bool = False, ) -> bool: token = await self._resolve_token(account_id) if not token: return False result = await self._call( token, "pinChatMessage", {"chat_id": chat_id, "message_id": message_id, "disable_notification": disable_notification}, ) return result is not None and not isinstance(result, dict) async def unpin_message( self, account_id: str, chat_id: str, message_id: int | None = None, ) -> bool: token = await self._resolve_token(account_id) if not token: return False payload: dict[str, Any] = {"chat_id": chat_id} if message_id: payload["message_id"] = message_id result = await self._call(token, "unpinChatMessage", payload) return result is not None and not isinstance(result, dict) async def create_forum_topic( self, account_id: str, chat_id: str, name: str, *, icon_color: int | None = None, icon_custom_emoji_id: str | None = None, ) -> dict | None: token = await self._resolve_token(account_id) if not token: return None payload: dict[str, Any] = {"chat_id": chat_id, "name": name} if icon_color is not None: payload["icon_color"] = icon_color if icon_custom_emoji_id: payload["icon_custom_emoji_id"] = icon_custom_emoji_id result = await self._call(token, "createForumTopic", payload) return result if isinstance(result, dict) else None async def close_forum_topic( self, account_id: str, chat_id: str, message_thread_id: int, ) -> bool: token = await self._resolve_token(account_id) if not token: return False result = await self._call( token, "closeForumTopic", {"chat_id": chat_id, "message_thread_id": message_thread_id}, ) return result is not None and not isinstance(result, dict) async def reopen_forum_topic( self, account_id: str, chat_id: str, message_thread_id: int, ) -> bool: token = await self._resolve_token(account_id) if not token: return False result = await self._call( token, "reopenForumTopic", {"chat_id": chat_id, "message_thread_id": message_thread_id}, ) return result is not None and not isinstance(result, dict) async def delete_forum_topic( self, account_id: str, chat_id: str, message_thread_id: int, ) -> bool: token = await self._resolve_token(account_id) if not token: return False result = await self._call( token, "deleteForumTopic", {"chat_id": chat_id, "message_thread_id": message_thread_id}, ) return result is not None and not isinstance(result, dict) async def edit_forum_topic( self, account_id: str, chat_id: str, message_thread_id: int, *, name: str | None = None, icon_custom_emoji_id: str | None = None, ) -> bool: token = await self._resolve_token(account_id) if not token: return False payload: dict[str, Any] = {"chat_id": chat_id, "message_thread_id": message_thread_id} if name: payload["name"] = name if icon_custom_emoji_id: payload["icon_custom_emoji_id"] = icon_custom_emoji_id result = await self._call(token, "editForumTopic", payload) return result is not None and not isinstance(result, dict) async def edit_general_forum_topic( self, account_id: str, chat_id: str, name: str, ) -> bool: token = await self._resolve_token(account_id) if not token: return False result = await self._call( token, "editGeneralForumTopic", {"chat_id": chat_id, "name": name}, ) return result is not None and not isinstance(result, dict) async def set_chat_member_tag( self, account_id: str, chat_id: str, user_id: int, tag: str, ) -> bool: token = await self._resolve_token(account_id) if not token: return False result = await self._call( token, "setChatMemberTag", {"chat_id": chat_id, "user_id": user_id, "tag": tag}, ) return result is not None and not isinstance(result, dict) async def _resolve_token(self, account_id: str | None) -> str: from yuxi.channel.extensions.telegram.config import TelegramConfigAdapter adapter = TelegramConfigAdapter() aid = account_id or "default" account = await adapter.resolve_account(aid) return account.get("token", "")