ForcePilot/backend/package/yuxi/channels/adapters/synologychat/session.py

73 lines
2.1 KiB
Python
Raw Normal View History

"""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