from __future__ import annotations import logging from enum import StrEnum logger = logging.getLogger(__name__) class TelegramAction(StrEnum): REACT = "react" SEND = "send" POLL = "poll" STICKER = "sticker" DELETE = "delete" EDIT = "edit" TYPING = "typing" class ReactionLevel(StrEnum): OFF = "off" ACK = "ack" MINIMAL = "minimal" REACTION_LEVEL_EMOJI = { "typing": "👀", "done": "✅", "error": "❌", "thinking": "🤔", } def resolve_reaction_emoji(level: str, action: str = "typing") -> str | None: if level == "off": return None if level == "ack" and action == "typing": return REACTION_LEVEL_EMOJI["typing"] if level == "minimal": return REACTION_LEVEL_EMOJI.get(action) return None class TelegramActions: @staticmethod async def react( outbound, target_id: str, message_id: str, level: str, account_id: str | None = None, ) -> None: emoji = resolve_reaction_emoji(level, "typing") if not emoji: return await outbound.send_reaction(target_id, message_id, emoji, account_id=account_id) @staticmethod async def clear_reaction( outbound, target_id: str, message_id: str, account_id: str | None = None, ) -> None: try: await outbound.send_reaction(target_id, message_id, "", account_id=account_id) except Exception: logger.debug("Failed to clear reaction", exc_info=True) @staticmethod async def send_typing( outbound, target_id: str, thread_id: str | None = None, account_id: str | None = None, ) -> None: await outbound.send_typing(target_id, thread_id=thread_id, account_id=account_id) @staticmethod async def delete_message( outbound, target_id: str, message_id: str, account_id: str | None = None, ) -> None: await outbound.delete_message(target_id, message_id, account_id=account_id) @staticmethod def get_action_whitelist(account: dict) -> list[str]: actions = [] if account.get("actions_send_message", True): actions.append("send") if account.get("actions_reactions", True): actions.append("react") if account.get("actions_poll", True): actions.append("poll") if account.get("actions_sticker", True): actions.append("sticker") return actions