ForcePilot/backend/package/yuxi/channel/extensions/wecom/menu.py
Kris 7215418610 feat(channel): 添加企业微信、微博、WhatsApp 和 Workplace 渠道扩展
新增企业微信、微博、WhatsApp、Workplace 四个渠道扩展。

企业微信渠道扩展主要模块:config, gateway, webhook, webhook_bot, outbound, streaming, pairing, security, crypto, dedupe, persistent_dedupe, card, directory, events, externalcontact, media, mentions, menu, message, oauth, status

微博渠道扩展主要模块:config, gateway, webhook, outbound, streaming, pairing, security, dedupe, passive_reply, broadcast, message, menu, media, subscription, template, status

WhatsApp 渠道扩展主要模块:config, gateway, webhook, outbound, streaming, pairing, security, dedupe, actions, monitor, status

Workplace 渠道扩展主要模块:config, gateway, webhook, outbound, streaming, pairing, security, dedupe, actions, challenge, groups, media, mentions, menu, monitor, persona, quick_reply, signature, subscriptions, template, threading, users, status
2026-05-21 12:01:56 +08:00

76 lines
2.5 KiB
Python

import logging
import httpx
logger = logging.getLogger(__name__)
MENU_CREATE_URL = "https://qyapi.weixin.qq.com/cgi-bin/menu/create"
MENU_GET_URL = "https://qyapi.weixin.qq.com/cgi-bin/menu/get"
MENU_DELETE_URL = "https://qyapi.weixin.qq.com/cgi-bin/menu/delete"
class WeComMenu:
def __init__(self, gateway):
self._gateway = gateway
self._http: httpx.AsyncClient | None = None
@property
def _token(self) -> str | None:
return self._gateway.access_token if self._gateway else None
async def create(self, agent_id: int, buttons: list[dict]) -> bool:
token = self._token
if not token:
return False
url = f"{MENU_CREATE_URL}?access_token={token}&agentid={agent_id}"
try:
resp = await self._get_http().post(url, json={"button": buttons})
data = resp.json()
if data.get("errcode") == 0:
logger.info("WeCom menu created for agent %s", agent_id)
return True
logger.warning("WeCom menu create failed: %s", data)
return False
except Exception:
logger.exception("WeCom menu create error")
return False
async def get(self, agent_id: int) -> dict | None:
token = self._token
if not token:
return None
url = f"{MENU_GET_URL}?access_token={token}&agentid={agent_id}"
try:
resp = await self._get_http().get(url)
return resp.json()
except Exception:
logger.exception("WeCom menu get error")
return None
async def delete(self, agent_id: int) -> bool:
token = self._token
if not token:
return False
url = f"{MENU_DELETE_URL}?access_token={token}&agentid={agent_id}"
try:
resp = await self._get_http().get(url)
data = resp.json()
if data.get("errcode") == 0:
logger.info("WeCom menu deleted for agent %s", agent_id)
return True
logger.warning("WeCom menu delete failed: %s", data)
return False
except Exception:
logger.exception("WeCom menu delete error")
return False
def _get_http(self) -> httpx.AsyncClient:
if self._http is None:
self._http = httpx.AsyncClient(timeout=10.0)
return self._http
async def close(self):
if self._http:
await self._http.aclose()
self._http = None