ForcePilot/backend/package/yuxi/channels/adapters/synologychat/directory.py
Kris 3ad218e537 feat(synologychat): 新增群晖Chat适配器完整实现
新增群晖Chat渠道适配器的全套实现,包括:
1. 基础适配器与导出接口定义
2. DSM API认证、探测与会话管理
3. 轮询与Webhook两种消息接收方式
4. 消息去重、格式化与规范化处理
5. 多账号支持与权限安全策略
6. 目录用户/群组发现功能
7. 审批配对与流量控制机制
8. 安全审计与配置检查功能
2026-05-12 00:49:16 +08:00

81 lines
2.3 KiB
Python

"""Directory adapter for Synology Chat user and channel discovery.
Encapsulates DSM user_list and channel_list APIs into a unified directory
interface for listing peers and groups.
"""
from __future__ import annotations
import asyncio
from dataclasses import dataclass, field
from yuxi.channels.adapters.synologychat.client import DSMClient
from yuxi.utils.logging_config import logger
@dataclass
class DirectoryPeer:
id: str
username: str = ""
name: str = ""
is_bot: bool = False
@dataclass
class DirectoryGroup:
id: str
name: str = ""
member_count: int = 0
@dataclass
class DirectoryResult:
peers: list[DirectoryPeer] = field(default_factory=list)
groups: list[DirectoryGroup] = field(default_factory=list)
async def list_peers(client: DSMClient) -> list[DirectoryPeer]:
try:
result = await client.user_list()
if not result.get("success"):
logger.warning(f"[SynologyChat] user_list failed: {result.get('error', {})}")
return []
users = result.get("data", {}).get("users", [])
return [
DirectoryPeer(
id=str(u.get("user_id", "")),
username=u.get("username", ""),
name=u.get("name", ""),
is_bot=u.get("is_bot", False),
)
for u in users
]
except Exception as e:
logger.error(f"[SynologyChat] list_peers failed: {e}")
return []
async def list_groups(client: DSMClient) -> list[DirectoryGroup]:
try:
result = await client.channel_list()
if not result.get("success"):
logger.warning(f"[SynologyChat] channel_list failed: {result.get('error', {})}")
return []
channels = result.get("data", {}).get("channels", [])
return [
DirectoryGroup(
id=str(c.get("channel_id", "")),
name=c.get("name", ""),
member_count=c.get("member_count", 0),
)
for c in channels
]
except Exception as e:
logger.error(f"[SynologyChat] list_groups failed: {e}")
return []
async def get_directory(client: DSMClient) -> DirectoryResult:
peers, groups = await asyncio.gather(list_peers(client), list_groups(client))
return DirectoryResult(peers=peers, groups=groups)