import asyncio import httpx SYNC_MSG_URL = "/cgi-bin/kf/sync_msg" MAX_RETRIES = 3 RETRY_BASE_DELAY = 1.0 async def sync_messages( http: httpx.AsyncClient, access_token: str, open_kfid: str, cursor: str = "", token: str = "", limit: int = 1000, voice_format: int = 0, ) -> dict: payload: dict = { "open_kfid": open_kfid, "limit": min(limit, 1000), "voice_format": voice_format, } if cursor: payload["cursor"] = cursor if token: payload["token"] = token last_error = None for attempt in range(MAX_RETRIES): try: resp = await http.post( SYNC_MSG_URL, params={"access_token": access_token}, json=payload, ) data = resp.json() errcode = data.get("errcode", 0) if errcode == 0: return data if errcode == 42001: raise RuntimeError("access_token 失效") if errcode == 45009: raise RuntimeError("日调用量超限") last_error = data except httpx.TimeoutException: last_error = {"errcode": -1, "errmsg": "timeout"} except RuntimeError: raise if attempt < MAX_RETRIES - 1: delay = RETRY_BASE_DELAY * (2**attempt) await asyncio.sleep(delay) return {"errcode": -1, "errmsg": str(last_error), "msg_list": [], "has_more": 0}