import logging from yuxi.channel.protocols import AgentToolParam, MessageActionCapability logger = logging.getLogger(__name__) class ZoomActions: def __init__(self, outbound=None): self._outbound = outbound def get_message_actions(self) -> list[MessageActionCapability]: return [ MessageActionCapability( action="send", description="通过 Zoom Chat API 发送纯文本消息", parameters=[ AgentToolParam( name="target_id", type="string", description="目标频道ID或联系人email", required=True, ), AgentToolParam(name="content", type="string", description="消息内容", required=True), ], scope="current_channel", ), MessageActionCapability( action="react", description="向消息添加 Emoji 反应", parameters=[ AgentToolParam(name="message_id", type="string", description="消息ID", required=True), AgentToolParam(name="emoji", type="string", description="Emoji 名称 (如 thumbsup)", required=True), ], scope="current_channel", ), ] async def execute_message_action(self, action: str, params: dict, context: dict) -> dict: match action: case "send": return {"success": True, "result": {"action": "send", "params": params}} case "react": return await self._do_react(params) case _: return {"success": False, "error": f"Unsupported action: {action}"} async def _do_react(self, params: dict) -> dict: if not self._outbound: return {"success": False, "error": "Outbound not available"} from yuxi.channel.extensions.zoomchat.reactions import emoji_to_zoom_reaction message_id = params.get("message_id", "") emoji = params.get("emoji", "") reaction_name = emoji_to_zoom_reaction(emoji) if not reaction_name: reaction_name = emoji.lstrip(":").rstrip(":") try: token = await self._outbound._get_token() bot_user_id = self._outbound._account.get("bot_user_id", "me") url = f"https://api.zoom.us/v2/chat/users/{bot_user_id}/messages/{message_id}/emoji_reactions" resp = await self._outbound._client.post( url, json={"emoji_name": reaction_name}, headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"}, ) if resp.status_code in (200, 201, 204): logger.info("Zoom reaction added: emoji=%s reaction=%s msg=%s", emoji, reaction_name, message_id) return {"success": True, "result": {"reaction": reaction_name, "message_id": message_id}} logger.warning("Zoom react API failed: status=%s", resp.status_code) return {"success": False, "error": f"API error: {resp.status_code}"} except Exception as e: logger.exception("Zoom react API call failed") return {"success": False, "error": str(e)} def supports_action(self, action: str) -> bool: return action in ("send", "react")