feat: 添加物流查询功能和完善 token 传递
- 添加 get_logistics 工具查询 Mall API /mall/api/order/parcel - 修复 Cookie token 传递到 MCP 的问题 - 增强 LLM 客户端超时处理和日志 - 移除 MALL_API_TOKEN,使用用户登录 token - 更新测试页面使用 setUser 设置用户属性 - 增强 webhook 调试日志
This commit is contained in:
@@ -136,6 +136,26 @@ async def handle_incoming_message(payload: ChatwootWebhookPayload, cookie_token:
|
||||
contact = payload.contact or payload.sender
|
||||
user_id = str(contact.id) if contact else "unknown"
|
||||
|
||||
# Log webhook payload structure for debugging
|
||||
logger.info(
|
||||
"Webhook payload structure",
|
||||
payload_event=payload.event,
|
||||
has_conversation=bool(conversation),
|
||||
has_contact=bool(contact),
|
||||
contact_type=type(contact).__name__ if contact else None,
|
||||
conversation_id=conversation_id
|
||||
)
|
||||
|
||||
# Log full payload keys for debugging
|
||||
payload_dict = payload.model_dump()
|
||||
logger.info(
|
||||
"Full webhook payload keys",
|
||||
keys=list(payload_dict.keys()),
|
||||
conversation_keys=list(payload_dict.get('conversation', {}).keys()) if payload_dict.get('conversation') else [],
|
||||
contact_keys=list(payload_dict.get('contact', {}).keys()) if payload_dict.get('contact') else [],
|
||||
sender_keys=list(payload_dict.get('sender', {}).keys()) if payload_dict.get('sender') else []
|
||||
)
|
||||
|
||||
# Get account_id from payload (top-level account object)
|
||||
# Chatwoot webhook includes account info at the top level
|
||||
account_obj = payload.account
|
||||
@@ -148,13 +168,35 @@ async def handle_incoming_message(payload: ChatwootWebhookPayload, cookie_token:
|
||||
if not user_token:
|
||||
# 1. 尝试从 contact/custom_attributes 获取
|
||||
if contact:
|
||||
contact_dict = contact.model_dump() if hasattr(contact, 'model_dump') else contact.__dict__
|
||||
user_token = TokenManager.extract_token_from_contact(contact_dict)
|
||||
logger.debug("Extracted token from contact", has_token=bool(user_token))
|
||||
logger.info(
|
||||
"Checking contact for token",
|
||||
contact_id=contact.id if contact else None,
|
||||
contact_type=type(contact).__name__
|
||||
)
|
||||
|
||||
# 只有 WebhookContact 才有 custom_attributes
|
||||
if hasattr(contact, 'custom_attributes'):
|
||||
logger.info(
|
||||
"Checking contact custom_attributes",
|
||||
has_custom_attributes=bool(contact.custom_attributes)
|
||||
)
|
||||
|
||||
custom_attrs = contact.custom_attributes or {}
|
||||
logger.info(
|
||||
"Contact custom_attributes",
|
||||
keys=list(custom_attrs.keys()) if custom_attrs else [],
|
||||
has_jwt_token='jwt_token' in custom_attrs if custom_attrs else False,
|
||||
has_mall_token='mall_token' in custom_attrs if custom_attrs else False
|
||||
)
|
||||
|
||||
contact_dict = {"custom_attributes": custom_attrs}
|
||||
user_token = TokenManager.extract_token_from_contact(contact_dict)
|
||||
logger.debug("Extracted token from contact", has_token=bool(user_token))
|
||||
else:
|
||||
logger.debug("Contact type is WebhookSender, no custom_attributes available")
|
||||
|
||||
# 2. 尝试从 conversation.meta.sender.custom_attributes 获取(Chatwoot SDK setUser 设置的位置)
|
||||
if not user_token and conversation:
|
||||
# 记录 conversation 的类型和内容用于调试
|
||||
logger.debug("Conversation object type", type=str(type(conversation)))
|
||||
if hasattr(conversation, 'model_dump'):
|
||||
conv_dict = conversation.model_dump()
|
||||
@@ -162,12 +204,32 @@ async def handle_incoming_message(payload: ChatwootWebhookPayload, cookie_token:
|
||||
logger.debug("Has meta", has_meta='meta' in conv_dict)
|
||||
|
||||
meta_sender = conv_dict.get('meta', {}).get('sender', {})
|
||||
logger.info(
|
||||
"Conversation meta.sender",
|
||||
has_sender=bool(meta_sender),
|
||||
sender_keys=list(meta_sender.keys()) if meta_sender else [],
|
||||
has_custom_attributes=bool(meta_sender.get('custom_attributes')) if meta_sender else False
|
||||
)
|
||||
|
||||
if meta_sender.get('custom_attributes'):
|
||||
logger.info("Found custom_attributes in meta.sender", keys=list(meta_sender['custom_attributes'].keys()))
|
||||
user_token = TokenManager.extract_token_from_contact({'custom_attributes': meta_sender['custom_attributes']})
|
||||
logger.info("Token found in conversation.meta.sender.custom_attributes", token_prefix=user_token[:20] if user_token else None)
|
||||
|
||||
if user_token:
|
||||
logger.info("JWT token found", user_id=user_id, source="cookie" if cookie_token else "contact")
|
||||
logger.info(
|
||||
"JWT token found",
|
||||
user_id=user_id,
|
||||
source="cookie" if cookie_token else "contact",
|
||||
token_prefix=user_token[:20] if user_token else None
|
||||
)
|
||||
else:
|
||||
logger.warning(
|
||||
"No JWT token found from any source",
|
||||
user_id=user_id,
|
||||
cookie_token_exists=bool(cookie_token),
|
||||
contact_type=type(contact).__name__ if contact else None
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"Processing incoming message",
|
||||
@@ -352,7 +414,9 @@ async def chatwoot_webhook(
|
||||
# 尝试从请求 Cookie 中获取用户 Token
|
||||
user_token = request.cookies.get("token") # 从 Cookie 读取 token
|
||||
if user_token:
|
||||
logger.info("User token found in request cookies")
|
||||
logger.info("User token found in request cookies", token_prefix=user_token[:20])
|
||||
else:
|
||||
logger.debug("No token found in request cookies (this is expected for webhook requests)")
|
||||
|
||||
# Verify signature
|
||||
signature = request.headers.get("X-Chatwoot-Signature", "")
|
||||
|
||||
Reference in New Issue
Block a user