diff --git a/gateway/platforms/dingtalk.py b/gateway/platforms/dingtalk.py index dfa4f7363..1abf3a368 100644 --- a/gateway/platforms/dingtalk.py +++ b/gateway/platforms/dingtalk.py @@ -54,7 +54,7 @@ logger = logging.getLogger(__name__) MAX_MESSAGE_LENGTH = 20000 RECONNECT_BACKOFF = [2, 5, 10, 30, 60] _SESSION_WEBHOOKS_MAX = 500 -_DINGTALK_WEBHOOK_RE = re.compile(r'^https://api\.dingtalk\.com/') +_DINGTALK_WEBHOOK_RE = re.compile(r'^https://(?:api|oapi)\.dingtalk\.com/') def check_dingtalk_requirements() -> bool: @@ -128,12 +128,12 @@ class DingTalkAdapter(BasePlatformAdapter): return False async def _run_stream(self) -> None: - """Run the blocking stream client with auto-reconnection.""" + """Run the stream client with auto-reconnection.""" backoff_idx = 0 while self._running: try: logger.debug("[%s] Starting stream client...", self.name) - await asyncio.to_thread(self._stream_client.start) + await self._stream_client.start() except asyncio.CancelledError: return except Exception as e: @@ -314,19 +314,16 @@ class _IncomingHandler(ChatbotHandler if DINGTALK_STREAM_AVAILABLE else object): self._adapter = adapter self._loop = loop - def process(self, message: "ChatbotMessage"): - """Called by dingtalk-stream in its thread when a message arrives. + async def process(self, callback_message): + """Called by dingtalk-stream when a message arrives. - Schedules the async handler on the main event loop. + dingtalk-stream >= 0.24 passes a CallbackMessage whose `.data` contains + the chatbot payload. Convert it to ChatbotMessage and await the adapter + handler directly on the main event loop. """ - loop = self._loop - if loop is None or loop.is_closed(): - logger.error("[DingTalk] Event loop unavailable, cannot dispatch message") - return dingtalk_stream.AckMessage.STATUS_OK, "OK" - - future = asyncio.run_coroutine_threadsafe(self._adapter._on_message(message), loop) try: - future.result(timeout=60) + chatbot_msg = ChatbotMessage.from_dict(callback_message.data) + await self._adapter._on_message(chatbot_msg) except Exception: logger.exception("[DingTalk] Error processing incoming message")