ForcePilot/backend/package/yuxi/channels/adapters/dingding/stream_handler.py
Kris 86105d163d feat(dingding): add dingtalk channel adapter implementation
实现钉钉官方的频道适配器,包含完整的消息收发、事件处理、媒体上传下载、流式响应以及webhook支持,覆盖了认证、签名校验、速率限制、健康检查等完整功能流程。
2026-05-12 00:43:14 +08:00

68 lines
2.1 KiB
Python

from __future__ import annotations
import logging
from typing import TYPE_CHECKING
logger = logging.getLogger(__name__)
if TYPE_CHECKING:
from yuxi.channels.adapters.dingding.adapter import DingDingChannelAdapter
HAS_DINGTALK_STREAM = False
try:
import dingtalk_stream # noqa: F401
HAS_DINGTALK_STREAM = True
except ImportError:
pass
class DingDingChatbotHandler:
def __init__(self, adapter: DingDingChannelAdapter):
self._adapter = adapter
async def process(self, callback: object) -> tuple[int, str]:
if not HAS_DINGTALK_STREAM:
return 200, "OK"
from dingtalk_stream import AckMessage
try:
raw_data = getattr(callback, "data", {})
session_webhook = getattr(callback, "sessionWebhook", None) or raw_data.get("sessionWebhook", "")
if session_webhook:
self._adapter._session_webhooks[raw_data.get("conversationId", "")] = session_webhook
msg = self._adapter.normalize_inbound(raw_data)
await self._adapter._handle_message(msg)
return AckMessage.STATUS_OK, "OK"
except Exception as e:
logger.error(f"[DingDing] ChatbotHandler error: {e}")
return AckMessage.STATUS_INTERNAL_SERVER_ERROR, str(e)
class DingDingCallbackHandler:
"""互动卡片回传事件处理器"""
def __init__(self, adapter: DingDingChannelAdapter):
self._adapter = adapter
async def process(self, callback: object) -> tuple[int, str]:
if not HAS_DINGTALK_STREAM:
return 200, "OK"
from dingtalk_stream import AckMessage
try:
raw_data = getattr(callback, "data", {})
from yuxi.channels.models import EventType
msg = self._adapter.normalize_inbound(raw_data)
msg.event_type = EventType.CARD_ACTION
await self._adapter._handle_message(msg)
return AckMessage.STATUS_OK, "OK"
except Exception as e:
logger.error(f"[DingDing] CallbackHandler error: {e}")
return AckMessage.STATUS_INTERNAL_SERVER_ERROR, str(e)