From adb0bf247387dae14e581567d1f0fd4a13e30200 Mon Sep 17 00:00:00 2001 From: Dong_master <2213070223@qq.com> Date: Sat, 19 Jul 2025 01:05:44 +0800 Subject: [PATCH] feat:add dingtalk stream --- pkg/platform/sources/dingtalk.py | 73 ++++++++++++++++++++++++++---- pkg/platform/sources/dingtalk.yaml | 17 +++++++ 2 files changed, 81 insertions(+), 9 deletions(-) diff --git a/pkg/platform/sources/dingtalk.py b/pkg/platform/sources/dingtalk.py index 3147c984..f297019d 100644 --- a/pkg/platform/sources/dingtalk.py +++ b/pkg/platform/sources/dingtalk.py @@ -99,11 +99,13 @@ class DingTalkAdapter(adapter.MessagePlatformAdapter): message_converter: DingTalkMessageConverter = DingTalkMessageConverter() event_converter: DingTalkEventConverter = DingTalkEventConverter() config: dict + card_instance_id_dict: dict def __init__(self, config: dict, ap: app.Application, logger: EventLogger): self.config = config self.ap = ap self.logger = logger + self.card_instance_id_dict = {} required_keys = [ 'client_id', 'client_secret', @@ -116,6 +118,15 @@ class DingTalkAdapter(adapter.MessagePlatformAdapter): self.bot_account_id = self.config['robot_name'] + self.bot = DingTalkClient( + client_id=config['client_id'], + client_secret=config['client_secret'], + robot_name=config['robot_name'], + robot_code=config['robot_code'], + markdown_card=config['markdown_card'], + logger=self.logger, + ) + async def reply_message( self, message_source: platform_events.MessageEvent, @@ -130,6 +141,34 @@ class DingTalkAdapter(adapter.MessagePlatformAdapter): content, at = await DingTalkMessageConverter.yiri2target(message) await self.bot.send_message(content, incoming_message, at) + async def reply_message_chunk( + self, + message_source: platform_events.MessageEvent, + message_id: int, + message: platform_message.MessageChain, + quote_origin: bool = False, + is_final: bool = False, + ): + event = await DingTalkEventConverter.yiri2target( + message_source, + ) + incoming_message = event.incoming_message + + msg_id = incoming_message.message_id + + content, at = await DingTalkMessageConverter.yiri2target(message) + # is_stream = self.config['enable-stream-reply'] + # print(content) + card_template_id = self.config['card_template_id'] + if msg_id not in self.card_instance_id_dict: + card_instance,card_instance_id = await self.bot.create_and_card(card_template_id,incoming_message,at) + self.card_instance_id_dict[msg_id] = (card_instance,card_instance_id) + else: + card_instance,card_instance_id = self.card_instance_id_dict[msg_id] + # print(card_instance_id) + await self.bot.send_card_message(card_instance,card_instance_id,content,is_final) + + async def send_message(self, target_type: str, target_id: str, message: platform_message.MessageChain): content = await DingTalkMessageConverter.yiri2target(message) if target_type == 'person': @@ -137,6 +176,21 @@ class DingTalkAdapter(adapter.MessagePlatformAdapter): if target_type == 'group': await self.bot.send_proactive_message_to_group(target_id, content) + async def is_stream_output_supported(self) -> bool: + is_stream = False + if self.config.get("enable-stream-reply", None): + is_stream = True + self.is_stream = is_stream + + return is_stream + + async def create_message_card(self,message_id: str, incoming_message): + card_template_id = self.config['card_template_id'] + + card_instance, card_instance_id = await self.bot.create_and_card(card_template_id, incoming_message) + self.card_instance_id_dict[message_id] = (card_instance, card_instance_id) + + def register_listener( self, event_type: typing.Type[platform_events.Event], @@ -144,6 +198,7 @@ class DingTalkAdapter(adapter.MessagePlatformAdapter): ): async def on_message(event: DingTalkEvent): try: + await self.is_stream_output_supported() return await callback( await self.event_converter.target2yiri(event, self.config['robot_name']), self, @@ -157,15 +212,15 @@ class DingTalkAdapter(adapter.MessagePlatformAdapter): self.bot.on_message('GroupMessage')(on_message) async def run_async(self): - config = self.config - self.bot = DingTalkClient( - client_id=config['client_id'], - client_secret=config['client_secret'], - robot_name=config['robot_name'], - robot_code=config['robot_code'], - markdown_card=config['markdown_card'], - logger=self.logger, - ) + # config = self.config + # self.bot = DingTalkClient( + # client_id=config['client_id'], + # client_secret=config['client_secret'], + # robot_name=config['robot_name'], + # robot_code=config['robot_code'], + # markdown_card=config['markdown_card'], + # logger=self.logger, + # ) await self.bot.start() async def kill(self) -> bool: diff --git a/pkg/platform/sources/dingtalk.yaml b/pkg/platform/sources/dingtalk.yaml index fac2d6ff..70855c2b 100644 --- a/pkg/platform/sources/dingtalk.yaml +++ b/pkg/platform/sources/dingtalk.yaml @@ -46,6 +46,23 @@ spec: type: boolean required: false default: true + - name: enable-stream-reply + label: + en_US: Enable Stream Reply Mode + zh_Hans: 启用钉钉卡片流式回复模式 + description: + en_US: If enabled, the bot will use the stream of lark reply mode + zh_Hans: 如果启用,将使用钉钉卡片流式方式来回复内容 + type: boolean + required: true + default: false + - name: card_template_id + label: + en_US: card template id + zh_Hans: 卡片模板ID + type: string + required: true + default: "填写你的卡片template_id" execution: python: path: ./dingtalk.py