From b06b32306f5079d95995929c76b1c35d3d99a48e Mon Sep 17 00:00:00 2001 From: Junyan Qin Date: Fri, 5 Dec 2025 17:24:58 +0800 Subject: [PATCH] feat: remove all unnecessary fields in GroupMember and implement MessageEvent field for pipeline events --- src/langbot/pkg/pipeline/pipelinemgr.py | 1 + .../pkg/pipeline/process/handlers/chat.py | 1 + src/langbot/pkg/platform/sources/aiocqhttp.py | 3 -- src/langbot/pkg/platform/sources/dingtalk.py | 3 -- src/langbot/pkg/platform/sources/discord.py | 3 -- src/langbot/pkg/platform/sources/kook.py | 3 -- src/langbot/pkg/platform/sources/lark.py | 36 ++++++++----------- .../pkg/platform/sources/legacy/gewechat.py | 3 -- .../pkg/platform/sources/legacy/nakuru.py | 3 -- .../pkg/platform/sources/legacy/qqbotpy.py | 8 ----- src/langbot/pkg/platform/sources/line.py | 3 -- .../pkg/platform/sources/qqofficial.py | 6 ---- src/langbot/pkg/platform/sources/slack.py | 23 +++++------- src/langbot/pkg/platform/sources/telegram.py | 3 -- src/langbot/pkg/platform/sources/wechatpad.py | 3 -- src/langbot/pkg/platform/sources/wecombot.py | 3 -- src/langbot/pkg/plugin/handler.py | 2 ++ 17 files changed, 28 insertions(+), 79 deletions(-) diff --git a/src/langbot/pkg/pipeline/pipelinemgr.py b/src/langbot/pkg/pipeline/pipelinemgr.py index d9915583..06f77b28 100644 --- a/src/langbot/pkg/pipeline/pipelinemgr.py +++ b/src/langbot/pkg/pipeline/pipelinemgr.py @@ -237,6 +237,7 @@ class RuntimePipeline: launcher_type=query.launcher_type.value, launcher_id=query.launcher_id, sender_id=query.sender_id, + message_event=query.message_event, message_chain=query.message_chain, ) diff --git a/src/langbot/pkg/pipeline/process/handlers/chat.py b/src/langbot/pkg/pipeline/process/handlers/chat.py index 965f50db..817e0b77 100644 --- a/src/langbot/pkg/pipeline/process/handlers/chat.py +++ b/src/langbot/pkg/pipeline/process/handlers/chat.py @@ -40,6 +40,7 @@ class ChatMessageHandler(handler.MessageHandler): launcher_id=query.launcher_id, sender_id=query.sender_id, text_message=str(query.message_chain), + message_event=query.message_event, message_chain=query.message_chain, query=query, ) diff --git a/src/langbot/pkg/platform/sources/aiocqhttp.py b/src/langbot/pkg/platform/sources/aiocqhttp.py index f255a330..a8cf8acc 100644 --- a/src/langbot/pkg/platform/sources/aiocqhttp.py +++ b/src/langbot/pkg/platform/sources/aiocqhttp.py @@ -327,9 +327,6 @@ class AiocqhttpEventConverter(abstract_platform_adapter.AbstractEventConverter): permission=platform_entities.Permission.Member, ), special_title=event.sender['title'] if 'title' in event.sender else '', - join_timestamp=0, - last_speak_timestamp=0, - mute_time_remaining=0, ), message_chain=yiri_chain, time=event.time, diff --git a/src/langbot/pkg/platform/sources/dingtalk.py b/src/langbot/pkg/platform/sources/dingtalk.py index 189e3288..a47a5238 100644 --- a/src/langbot/pkg/platform/sources/dingtalk.py +++ b/src/langbot/pkg/platform/sources/dingtalk.py @@ -119,9 +119,6 @@ class DingTalkEventConverter(abstract_platform_adapter.AbstractEventConverter): permission=platform_entities.Permission.Member, ), special_title='', - join_timestamp=0, - last_speak_timestamp=0, - mute_time_remaining=0, ) time = event.incoming_message.create_at return platform_events.GroupMessage( diff --git a/src/langbot/pkg/platform/sources/discord.py b/src/langbot/pkg/platform/sources/discord.py index 933961de..7653e03f 100644 --- a/src/langbot/pkg/platform/sources/discord.py +++ b/src/langbot/pkg/platform/sources/discord.py @@ -769,9 +769,6 @@ class DiscordEventConverter(abstract_platform_adapter.AbstractEventConverter): permission=platform_entities.Permission.Member, ), special_title='', - join_timestamp=0, - last_speak_timestamp=0, - mute_time_remaining=0, ), message_chain=message_chain, time=event.created_at.timestamp(), diff --git a/src/langbot/pkg/platform/sources/kook.py b/src/langbot/pkg/platform/sources/kook.py index 2ae3196c..d5070be4 100644 --- a/src/langbot/pkg/platform/sources/kook.py +++ b/src/langbot/pkg/platform/sources/kook.py @@ -219,9 +219,6 @@ class KookEventConverter(abstract_platform_adapter.AbstractEventConverter): permission=platform_entities.Permission.Member, ), special_title='', - join_timestamp=0, - last_speak_timestamp=0, - mute_time_remaining=0, ), message_chain=message_chain, time=event_time, diff --git a/src/langbot/pkg/platform/sources/lark.py b/src/langbot/pkg/platform/sources/lark.py index e442ed12..77fae8b0 100644 --- a/src/langbot/pkg/platform/sources/lark.py +++ b/src/langbot/pkg/platform/sources/lark.py @@ -55,9 +55,7 @@ class AESCipher(object): class LarkMessageConverter(abstract_platform_adapter.AbstractMessageConverter): @staticmethod - async def upload_image_to_lark( - msg: platform_message.Image, api_client: lark_oapi.Client - ) -> typing.Optional[str]: + async def upload_image_to_lark(msg: platform_message.Image, api_client: lark_oapi.Client) -> typing.Optional[str]: """Upload an image to Lark and return the image_key, or None if upload fails.""" image_bytes = None @@ -95,7 +93,9 @@ class LarkMessageConverter(abstract_platform_adapter.AbstractMessageConverter): return None if image_bytes is None: - print(f'No image data available for Image message (url={msg.url}, base64={bool(msg.base64)}, path={msg.path})') + print( + f'No image data available for Image message (url={msg.url}, base64={bool(msg.base64)}, path={msg.path})' + ) return None try: @@ -113,10 +113,7 @@ class LarkMessageConverter(abstract_platform_adapter.AbstractMessageConverter): request = ( CreateImageRequest.builder() .request_body( - CreateImageRequestBody.builder() - .image_type('message') - .image(open(temp_file_path, 'rb')) - .build() + CreateImageRequestBody.builder().image_type('message').image(open(temp_file_path, 'rb')).build() ) .build() ) @@ -143,7 +140,7 @@ class LarkMessageConverter(abstract_platform_adapter.AbstractMessageConverter): message_chain: platform_message.MessageChain, api_client: lark_oapi.Client ) -> typing.Tuple[list, list]: """Convert message chain to Lark format. - + Returns: Tuple of (text_elements, image_keys): - text_elements: List of paragraphs for post message format @@ -159,24 +156,24 @@ class LarkMessageConverter(abstract_platform_adapter.AbstractMessageConverter): async def process_text_with_images(text: str) -> typing.Tuple[str, list]: """Extract Markdown images from text and return cleaned text + image URLs.""" extracted_urls = [] - + # Find all Markdown images matches = list(markdown_image_pattern.finditer(text)) if not matches: return text, [] - + # Extract URLs and remove image syntax from text cleaned_text = text for match in reversed(matches): # Reverse to maintain correct positions url = match.group(2) extracted_urls.insert(0, url) # Insert at beginning since we're going in reverse # Replace image syntax with empty string or a placeholder - cleaned_text = cleaned_text[:match.start()] + cleaned_text[match.end():] - + cleaned_text = cleaned_text[: match.start()] + cleaned_text[match.end() :] + # Clean up multiple consecutive newlines that might result from removing images cleaned_text = re.sub(r'\n{3,}', '\n\n', cleaned_text) cleaned_text = cleaned_text.strip() - + return cleaned_text, extracted_urls for msg in message_chain: @@ -189,14 +186,14 @@ class LarkMessageConverter(abstract_platform_adapter.AbstractMessageConverter): text = msg.text.encode('latin1').decode('utf-8') except UnicodeError: text = msg.text.encode('utf-8', errors='replace').decode('utf-8') - + # Check for and extract Markdown images from text cleaned_text, extracted_urls = await process_text_with_images(text) - + # Add cleaned text if not empty if cleaned_text: pending_paragraph.append({'tag': 'md', 'text': cleaned_text}) - + # Process extracted image URLs for url in extracted_urls: # Create a temporary Image message to upload @@ -204,7 +201,7 @@ class LarkMessageConverter(abstract_platform_adapter.AbstractMessageConverter): image_key = await LarkMessageConverter.upload_image_to_lark(temp_image, api_client) if image_key: image_keys.append(image_key) - + elif isinstance(msg, platform_message.At): pending_paragraph.append({'tag': 'at', 'user_id': msg.target, 'style': []}) elif isinstance(msg, platform_message.AtAll): @@ -369,9 +366,6 @@ class LarkEventConverter(abstract_platform_adapter.AbstractEventConverter): permission=platform_entities.Permission.Member, ), special_title='', - join_timestamp=0, - last_speak_timestamp=0, - mute_time_remaining=0, ), message_chain=message_chain, time=event.event.message.create_time, diff --git a/src/langbot/pkg/platform/sources/legacy/gewechat.py b/src/langbot/pkg/platform/sources/legacy/gewechat.py index cd5dcf22..93bef53c 100644 --- a/src/langbot/pkg/platform/sources/legacy/gewechat.py +++ b/src/langbot/pkg/platform/sources/legacy/gewechat.py @@ -437,9 +437,6 @@ class GewechatEventConverter(abstract_platform_adapter.AbstractEventConverter): permission=platform_entities.Permission.Member, ), special_title='', - join_timestamp=0, - last_speak_timestamp=0, - mute_time_remaining=0, ), message_chain=message_chain, time=event['Data']['CreateTime'], diff --git a/src/langbot/pkg/platform/sources/legacy/nakuru.py b/src/langbot/pkg/platform/sources/legacy/nakuru.py index 52609792..1e34af0b 100644 --- a/src/langbot/pkg/platform/sources/legacy/nakuru.py +++ b/src/langbot/pkg/platform/sources/legacy/nakuru.py @@ -153,9 +153,6 @@ class NakuruProjectEventConverter(abstract_platform_adapter.AbstractEventConvert permission=platform_entities.Permission.Member, ), special_title=event.sender.title, - join_timestamp=0, - last_speak_timestamp=0, - mute_time_remaining=0, ), message_chain=yiri_chain, time=event.time, diff --git a/src/langbot/pkg/platform/sources/legacy/qqbotpy.py b/src/langbot/pkg/platform/sources/legacy/qqbotpy.py index 90e4c2d7..3a55482c 100644 --- a/src/langbot/pkg/platform/sources/legacy/qqbotpy.py +++ b/src/langbot/pkg/platform/sources/legacy/qqbotpy.py @@ -279,11 +279,6 @@ class OfficialEventConverter(abstract_platform_adapter.AbstractEventConverter): permission=platform_entities.Permission.Member, ), special_title='', - join_timestamp=int( - datetime.datetime.strptime(event.member.joined_at, '%Y-%m-%dT%H:%M:%S%z').timestamp() - ), - last_speak_timestamp=datetime.datetime.now().timestamp(), - mute_time_remaining=0, ), message_chain=OfficialMessageConverter.extract_message_chain_from_obj(event, event.id), time=int(datetime.datetime.strptime(event.timestamp, '%Y-%m-%dT%H:%M:%S%z').timestamp()), @@ -312,9 +307,6 @@ class OfficialEventConverter(abstract_platform_adapter.AbstractEventConverter): permission=platform_entities.Permission.Member, ), special_title='', - join_timestamp=int(0), - last_speak_timestamp=datetime.datetime.now().timestamp(), - mute_time_remaining=0, ), message_chain=OfficialMessageConverter.extract_message_chain_from_obj(event, event.id), time=int(datetime.datetime.strptime(event.timestamp, '%Y-%m-%dT%H:%M:%S%z').timestamp()), diff --git a/src/langbot/pkg/platform/sources/line.py b/src/langbot/pkg/platform/sources/line.py index c36b4f05..97e3802c 100644 --- a/src/langbot/pkg/platform/sources/line.py +++ b/src/langbot/pkg/platform/sources/line.py @@ -108,9 +108,6 @@ class LINEEventConverter(abstract_platform_adapter.AbstractEventConverter): permission=platform_entities.Permission.Member, ), special_title='', - join_timestamp=0, - last_speak_timestamp=0, - mute_time_remaining=0, ), message_chain=message_chain, time=event.timestamp, diff --git a/src/langbot/pkg/platform/sources/qqofficial.py b/src/langbot/pkg/platform/sources/qqofficial.py index a3288793..a5444119 100644 --- a/src/langbot/pkg/platform/sources/qqofficial.py +++ b/src/langbot/pkg/platform/sources/qqofficial.py @@ -94,9 +94,6 @@ class QQOfficialEventConverter(abstract_platform_adapter.AbstractEventConverter) permission=platform_entities.Permission.Member, ), special_title='', - join_timestamp=0, - last_speak_timestamp=0, - mute_time_remaining=0, ) time = int(datetime.datetime.strptime(event.timestamp, '%Y-%m-%dT%H:%M:%S%z').timestamp()) return platform_events.GroupMessage( @@ -117,9 +114,6 @@ class QQOfficialEventConverter(abstract_platform_adapter.AbstractEventConverter) permission=platform_entities.Permission.Member, ), special_title='', - join_timestamp=0, - last_speak_timestamp=0, - mute_time_remaining=0, ) time = int(datetime.datetime.strptime(event.timestamp, '%Y-%m-%dT%H:%M:%S%z').timestamp()) return platform_events.GroupMessage( diff --git a/src/langbot/pkg/platform/sources/slack.py b/src/langbot/pkg/platform/sources/slack.py index 1f2a70b7..e325657f 100644 --- a/src/langbot/pkg/platform/sources/slack.py +++ b/src/langbot/pkg/platform/sources/slack.py @@ -76,9 +76,6 @@ class SlackEventConverter(abstract_platform_adapter.AbstractEventConverter): id=event.channel_id, name='MEMBER', permission=platform_entities.Permission.Member ), special_title='', - join_timestamp=0, - last_speak_timestamp=0, - mute_time_remaining=0, ) time = int(datetime.datetime.utcnow().timestamp()) return platform_events.GroupMessage( @@ -112,10 +109,7 @@ class SlackAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter): raise command_errors.ParamNotEnoughError('Slack机器人缺少相关配置项,请查看文档或联系管理员') bot = SlackClient( - bot_token=config['bot_token'], - signing_secret=config['signing_secret'], - logger=logger, - unified_mode=True + bot_token=config['bot_token'], signing_secret=config['signing_secret'], logger=logger, unified_mode=True ) super().__init__( @@ -199,19 +193,20 @@ class SlackAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter): if self.bot_uuid and hasattr(self.logger, 'ap'): try: api_port = self.logger.ap.instance_config.data['api']['port'] - webhook_url = f"http://127.0.0.1:{api_port}/bots/{self.bot_uuid}" - webhook_url_public = f"http://:{api_port}/bots/{self.bot_uuid}" + webhook_url = f'http://127.0.0.1:{api_port}/bots/{self.bot_uuid}' + webhook_url_public = f'http://:{api_port}/bots/{self.bot_uuid}' - await self.logger.info(f"Slack 机器人 Webhook 回调地址:") - await self.logger.info(f" 本地地址: {webhook_url}") - await self.logger.info(f" 公网地址: {webhook_url_public}") - await self.logger.info(f"请在 Slack 后台配置此回调地址") + await self.logger.info('Slack 机器人 Webhook 回调地址:') + await self.logger.info(f' 本地地址: {webhook_url}') + await self.logger.info(f' 公网地址: {webhook_url_public}') + await self.logger.info('请在 Slack 后台配置此回调地址') except Exception as e: - await self.logger.warning(f"无法生成 webhook URL: {e}") + await self.logger.warning(f'无法生成 webhook URL: {e}') async def keep_alive(): while True: await asyncio.sleep(1) + await keep_alive() async def kill(self) -> bool: diff --git a/src/langbot/pkg/platform/sources/telegram.py b/src/langbot/pkg/platform/sources/telegram.py index 537a8d92..b081d6dc 100644 --- a/src/langbot/pkg/platform/sources/telegram.py +++ b/src/langbot/pkg/platform/sources/telegram.py @@ -120,9 +120,6 @@ class TelegramEventConverter(abstract_platform_adapter.AbstractEventConverter): permission=platform_entities.Permission.Member, ), special_title='', - join_timestamp=0, - last_speak_timestamp=0, - mute_time_remaining=0, ), message_chain=lb_message, time=event.message.date.timestamp(), diff --git a/src/langbot/pkg/platform/sources/wechatpad.py b/src/langbot/pkg/platform/sources/wechatpad.py index 72609cfc..1c9c5ee2 100644 --- a/src/langbot/pkg/platform/sources/wechatpad.py +++ b/src/langbot/pkg/platform/sources/wechatpad.py @@ -501,9 +501,6 @@ class WeChatPadEventConverter(abstract_platform_adapter.AbstractEventConverter): permission=platform_entities.Permission.Member, ), special_title='', - join_timestamp=0, - last_speak_timestamp=0, - mute_time_remaining=0, ), message_chain=message_chain, time=event['create_time'], diff --git a/src/langbot/pkg/platform/sources/wecombot.py b/src/langbot/pkg/platform/sources/wecombot.py index 5fd66aca..77a35ddb 100644 --- a/src/langbot/pkg/platform/sources/wecombot.py +++ b/src/langbot/pkg/platform/sources/wecombot.py @@ -67,9 +67,6 @@ class WecomBotEventConverter(abstract_platform_adapter.AbstractEventConverter): permission=platform_entities.Permission.Member, ), special_title='', - join_timestamp=0, - last_speak_timestamp=0, - mute_time_remaining=0, ) time = datetime.datetime.now().timestamp() return platform_events.GroupMessage( diff --git a/src/langbot/pkg/plugin/handler.py b/src/langbot/pkg/plugin/handler.py index 155721b3..a916bdff 100644 --- a/src/langbot/pkg/plugin/handler.py +++ b/src/langbot/pkg/plugin/handler.py @@ -139,6 +139,8 @@ class RuntimeConnectionHandler(handler.Handler): message_chain_obj = platform_message.MessageChain.model_validate(message_chain) + self.ap.logger.debug(f'Reply message: {message_chain_obj.model_dump(serialize_as_any=False)}') + await query.adapter.reply_message( query.message_event, message_chain_obj,