ForcePilot/backend/package/yuxi/channels/adapters/nextcloudtalk/status.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

67 lines
2.7 KiB
Python

from __future__ import annotations
import logging
from yuxi.channels.models import ChannelAccountSnapshot, TokenStatus
logger = logging.getLogger(__name__)
def build_snapshot(adapter) -> ChannelAccountSnapshot:
config = adapter.config or {}
server_url = config.get("server_url", "")
bot_user = config.get("bot_user", config.get("botUser", ""))
has_bot_creds = bool(bot_user and (config.get("app_password") or config.get("appPassword")))
credential_source = "none"
if config.get("app_password") or config.get("appPassword"):
credential_source = "config"
elif config.get("bot_secret_file"):
credential_source = "secretFile"
bot_token_source = "config" if has_bot_creds else "none"
api_user = config.get("api_user", "")
api_password = config.get("api_password", "")
has_api_creds = bool(api_user and api_password)
app_token_source = "config" if has_api_creds else "none"
dm_policy = config.get("dm_policy", "pairing")
group_policy = config.get("group_policy", "allowlist")
allow_from = config.get("allow_from", config.get("allowFrom", []))
group_allow_from = config.get("group_allow_from", config.get("groupAllowFrom", []))
monitor_mode = getattr(adapter, "_monitor_mode", "polling")
status_value = getattr(adapter, "_status", None)
status_str = str(status_value.value) if hasattr(status_value, "value") else str(status_value or "disconnected")
conversations = getattr(adapter, "_conversations", {})
return ChannelAccountSnapshot(
account_id=getattr(adapter, "channel_id", "nextcloud-talk"),
name="Nextcloud Talk",
configured=has_bot_creds,
enabled=True,
linked=has_bot_creds,
running=status_str == "connected",
connected=status_str == "connected",
status_state="configured" if has_bot_creds else "not-configured",
health_state=status_str,
dm_policy=dm_policy,
group_policy=group_policy,
allow_from_count=len(allow_from) + len(group_allow_from),
base_url=server_url,
secret_source=credential_source,
credential_source=credential_source,
bot_token_source=bot_token_source,
bot_token_status=TokenStatus(source=bot_token_source, status="ok" if has_bot_creds else "missing"),
app_token_source=app_token_source,
app_token_status=TokenStatus(source=app_token_source, status="ok" if has_api_creds else "missing"),
probe={
"monitor_mode": monitor_mode,
"conversation_count": len(conversations),
"talk_version": getattr(adapter, "_talk_version", ""),
"api_base": getattr(adapter, "_api_base", ""),
},
)