fix: resolve Feishu cross-app notification routing bug
Implement per-app open_id storage via user_feishu_open_ids table with union_id-based cross-app user identification. WS handlers now auto-capture open_id+union_id and resolve/associate user accounts. Schedule notifications route through the correct bot's open_id instead of always falling back to 苹果. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -70,6 +70,21 @@ def _get_sender_open_id(data) -> Optional[str]:
|
||||
return None
|
||||
|
||||
|
||||
def _get_sender_union_id(data) -> Optional[str]:
|
||||
"""从 Feishu 消息事件中提取发送者 union_id(跨应用唯一)。"""
|
||||
try:
|
||||
ev = data.event
|
||||
sender = getattr(ev, "sender", None)
|
||||
if not sender:
|
||||
return None
|
||||
sender_id = getattr(sender, "sender_id", None)
|
||||
if not sender_id:
|
||||
return None
|
||||
return getattr(sender_id, "union_id", None)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _get_chat_type(data) -> str:
|
||||
"""获取聊天类型。"""
|
||||
try:
|
||||
@@ -103,6 +118,7 @@ def _reply_card(open_id: str, title: str, content: str, status: str = "info"):
|
||||
async def _handle_message_async(data):
|
||||
"""异步处理飞书消息。"""
|
||||
open_id = _get_sender_open_id(data)
|
||||
union_id = _get_sender_union_id(data)
|
||||
chat_type = _get_chat_type(data)
|
||||
text = _get_message_text(data)
|
||||
|
||||
@@ -128,11 +144,21 @@ async def _handle_message_async(data):
|
||||
from app.core.database import SessionLocal
|
||||
from app.models.user import User
|
||||
from app.models.agent import Agent
|
||||
from app.services.feishu_open_id_service import resolve_user_and_save
|
||||
|
||||
db: Optional[Session] = None
|
||||
try:
|
||||
db = SessionLocal()
|
||||
|
||||
# 自动保存/关联此应用的 open_id(跨应用识别)
|
||||
resolved_uid = resolve_user_and_save(
|
||||
db, app_id=settings.FEISHU_APP_ID or "",
|
||||
open_id=open_id, union_id=union_id,
|
||||
)
|
||||
|
||||
user = db.query(User).filter(User.feishu_open_id == open_id).first()
|
||||
if not user and resolved_uid:
|
||||
user = db.query(User).filter(User.id == resolved_uid).first()
|
||||
if not user:
|
||||
_reply_to_feishu(open_id, "你的账号未绑定平台用户,请先在平台绑定飞书。")
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user