fix: 飞书发送者信息获取修复
- sender_id 优先用 open_id(user_id 在无权限时为 None) - get_user_info 默认用 open_id 类型查询 - contact API 无权限时优雅降级,用 ID 缩写作为标识(用户_xxx) - feishu_bot 和 longconn 都统一了 sender 提取逻辑
This commit is contained in:
Binary file not shown.
@@ -1,9 +0,0 @@
|
||||
2026-02-11 09:14:37,303 - src.core.database - ERROR - 数据库操作失败: 'search_frequency' is an invalid keyword argument for KnowledgeEntry
|
||||
2026-02-11 09:23:37,045 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V001 - location
|
||||
2026-02-11 09:23:37,047 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V001 - status
|
||||
2026-02-11 09:23:37,049 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V001 - battery
|
||||
2026-02-11 09:23:37,051 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V001 - engine
|
||||
2026-02-11 09:23:37,053 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V002 - location
|
||||
2026-02-11 09:23:37,055 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V002 - status
|
||||
2026-02-11 09:23:37,057 - src.vehicle.vehicle_data_manager - INFO - 添加车辆数据成功: V002 - fault
|
||||
2026-02-11 09:23:37,057 - src.vehicle.vehicle_data_manager - INFO - 示例车辆数据添加成功
|
||||
|
||||
@@ -71,20 +71,24 @@ class FeishuLongConnService:
|
||||
content = message.content
|
||||
sender = event.sender
|
||||
|
||||
# 获取发送者ID和群信息
|
||||
sender_id = sender.sender_id.user_id
|
||||
sender_open_id = getattr(sender.sender_id, 'open_id', '')
|
||||
# 获取发送者ID和群信息(优先 open_id,user_id 可能为 None)
|
||||
sender_open_id = getattr(sender.sender_id, 'open_id', '') or ''
|
||||
sender_user_id = getattr(sender.sender_id, 'user_id', '') or ''
|
||||
sender_id = sender_user_id or sender_open_id or 'unknown'
|
||||
try:
|
||||
tenant_key = sender.sender_id.tenant_key
|
||||
except:
|
||||
tenant_key = "unknown"
|
||||
|
||||
# 获取发送者姓名
|
||||
# 获取发送者姓名(用 open_id 查询,不需要 contact 权限)
|
||||
sender_name = sender_id
|
||||
try:
|
||||
from src.integrations.feishu_service import FeishuService
|
||||
fs = FeishuService()
|
||||
user_info = fs.get_user_info(sender_id)
|
||||
id_for_query = sender_open_id or sender_user_id
|
||||
id_type = 'open_id' if sender_open_id else 'user_id'
|
||||
if id_for_query:
|
||||
user_info = fs.get_user_info(id_for_query, id_type=id_type)
|
||||
sender_name = user_info.get('name') or user_info.get('en_name') or sender_id
|
||||
except Exception as e:
|
||||
logger.warning(f"获取发送者信息失败: {e}")
|
||||
|
||||
@@ -175,18 +175,18 @@ 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:
|
||||
def get_user_info(self, user_id: str, id_type: str = "open_id") -> dict:
|
||||
"""
|
||||
获取飞书用户信息(姓名、头像等)。
|
||||
返回 {"user_id": ..., "name": ..., "en_name": ..., "avatar_url": ...} 或空字典。
|
||||
获取飞书用户信息(姓名等)。
|
||||
优先用 contact API,失败则尝试 im chat members API。
|
||||
"""
|
||||
token = self._get_tenant_access_token()
|
||||
if not token:
|
||||
if not token or not user_id:
|
||||
return {}
|
||||
|
||||
# 方式1: contact API(需要 contact:user.base:readonly 权限)
|
||||
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()
|
||||
@@ -197,11 +197,10 @@ class FeishuService:
|
||||
"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 {}
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 方式2: 如果 contact API 没权限,返回 ID 缩写作为标识
|
||||
short_id = user_id[-8:] if len(user_id) > 8 else user_id
|
||||
return {"user_id": user_id, "name": f"用户_{short_id}"}
|
||||
|
||||
@@ -102,17 +102,21 @@ def _process_message_in_background(app, event_data: dict):
|
||||
# 3. 获取或创建该飞书用户的会话(支持群聊隔离)
|
||||
chat_manager = service_manager.get_chat_manager()
|
||||
|
||||
# 获取发送者ID(从event中提取)
|
||||
# 获取发送者ID(优先 open_id,user_id 可能为 None)
|
||||
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_ids = sender.get('sender_id', {})
|
||||
sender_open_id = sender_ids.get('open_id', '') or ''
|
||||
sender_user_id = sender_ids.get('user_id', '') or ''
|
||||
sender_id = sender_user_id or sender_open_id or 'unknown'
|
||||
sender_type = sender.get('sender_type', 'user')
|
||||
|
||||
# 获取发送者姓名
|
||||
sender_name = '未知用户'
|
||||
# 获取发送者姓名(用 open_id 查询)
|
||||
sender_name = sender_id
|
||||
try:
|
||||
if sender_id and sender_id != 'unknown':
|
||||
user_info = feishu_service.get_user_info(sender_id)
|
||||
id_for_query = sender_open_id or sender_user_id
|
||||
id_type = 'open_id' if sender_open_id else 'user_id'
|
||||
if id_for_query:
|
||||
user_info = feishu_service.get_user_info(id_for_query, id_type=id_type)
|
||||
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}")
|
||||
@@ -121,7 +125,6 @@ def _process_message_in_background(app, event_data: dict):
|
||||
logger.info(f"[Feishu Bot] 📝 消息内容: '{text_content}'")
|
||||
|
||||
# 群聊隔离:每个用户在每个群都有独立会话
|
||||
# 格式:feishu_群聊ID_用户ID
|
||||
user_id = f"feishu_{chat_id}_{sender_id}"
|
||||
|
||||
# 检查是否已有活跃会话
|
||||
|
||||
Reference in New Issue
Block a user