import json import logging import httpx logger = logging.getLogger(__name__) TEMPLATE_SEND_URL = "https://m.api.weibo.com/2/eps/template/send.json" class WeiboTemplate: def __init__(self, gateway=None): self._gateway = gateway self._http: httpx.AsyncClient | None = None async def send( self, receiver_id: int, template_id: str, data: dict, *, url: str = "", topcolor: str = "#FF0000", ) -> dict | None: """ 发送模板消息。 data 为模板变量的键值对,格式: {"first": {"value": "标题", "color": "#173177"}, "keyword1": {"value": "内容", "color": "#173177"}, ...} 支持两种格式: - 纯文本模板:data 中的变量将替换文本中的 {{var.DATA}} - 卡片模板:自动生成结构化卡片形式 """ if self._http is None: self._http = httpx.AsyncClient(timeout=15.0) token = self._gateway.access_token if self._gateway else None if not token: logger.error("No access_token for template message") return None payload = { "access_token": token, "receiver_id": receiver_id, "template_id": template_id, "data": data, } if url: payload["url"] = url if topcolor: payload["topcolor"] = topcolor try: resp = await self._http.post( TEMPLATE_SEND_URL, data={"access_token": token, "json": json.dumps(payload, ensure_ascii=False)}, ) data = resp.json() if data.get("error_code"): logger.error("Template send failed: %s", data) return data except Exception: logger.exception("Template send error") return None async def close(self): if self._http: await self._http.aclose() self._http = None