diff --git a/data/tsp_assistant.db b/data/tsp_assistant.db index 2df7fb7..cec2150 100644 Binary files a/data/tsp_assistant.db and b/data/tsp_assistant.db differ diff --git a/src/core/models.py b/src/core/models.py index 792bdb4..f4c7589 100644 --- a/src/core/models.py +++ b/src/core/models.py @@ -103,8 +103,8 @@ class ChatSession(Base): title = Column(String(200), nullable=True) # 会话标题(取首条消息摘要) status = Column(String(20), default="active") # active, ended message_count = Column(Integer, default=0) # 消息轮数 - source = Column(String(50), nullable=True) # 来源:websocket, api, feishu - ip_address = Column(String(45), nullable=True) + source = Column(String(100), nullable=True) # 来源:websocket, api, feishu_bot(group) 等 + ip_address = Column(String(200), nullable=True) # IP地址或来源标识 created_at = Column(DateTime, default=datetime.now) updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now) ended_at = Column(DateTime, nullable=True) @@ -143,8 +143,8 @@ class Conversation(Base): confidence_score = Column(Float) knowledge_used = Column(Text) # 使用的知识库条目 response_time = Column(Float) # 响应时间(秒) - ip_address = Column(String(45), nullable=True) # IP地址 - invocation_method = Column(String(50), nullable=True) # 调用方式(websocket, api等) + ip_address = Column(String(200), nullable=True) # IP地址或来源标识(如 feishu:uid:name) + invocation_method = Column(String(100), nullable=True) # 调用方式(websocket, api, feishu_bot(group) 等) # 系统优化字段 processing_time = Column(Float) # 处理时间 diff --git a/src/integrations/feishu_longconn_service.py b/src/integrations/feishu_longconn_service.py index 06e38b3..4f30aa6 100644 --- a/src/integrations/feishu_longconn_service.py +++ b/src/integrations/feishu_longconn_service.py @@ -73,19 +73,25 @@ class FeishuLongConnService: # 获取发送者ID和群信息 sender_id = sender.sender_id.user_id + sender_open_id = getattr(sender.sender_id, 'open_id', '') try: tenant_key = sender.sender_id.tenant_key except: tenant_key = "unknown" + # 获取发送者姓名 + sender_name = sender_id + try: + from src.integrations.feishu_service import FeishuService + fs = FeishuService() + user_info = fs.get_user_info(sender_id) + sender_name = user_info.get('name') or user_info.get('en_name') or sender_id + except Exception as e: + logger.warning(f"获取发送者信息失败: {e}") + # 详细日志记录 - logger.info(f"📋 消息详情 [长连接]:") - logger.info(f" - 消息ID: {message_id}") - logger.info(f" - 会话类型: {'群聊(group)' if chat_type == 'group' else '私聊(p2p)' if chat_type == 'p2p' else chat_type}") - logger.info(f" - 会话ID: {chat_id}") - logger.info(f" - 发送者ID: {sender_id}") - logger.info(f" - 租户Key: {tenant_key}") - logger.info(f" - 消息类型: {message_type}") + chat_type_desc = '群聊(group)' if chat_type == 'group' else '私聊(p2p)' if chat_type == 'p2p' else chat_type + logger.info(f"📨 [长连接] 发送者={sender_name}({sender_id}), 群={chat_id}, 类型={chat_type_desc}, 消息ID={message_id}") # 消息去重检查 if cache_manager.check_and_set_message_processed(message_id): @@ -163,15 +169,14 @@ class FeishuLongConnService: work_order_id=None, tenant_id=tenant_id ) - logger.info(f"🆕 创建新会话: {session_id} (租户: {tenant_id})") + logger.info(f"🆕 创建新会话: {session_id}, 用户={sender_name}({sender_id}), 租户={tenant_id}") # 调用实时对话接口处理消息 - logger.info(f"🤖 调用 TSP Assistant 处理消息...") response_data = chat_manager.process_message( session_id=session_id, user_message=text_content, - ip_address=f"Feishu:{sender_id}", - invocation_method=f"Feishu({chat_type})" + ip_address=f"feishu:{sender_id}:{sender_name}", + invocation_method=f"feishu_longconn({chat_type})" ) logger.info(f"📊 处理结果: {response_data.get('success')}") diff --git a/src/integrations/feishu_service.py b/src/integrations/feishu_service.py index 7f4bda5..c72ae91 100644 --- a/src/integrations/feishu_service.py +++ b/src/integrations/feishu_service.py @@ -174,3 +174,34 @@ class FeishuService: logger.info(f"获取到 {len(all_chats)} 个机器人所在的群") return all_chats + + def get_user_info(self, user_id: str, id_type: str = "user_id") -> dict: + """ + 获取飞书用户信息(姓名、头像等)。 + 返回 {"user_id": ..., "name": ..., "en_name": ..., "avatar_url": ...} 或空字典。 + """ + token = self._get_tenant_access_token() + if not token: + return {} + + url = f"{self.BASE_URL}/contact/v3/users/{user_id}?user_id_type={id_type}" + headers = {"Authorization": f"Bearer {token}"} + + try: + response = requests.get(url, headers=headers) + data = response.json() + if data.get("code") == 0: + user = data.get("data", {}).get("user", {}) + return { + "user_id": user.get("user_id", ""), + "open_id": user.get("open_id", ""), + "name": user.get("name", ""), + "en_name": user.get("en_name", ""), + "avatar_url": user.get("avatar", {}).get("avatar_72", ""), + } + else: + logger.warning(f"获取用户信息失败: {data.get('msg')} (user_id={user_id})") + return {} + except Exception as e: + logger.warning(f"获取用户信息异常: {e}") + return {} diff --git a/src/web/blueprints/feishu_bot.py b/src/web/blueprints/feishu_bot.py index 3e721f9..25c638d 100644 --- a/src/web/blueprints/feishu_bot.py +++ b/src/web/blueprints/feishu_bot.py @@ -103,14 +103,27 @@ def _process_message_in_background(app, event_data: dict): chat_manager = service_manager.get_chat_manager() # 获取发送者ID(从event中提取) - sender_id = event.get('sender', {}).get('sender_id', {}).get('user_id', 'unknown') + sender = event.get('sender', {}) + sender_id = sender.get('sender_id', {}).get('user_id', 'unknown') + sender_open_id = sender.get('sender_id', {}).get('open_id', '') + sender_type = sender.get('sender_type', 'user') + + # 获取发送者姓名 + sender_name = '未知用户' + try: + if sender_id and sender_id != 'unknown': + user_info = feishu_service.get_user_info(sender_id) + sender_name = user_info.get('name') or user_info.get('en_name') or sender_id + except Exception as e: + logger.warning(f"[Feishu Bot] 获取发送者信息失败: {e}") + + logger.info(f"[Feishu Bot] 📨 消息详情: 发送者={sender_name}({sender_id}), 群={chat_id}, 类型={chat_type_desc}, 租户={tenant_id}, 消息ID={message_id}") + logger.info(f"[Feishu Bot] 📝 消息内容: '{text_content}'") # 群聊隔离:每个用户在每个群都有独立会话 # 格式:feishu_群聊ID_用户ID user_id = f"feishu_{chat_id}_{sender_id}" - logger.info(f"[Feishu Bot] 会话用户标识: {user_id}") - # 检查是否已有活跃会话 active_sessions = chat_manager.get_active_sessions() session_id = None @@ -126,17 +139,16 @@ def _process_message_in_background(app, event_data: dict): # 如果没有会话,创建新会话 if not session_id: session_id = chat_manager.create_session(user_id=user_id, work_order_id=None, tenant_id=tenant_id) - logger.info(f"[Feishu Bot] 为用户 {sender_id} 在群聊 {chat_id} 创建新会话: {session_id} (租户: {tenant_id})") + logger.info(f"[Feishu Bot] 新建会话: {session_id}, 用户={sender_name}({sender_id}), 租户={tenant_id}") # 4. 调用实时对话接口处理消息 - logger.info(f"[Feishu Bot] 调用实时对话接口处理消息...") response_data = chat_manager.process_message( session_id=session_id, user_message=text_content, - ip_address=None, - invocation_method="feishu_bot" + ip_address=f"feishu:{sender_id}:{sender_name}", + invocation_method=f"feishu_bot({chat_type})" ) - logger.info(f"[Feishu Bot] 实时对话接口返回结果: {response_data}") + logger.info(f"[Feishu Bot] 处理结果: success={response_data.get('success')}, 用户={sender_name}") # 5. 提取回复并发送 if response_data.get("success"):