ForcePilot/backend/package/yuxi/channel/extensions/nextcloud_talk/accounts.py
Kris 6fc9a4a94c feat(channel): 添加 Nextcloud Talk 渠道扩展
新增 Nextcloud Talk 渠道扩展,支持在 Yuxi 平台中集成 Nextcloud Talk 即时通讯渠道。

包含以下功能模块:
- accounts: 账户管理
- bot_admin: Bot 管理
- chat_api: 聊天 API 封装
- config_schema: 配置模式
- conversation: 会话管理
- gateway: SSE/WebSocket 网关接入
- inbound: 入站消息处理
- send: 消息发送
- webhook_server: Webhook 服务
- format: 消息格式转换
- normalize: 消息规范化
- poll_api: 投票 API
- reaction_api: 表情反应 API
- policy: 安全策略
- probe: 健康探测
- replay_guard: 重放防护
- signature: 签名验证
- room_info: 房间信息
- types: 类型定义
2026-05-21 11:29:56 +08:00

76 lines
2.3 KiB
Python

from __future__ import annotations
import logging
import os
from pathlib import Path
from yuxi.channel.extensions.nextcloud_talk.config_schema import NextcloudTalkConfig
from yuxi.channel.extensions.nextcloud_talk.types import ResolvedNextcloudTalkAccount
logger = logging.getLogger(__name__)
def _read_secret_file(file_path: str) -> str:
p = Path(file_path)
if not p.is_file():
logger.warning("Nextcloud Talk: secret file not found: %s", file_path)
return ""
if p.is_symlink():
logger.warning("Nextcloud Talk: secret file is a symlink, refusing to read: %s", file_path)
return ""
try:
return p.read_text(encoding="utf-8").strip()
except Exception as e:
logger.warning("Nextcloud Talk: failed to read secret file %s: %s", file_path, e)
return ""
def _resolve_bot_secret(cfg: NextcloudTalkConfig, account_id: str) -> tuple[str, str]:
if account_id == "default":
env_val = os.environ.get("NEXTCLOUD_TALK_BOT_SECRET")
if env_val:
return env_val, "env"
if cfg.bot_secret_file:
content = _read_secret_file(cfg.bot_secret_file)
if content:
return content, "file"
if cfg.bot_secret:
return cfg.bot_secret, "config"
return "", "none"
def _resolve_api_password(cfg: NextcloudTalkConfig) -> tuple[str, str]:
if cfg.api_password:
return cfg.api_password, "config"
if cfg.api_password_file:
content = _read_secret_file(cfg.api_password_file)
if content:
return content, "file"
return "", "none"
def resolve_nextcloud_talk_account(
cfg: NextcloudTalkConfig, account_id: str = "default"
) -> ResolvedNextcloudTalkAccount:
bot_secret, secret_source = _resolve_bot_secret(cfg, account_id)
api_password, api_password_source = _resolve_api_password(cfg)
configured = bool(cfg.base_url and bot_secret)
return ResolvedNextcloudTalkAccount(
account_id=account_id,
enabled=cfg.enabled,
name=cfg.name or account_id,
configured=configured,
base_url=cfg.base_url,
bot_secret=bot_secret,
secret_source=secret_source,
api_user=cfg.api_user,
api_password=api_password,
api_password_source=api_password_source,
)
def list_nextcloud_talk_account_ids(cfg: NextcloudTalkConfig) -> list[str]:
return ["default"]