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

73 lines
2.1 KiB
Python

"""Session routing for Synology Chat conversations.
Routes incoming messages to agent sessions based on chat type (direct/group),
user identity, and account for multi-account isolation.
DM sessions are keyed by userId to prevent cross-user session confusion
in shared DM channels. Group sessions are keyed by chat_id since group
context is shared among all members in the same group.
Identity links allow mapping between different representations of the
same user (e.g. webhook user_id ↔ DSM API user_id).
"""
from __future__ import annotations
from yuxi.channels.models import ChannelMessage, ChatType
DEFAULT_ACCOUNT_ID = "default"
def resolve_session_route(
msg: ChannelMessage,
default_agent_id: str = "default",
account_id: str = DEFAULT_ACCOUNT_ID,
) -> str:
user_id = msg.identity.channel_user_id
chat_id = msg.identity.channel_chat_id
chat_type = msg.chat_type
if chat_type == ChatType.DIRECT:
return f"agent:{default_agent_id}:synologychat:{account_id}:direct:{user_id}"
else:
return f"agent:{default_agent_id}:synologychat:{account_id}:group:{chat_id}"
def build_identity_link(
user_id: str,
account_id: str = DEFAULT_ACCOUNT_ID,
username: str = "",
chat_id: str = "",
) -> dict:
return {
"channel": "synologychat",
"account_id": account_id,
"user_id": user_id,
"username": username,
"chat_id": chat_id,
}
def resolve_identity_links(
msg: ChannelMessage,
account_id: str = DEFAULT_ACCOUNT_ID,
) -> list[dict]:
links = [
build_identity_link(
user_id=msg.identity.channel_user_id,
account_id=account_id,
username=msg.metadata.get("dsm_user_name", "") if msg.metadata else "",
chat_id=msg.identity.channel_chat_id,
)
]
forwarded_from = msg.metadata.get("forwarded_from") if msg.metadata else None
if forwarded_from:
links.append(
build_identity_link(
user_id=str(forwarded_from),
account_id=account_id,
chat_id=msg.identity.channel_chat_id,
)
)
return links