ForcePilot/backend/package/yuxi/channel/extensions/webex/monitor.py
Kris 7b5d1e5c69 feat(channel): 添加 Webex、微信 iLink 和微信小程序渠道扩展
新增 Webex、微信 iLink、微信小程序三个渠道扩展。

Webex 渠道扩展功能模块:
- config: 渠道配置管理
- gateway: SSE/WebSocket 网关接入
- webhook: Webhook 事件处理
- outbound: 外发消息管理
- streaming: 流式消息处理
- pairing: 用户配对与绑定
- security: 安全校验
- dedupe: 消息去重
- monitor: 渠道状态监控
- status: 会话状态管理
- media: 媒体资源处理

微信 iLink 渠道扩展功能模块:
- config: 渠道配置管理
- gateway: SSE/WebSocket 网关接入
- outbound: 外发消息管理
- streaming: 流式消息处理
- pairing: 用户配对与绑定
- security: 安全校验
- dedupe: 消息去重
- monitor: 渠道状态监控
- status: 会话状态管理
- context_store: 上下文存储
- aes_ecb: AES-ECB 加解密
- media: 媒体资源处理
- typing: 输入状态

微信小程序渠道扩展功能模块:
- config: 渠道配置管理
- gateway: SSE/WebSocket 网关接入
- webhook: Webhook 事件处理
- outbound: 外发消息管理
- streaming: 流式消息处理
- pairing: 用户配对与绑定
- security: 安全校验
- crypto: 加解密处理
- dedupe: 消息去重
- message: 消息处理
- passive_reply: 被动回复
- media: 媒体资源处理
- status: 会话状态管理
2026-05-21 11:59:04 +08:00

65 lines
1.9 KiB
Python

import re
from yuxi.channel.message.models import UnifiedMessage, PeerInfo, GroupContext
from yuxi.channel.routing.models import PeerKind
from yuxi.channel.extensions.webex.types import WebexMessage
def payload_to_unified_message(
webex_msg: WebexMessage,
bot_person_id: str,
account_id: str,
) -> UnifiedMessage | None:
if webex_msg.person_id == bot_person_id:
return None
content = webex_msg.text or _extract_text_from_markdown(webex_msg.markdown)
if not content and not webex_msg.files:
return None
was_mentioned = any(m.get("personId") == bot_person_id for m in webex_msg.mentions)
msg_id = f"webex:{webex_msg.id}"
sender = PeerInfo(
kind=PeerKind.DIRECT if webex_msg.room_type == "direct" else PeerKind.GROUP,
id=webex_msg.person_id,
display_name=webex_msg.person_email,
)
group = None
if webex_msg.room_type == "group":
group = GroupContext(id=webex_msg.room_id, kind="group")
media_urls = webex_msg.files if webex_msg.files else []
return UnifiedMessage(
msg_id=msg_id,
channel_type="webex",
account_id=account_id,
content=content,
sender=sender,
group=group,
was_mentioned=was_mentioned,
reply_to_id=webex_msg.parent_id,
media_urls=media_urls,
raw_payload=webex_msg.raw,
metadata={
"room_id": webex_msg.room_id,
"room_type": webex_msg.room_type,
"person_email": webex_msg.person_email,
"debounce_key": f"webex:{webex_msg.person_id}:{webex_msg.room_id}",
},
conversation_label=f"webex:{webex_msg.room_id}",
native_direct_user_id=webex_msg.person_id,
)
def _extract_text_from_markdown(md: str) -> str:
if not md:
return ""
txt = md
txt = re.sub(r"\*\*(.+?)\*\*", r"\1", txt)
txt = re.sub(r"\*(.+?)\*", r"\1", txt)
txt = re.sub(r"#{1,6}\s+", "", txt)
return txt.strip()