新增企业微信、微博、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
116 lines
4.1 KiB
Python
116 lines
4.1 KiB
Python
import logging
|
|
|
|
import httpx
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
DEPARTMENT_LIST_URL = "https://qyapi.weixin.qq.com/cgi-bin/department/list"
|
|
USER_LIST_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/list"
|
|
USER_SIMPLE_LIST_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist"
|
|
USER_GET_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/get"
|
|
USER_LIST_ID_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/list_id"
|
|
|
|
|
|
class WeComDirectory:
|
|
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 list_departments(self, parent_id: int = 0) -> list[dict]:
|
|
token = self._token
|
|
if not token:
|
|
return []
|
|
url = f"{DEPARTMENT_LIST_URL}?access_token={token}&id={parent_id}"
|
|
try:
|
|
resp = await self._get_http().get(url)
|
|
data = resp.json()
|
|
if data.get("errcode") == 0:
|
|
return data.get("department", [])
|
|
logger.warning("WeCom list_departments failed: %s", data)
|
|
return []
|
|
except Exception:
|
|
logger.exception("WeCom list_departments error")
|
|
return []
|
|
|
|
async def list_users_simple(self, department_id: int, fetch_child: int = 0) -> list[dict]:
|
|
token = self._token
|
|
if not token:
|
|
return []
|
|
url = f"{USER_SIMPLE_LIST_URL}?access_token={token}&department_id={department_id}&fetch_child={fetch_child}"
|
|
try:
|
|
resp = await self._get_http().get(url)
|
|
data = resp.json()
|
|
if data.get("errcode") == 0:
|
|
return data.get("userlist", [])
|
|
logger.warning("WeCom list_users_simple failed: %s", data)
|
|
return []
|
|
except Exception:
|
|
logger.exception("WeCom list_users_simple error")
|
|
return []
|
|
|
|
async def list_users(self, department_id: int, fetch_child: int = 0) -> list[dict]:
|
|
token = self._token
|
|
if not token:
|
|
return []
|
|
url = f"{USER_LIST_URL}?access_token={token}&department_id={department_id}&fetch_child={fetch_child}"
|
|
try:
|
|
resp = await self._get_http().get(url)
|
|
data = resp.json()
|
|
if data.get("errcode") == 0:
|
|
return data.get("userlist", [])
|
|
logger.warning("WeCom list_users failed: %s", data)
|
|
return []
|
|
except Exception:
|
|
logger.exception("WeCom list_users error")
|
|
return []
|
|
|
|
async def get_user(self, user_id: str) -> dict | None:
|
|
token = self._token
|
|
if not token:
|
|
return None
|
|
url = f"{USER_GET_URL}?access_token={token}&userid={user_id}"
|
|
try:
|
|
resp = await self._get_http().get(url)
|
|
data = resp.json()
|
|
if data.get("errcode") == 0:
|
|
return data
|
|
logger.warning("WeCom get_user failed: %s", data)
|
|
return None
|
|
except Exception:
|
|
logger.exception("WeCom get_user error")
|
|
return None
|
|
|
|
async def list_user_ids(self, department_id: int = 0, cursor: str = "", limit: int = 10000) -> dict:
|
|
token = self._token
|
|
if not token:
|
|
return {}
|
|
body: dict = {"cursor": cursor, "limit": limit}
|
|
if department_id > 0:
|
|
body["department_id"] = department_id
|
|
|
|
url = f"{USER_LIST_ID_URL}?access_token={token}"
|
|
try:
|
|
resp = await self._get_http().post(url, json=body)
|
|
data = resp.json()
|
|
if data.get("errcode") == 0:
|
|
return data
|
|
logger.warning("WeCom list_user_ids failed: %s", data)
|
|
return {}
|
|
except Exception:
|
|
logger.exception("WeCom list_user_ids error")
|
|
return {}
|
|
|
|
def _get_http(self) -> httpx.AsyncClient:
|
|
if self._http is None:
|
|
self._http = httpx.AsyncClient(timeout=15.0)
|
|
return self._http
|
|
|
|
async def close(self):
|
|
if self._http:
|
|
await self._http.aclose()
|
|
self._http = None
|