68 lines
2.3 KiB
Python
68 lines
2.3 KiB
Python
"""Shared helper: find-or-create ChatSession by external channel conv_id.
|
|
|
|
Used by feishu.py, slack.py, discord_bot.py, wecom.py, teams.py — eliminates in-process caches.
|
|
"""
|
|
import uuid as _uuid
|
|
from datetime import datetime, timezone
|
|
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.models.chat_session import ChatSession
|
|
|
|
|
|
async def find_or_create_channel_session(
|
|
db: AsyncSession,
|
|
agent_id: _uuid.UUID,
|
|
user_id: _uuid.UUID,
|
|
external_conv_id: str,
|
|
source_channel: str,
|
|
first_message_title: str,
|
|
is_group: bool = False,
|
|
group_name: str | None = None,
|
|
) -> ChatSession:
|
|
"""Find an existing ChatSession by (agent_id, external_conv_id), or create one.
|
|
|
|
Relies on the UNIQUE constraint on (agent_id, external_conv_id) in the DB.
|
|
|
|
Args:
|
|
is_group: True for group chat sessions (Feishu group, Slack channel, etc.).
|
|
Group sessions keep user_id as the agent creator (placeholder) and
|
|
are excluded from the user's "mine" session list.
|
|
group_name: Display name for group sessions (e.g. IM group/channel name).
|
|
"""
|
|
result = await db.execute(
|
|
select(ChatSession).where(
|
|
ChatSession.agent_id == agent_id,
|
|
ChatSession.external_conv_id == external_conv_id,
|
|
)
|
|
)
|
|
session = result.scalar_one_or_none()
|
|
|
|
if session is None:
|
|
now = datetime.now(timezone.utc)
|
|
session = ChatSession(
|
|
agent_id=agent_id,
|
|
user_id=user_id,
|
|
title=group_name[:40] if (is_group and group_name) else first_message_title[:40],
|
|
source_channel=source_channel,
|
|
external_conv_id=external_conv_id,
|
|
is_group=is_group,
|
|
group_name=group_name,
|
|
created_at=now,
|
|
)
|
|
db.add(session)
|
|
await db.flush() # populate session.id
|
|
else:
|
|
# For P2P sessions: re-attribute to the correct user
|
|
# (fixes legacy sessions stored under creator_id)
|
|
if not session.is_group and session.user_id != user_id:
|
|
session.user_id = user_id
|
|
|
|
# For group sessions: update group_name if it changed
|
|
if session.is_group and group_name and session.group_name != group_name:
|
|
session.group_name = group_name
|
|
session.title = group_name[:40]
|
|
|
|
return session
|