ForcePilot/backend/package/yuxi/channel/extensions/alipay/monitor.py
Kris 71364ea579 feat(alipay): 新增支付宝渠道插件完整实现
实现了支付宝生活号渠道的完整功能,包括消息接收回调、发送、安全验证、去重、配对绑定、流式回复支持等完整能力。
2026-05-21 10:39:23 +08:00

98 lines
3.3 KiB
Python

from datetime import datetime, UTC
from yuxi.channel.extensions.alipay.types import AlipayAccount, AlipayInboundEvent
from yuxi.channel.message.models import MessageType, PeerInfo, PeerKind, UnifiedMessage
def convert_alipay_event(event: AlipayInboundEvent, account: AlipayAccount) -> UnifiedMessage | None:
msg_type = _map_msg_type(event)
if event.msg_type == "event":
if event.event_type in ("follow", "enter"):
return _build_event_message(event, account, msg_type)
return None
return UnifiedMessage(
msg_id=event.msg_id,
channel_type="alipay",
account_id=account.account_id,
content=_extract_content(event),
sender=PeerInfo(
kind=PeerKind.DIRECT,
id=event.from_user_id,
display_name=event.from_user_name or event.from_user_id,
),
message_type=msg_type,
media_urls=_extract_media_urls(event),
timestamp=datetime.fromtimestamp(event.create_time / 1000, tz=UTC),
raw_payload=event.raw,
metadata={
"FromAlipayUserId": event.from_user_id,
"AppId": event.app_id,
"MsgType": event.msg_type,
"EventType": event.event_type or "",
},
body_for_agent=_extract_content(event),
)
def _map_msg_type(event: AlipayInboundEvent) -> MessageType:
if event.msg_type == "text":
return MessageType.TEXT
if event.msg_type == "image":
return MessageType.IMAGE
return MessageType.EVENT
def _extract_content(event: AlipayInboundEvent) -> str:
if event.msg_type == "text":
return (event.biz_content or {}).get("content", "")
if event.msg_type == "image":
return "[图片消息]"
if event.msg_type == "event":
event_names = {
"follow": "关注了生活号",
"unfollow": "取消关注",
"enter": "进入了生活号",
"click": f"点击了菜单: {(event.biz_content or {}).get('action_name', '')}",
}
return event_names.get(event.event_type or "", f"事件: {event.event_type}")
return ""
def _extract_media_urls(event: AlipayInboundEvent) -> list[str]:
if event.msg_type == "image":
biz = event.biz_content or {}
urls = []
if biz.get("pic_url"):
urls.append(biz["pic_url"])
if biz.get("media_id"):
urls.append(f"alipay://media/{biz['media_id']}")
return urls
return []
def _build_event_message(event: AlipayInboundEvent, account: AlipayAccount, msg_type: MessageType) -> UnifiedMessage:
return UnifiedMessage(
msg_id=event.msg_id,
channel_type="alipay",
account_id=account.account_id,
content=_extract_content(event),
sender=PeerInfo(
kind=PeerKind.DIRECT,
id=event.from_user_id,
display_name=event.from_user_name or event.from_user_id,
),
message_type=msg_type,
media_urls=[],
timestamp=datetime.fromtimestamp(event.create_time / 1000, tz=UTC),
raw_payload=event.raw,
metadata={
"FromAlipayUserId": event.from_user_id,
"AppId": event.app_id,
"MsgType": event.msg_type,
"EventType": event.event_type or "",
},
body_for_agent=_extract_content(event),
)