ForcePilot/backend/package/yuxi/channels/adapters/nextcloudtalk/directory.py
Kris b018ad25da feat(backend): add Nextcloud Talk channel adapter implementation
实现了完整的Nextcloud Talk聊天适配器,包含以下核心功能:
1. 基础客户端通信与认证
2. 会话路由与聊天类型解析
3. 消息分块与格式转换
4. 用户配对与权限校验
5. 轮询式消息监听
6. 配置验证与诊断工具
7. 安全策略与去重缓存
8. 指标统计与状态快照

新增配套的配对用户缓存文件与模块导出入口。
2026-05-12 00:47:06 +08:00

104 lines
3.1 KiB
Python

from __future__ import annotations
import logging
from typing import Any
from yuxi.channels.models import ChannelType, ChatType
from .client import NextcloudTalkClient
logger = logging.getLogger(__name__)
async def list_peers(
client: NextcloudTalkClient,
api_base: str,
channel_id: str = "nextcloud-talk",
) -> list[dict[str, Any]]:
try:
path = f"{api_base}/conversation"
result = await client.get(path)
ocs = result.get("ocs", {})
conversations = ocs.get("data", [])
peers: list[dict[str, Any]] = []
if not isinstance(conversations, list):
return peers
for conv in conversations:
conv_type = conv.get("type", 2)
if conv_type not in (0, 1):
continue
token = conv.get("token", "")
peers.append(
{
"id": f"nextcloud-talk:{token}",
"channel_id": channel_id,
"channel_type": ChannelType.NEXTCLOUDTALK,
"chat_type": ChatType.DIRECT if conv_type == 1 else ChatType.GROUP,
"token": token,
"name": conv.get("name", ""),
"display_name": conv.get("displayName", conv.get("name", "")),
"conversation_type": conv_type,
}
)
return peers
except Exception as e:
logger.warning(f"[NextcloudTalk] Failed to list peers: {e}")
return []
async def list_groups(
client: NextcloudTalkClient,
api_base: str,
channel_id: str = "nextcloud-talk",
) -> list[dict[str, Any]]:
try:
path = f"{api_base}/conversation"
result = await client.get(path)
ocs = result.get("ocs", {})
conversations = ocs.get("data", [])
groups: list[dict[str, Any]] = []
if not isinstance(conversations, list):
return groups
for conv in conversations:
conv_type = conv.get("type", 2)
if conv_type not in (2, 3):
continue
token = conv.get("token", "")
groups.append(
{
"id": f"nextcloud-talk:room:{token}",
"channel_id": channel_id,
"channel_type": ChannelType.NEXTCLOUDTALK,
"chat_type": ChatType.GROUP,
"token": token,
"name": conv.get("name", ""),
"display_name": conv.get("displayName", conv.get("name", "")),
"conversation_type": conv_type,
}
)
return groups
except Exception as e:
logger.warning(f"[NextcloudTalk] Failed to list groups: {e}")
return []
async def search_peers(
client: NextcloudTalkClient,
api_base: str,
query: str,
channel_id: str = "nextcloud-talk",
) -> list[dict[str, Any]]:
query_lower = query.lower()
all_peers = await list_peers(client, api_base, channel_id)
return [
p
for p in all_peers
if query_lower in p.get("name", "").lower() or query_lower in p.get("display_name", "").lower()
]