from __future__ import annotations import logging from typing import Any import httpx from yuxi.channels.models import DeliveryResult from .token import DingDingTokenManager logger = logging.getLogger(__name__) async def upload_media( token_manager: DingDingTokenManager, media_type: str, media_data: bytes, filename: str = "file", *, http_client: httpx.AsyncClient | None = None, ) -> dict[str, Any]: token = await token_manager.get_token() url = "https://api.dingtalk.com/v1.0/media/upload" headers = {"x-acs-dingtalk-access-token": token} files = {"media": (filename, media_data)} params = {"type": media_type} if http_client is not None: resp = await http_client.post(url, headers=headers, files=files, params=params) else: async with httpx.AsyncClient(timeout=httpx.Timeout(30)) as client: resp = await client.post(url, headers=headers, files=files, params=params) if resp.status_code != 200: logger.error(f"upload_media HTTP {resp.status_code}: {resp.text[:300]}") raise RuntimeError(f"Media upload failed: HTTP {resp.status_code}") return resp.json() async def download_media( token_manager: DingDingTokenManager, download_code: str, *, http_client: httpx.AsyncClient | None = None, ) -> bytes: token = await token_manager.get_token() url = "https://api.dingtalk.com/v1.0/media/download" headers = {"x-acs-dingtalk-access-token": token} params = {"downloadCode": download_code} if http_client is not None: resp = await http_client.get(url, headers=headers, params=params) else: async with httpx.AsyncClient(timeout=httpx.Timeout(30)) as client: resp = await client.get(url, headers=headers, params=params) if resp.status_code != 200: logger.error(f"download_media HTTP {resp.status_code}: {resp.text[:300]}") raise RuntimeError(f"Media download failed: HTTP {resp.status_code}") return resp.content async def send_media( token_manager: DingDingTokenManager, open_conversation_id: str, robot_code: str, media_id: str, media_type: str, *, chat_type: str = "direct", http_client: httpx.AsyncClient | None = None, ) -> DeliveryResult: try: msg_key_map = { "image": "sampleImageMsg", "voice": "sampleAudio", "file": "sampleFile", "video": "sampleVideo", } msg_key = msg_key_map.get(media_type, "sampleFile") msg_param = {"mediaId": media_id} from .send import _send_msg return await _send_msg( token_manager, open_conversation_id, robot_code, msg_key, msg_param, chat_type=chat_type, http_client=http_client, ) except Exception as e: logger.error(f"send_media failed: {e}") return DeliveryResult(success=False, error=str(e))