实现了完整的Nextcloud Talk聊天适配器,包含以下核心功能: 1. 基础客户端通信与认证 2. 会话路由与聊天类型解析 3. 消息分块与格式转换 4. 用户配对与权限校验 5. 轮询式消息监听 6. 配置验证与诊断工具 7. 安全策略与去重缓存 8. 指标统计与状态快照 新增配套的配对用户缓存文件与模块导出入口。
104 lines
3.1 KiB
Python
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()
|
|
]
|