From eb365e398d98bc3dfa2ca6353a34fe3586b4e9fe Mon Sep 17 00:00:00 2001 From: shuiping233 <1944680304@qq.com> Date: Mon, 2 Jun 2025 14:20:40 +0800 Subject: [PATCH 1/7] =?UTF-8?q?fix:=20qq=5Fofficial=E9=80=82=E9=85=8D?= =?UTF-8?q?=E5=99=A8=E4=BD=BF=E7=94=A8SessionController(=E4=BC=9A=E8=AF=9D?= =?UTF-8?q?=E6=8E=A7=E5=88=B6)=E5=8A=9F=E8=83=BD=E6=97=B6=E6=9C=BA?= =?UTF-8?q?=E5=99=A8=E4=BA=BA=E5=9B=9E=E5=A4=8D=E6=B6=88=E6=81=AF=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E5=8F=91=E9=80=81=E5=88=B0=E8=81=8A=E5=A4=A9=E5=B9=B3?= =?UTF-8?q?=E5=8F=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/platform/sources/qqofficial/qqofficial_message_event.py | 1 + 1 file changed, 1 insertion(+) diff --git a/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py b/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py index d55c2671b..afb84880e 100644 --- a/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py +++ b/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py @@ -32,6 +32,7 @@ class QQOfficialMessageEvent(AstrMessageEvent): self.send_buffer = message else: self.send_buffer.chain.extend(message.chain) + await self._post_send() async def send_streaming(self, generator, use_fallback: bool = False): """流式输出仅支持消息列表私聊""" From 1ce95c473d89913706fa2d1fbb70f8782044b1f0 Mon Sep 17 00:00:00 2001 From: shuiping233 <1944680304@qq.com> Date: Sun, 8 Jun 2025 10:19:37 +0800 Subject: [PATCH 2/7] =?UTF-8?q?fix=20:=20=E5=9C=A8stage.py=E4=B8=AD?= =?UTF-8?q?=E4=B8=93=E9=97=A8=E5=AF=B9qq=5Fofficial=E7=9A=84=E4=BC=9A?= =?UTF-8?q?=E8=AF=9D=E6=8E=A7=E5=88=B6=E5=99=A8=E6=B6=88=E6=81=AF=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- astrbot/core/pipeline/respond/stage.py | 4 ++++ .../platform/sources/qqofficial/qqofficial_message_event.py | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/astrbot/core/pipeline/respond/stage.py b/astrbot/core/pipeline/respond/stage.py index 275926ba9..ad0a62c8b 100644 --- a/astrbot/core/pipeline/respond/stage.py +++ b/astrbot/core/pipeline/respond/stage.py @@ -211,6 +211,10 @@ class RespondStage(Stage): logger.info( f"AstrBot -> {event.get_sender_name()}/{event.get_sender_id()}: {event._outline_chain(result.chain)}" ) + else: + # 对使用 qq_official 适配器的会话控制器发送消息的特殊处理 + if event.get_platform_name() == "qq_official": + await event._post_send() handlers = star_handlers_registry.get_handlers_by_event_type( EventType.OnAfterMessageSentEvent, platform_id=event.get_platform_id() diff --git a/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py b/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py index afb84880e..d55c2671b 100644 --- a/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py +++ b/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py @@ -32,7 +32,6 @@ class QQOfficialMessageEvent(AstrMessageEvent): self.send_buffer = message else: self.send_buffer.chain.extend(message.chain) - await self._post_send() async def send_streaming(self, generator, use_fallback: bool = False): """流式输出仅支持消息列表私聊""" From e7b4357fc72aa670e121e993f33dcf4ab7562d55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9B=9E=E5=BD=92=E5=A4=A9=E7=A9=BA?= Date: Wed, 25 Jun 2025 11:41:55 +0800 Subject: [PATCH 3/7] =?UTF-8?q?[feat]=20(discord=5Fplatform=5Fadapter)=20?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=E4=BA=86=E5=AF=B9=E6=9C=BA=E5=99=A8?= =?UTF-8?q?=E4=BA=BA=20Role=20Mention=20=E6=96=B9=E6=B3=95=E7=9A=84?= =?UTF-8?q?=E5=93=8D=E5=BA=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../discord/discord_platform_adapter.py | 63 +++++++++++-------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/astrbot/core/platform/sources/discord/discord_platform_adapter.py b/astrbot/core/platform/sources/discord/discord_platform_adapter.py index df40b5a23..d605ee621 100644 --- a/astrbot/core/platform/sources/discord/discord_platform_adapter.py +++ b/astrbot/core/platform/sources/discord/discord_platform_adapter.py @@ -166,38 +166,37 @@ class DiscordPlatformAdapter(Platform): content = message.content - # 如果机器人被@,移除@部分 - if ( - is_mentioned - and self.client - and self.client.user - and self.client.user in message.mentions - ): - # 构建机器人的@字符串,格式为 <@USER_ID> 或 <@!USER_ID> - mention_str = f"<@{self.client.user.id}>" - mention_str_nickname = ( - f"<@!{self.client.user.id}>" # 有些客户端会使用带!的格式 - ) + # 如果机器人被@,移除@部分 + # 剥离 User Mention (<@id>, <@!id>) + if self.client and self.client.user: + mention_str = f"<@{self.client.user.id}>" + mention_str_nickname = f"<@!{self.client.user.id}>" if content.startswith(mention_str): - content = content[len(mention_str) :].lstrip() + content = content[len(mention_str):].lstrip() elif content.startswith(mention_str_nickname): - content = content[len(mention_str_nickname) :].lstrip() + content = content[len(mention_str_nickname):].lstrip() + + # 剥离 Role Mention(bot 拥有的任一角色被提及,<@&role_id>) + if hasattr(message, "role_mentions") and hasattr(message, "guild") and message.guild: + bot_member = message.guild.get_member(self.client.user.id) if self.client and self.client.user else None + if bot_member and hasattr(bot_member, "roles"): + for role in bot_member.roles: + role_mention_str = f"<@&{role.id}>" + if content.startswith(role_mention_str): + content = content[len(role_mention_str):].lstrip() + break # 只剥离第一个匹配的角色 mention abm = AstrBotMessage() - abm.type = self._get_message_type(message.channel) abm.group_id = self._get_channel_id(message.channel) - abm.message_str = content abm.sender = MessageMember( user_id=str(message.author.id), nickname=message.author.display_name ) - message_chain = [] if abm.message_str: message_chain.append(Plain(text=abm.message_str)) - if message.attachments: for attachment in message.attachments: if attachment.content_type and attachment.content_type.startswith( @@ -210,7 +209,6 @@ class DiscordPlatformAdapter(Platform): message_chain.append( File(name=attachment.filename, url=attachment.url) ) - abm.message = message_chain abm.raw_message = message abm.self_id = self.client_self_id @@ -237,13 +235,25 @@ class DiscordPlatformAdapter(Platform): # 检查是否为斜杠指令 is_slash_command = message_event.interaction_followup_webhook is not None - # 检查是否被@ - is_mention = ( - self.client - and self.client.user - and hasattr(message.raw_message, "mentions") - and self.client.user in message.raw_message.mentions - ) + # 检查是否被@(User Mention 或 Bot 拥有的 Role Mention) + is_mention = False + # User Mention + if self.client and self.client.user and hasattr(message.raw_message, "mentions"): + if self.client.user in message.raw_message.mentions: + is_mention = True + # Role Mention(Bot 拥有的角色被提及) + if not is_mention and hasattr(message.raw_message, "role_mentions"): + bot_member = None + if hasattr(message.raw_message, "guild") and message.raw_message.guild: + try: + bot_member = message.raw_message.guild.get_member(self.client.user.id) + except Exception: + bot_member = None + if bot_member and hasattr(bot_member, "roles"): + bot_roles = set(bot_member.roles) + mentioned_roles = set(message.raw_message.role_mentions) + if bot_roles and mentioned_roles and bot_roles.intersection(mentioned_roles): + is_mention = True # 如果是斜杠指令或被@的消息,设置为唤醒状态 if is_slash_command or is_mention: @@ -252,6 +262,7 @@ class DiscordPlatformAdapter(Platform): self.commit_event(message_event) + @override async def terminate(self): """终止适配器""" From cebcd6925a47e754dda7d027a1e22672bf3c23a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9B=9E=E5=BD=92=E5=A4=A9=E7=A9=BA?= Date: Wed, 25 Jun 2025 11:46:49 +0800 Subject: [PATCH 4/7] =?UTF-8?q?[fix]=20(discord=5Fplatform=5Fadapter)=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E4=BA=86=20=E2=80=9CDiscord=20=E5=B9=B3?= =?UTF-8?q?=E5=8F=B0=E6=97=A0=E6=B3=95=E4=BC=98=E9=9B=85=E9=87=8D=E8=BD=BD?= =?UTF-8?q?=E2=80=9D=20=E7=9A=84=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### 问题现象(AI总结) - 在通过 Web 面板或配置变更热重载 Discord 平台时,适配器的 terminate() 方法会被调用,但经常出现“卡死”或长时间无响应,导致 Discord 平台无法优雅重载。 - 日志显示停留在“正在清理已注册的斜杠指令...”等步骤,甚至出现超时或异常。 #### 2. 原因分析 - 适配器的 terminate() 方法中,涉及多个异步操作(如取消 polling 任务、清理斜杠指令、关闭客户端)。 - 某些 await 操作(如 await self.client.sync_commands() 或 await self.client.close())在网络异常、事件循环被取消等情况下,可能会阻塞或抛出 CancelledError,导致整个重载流程卡住。 - 之前的实现没有对这些 await 操作加超时保护,也没有分步日志,难以定位具体卡点。 #### 3. 修复措施 - 分步日志:在 terminate() 的每个关键步骤前后都加了详细日志,便于定位卡点。 - 超时保护:对所有关键 await 操作(如 polling 任务取消、指令清理、客户端关闭)都加了 asyncio.wait_for(..., timeout=10),防止无限阻塞。 - 健壮性提升:先 cancel polling 任务,再清理指令,最后关闭客户端。每一步都捕获异常并输出日志,保证即使某一步失败也能继续后续清理。 - 避免重复终止:移除了 run() 方法中的 finally: await self.terminate(),只允许外部统一调度,防止重复调用导致资源冲突或日志重复。 #### 4. 修复效果 - 现在 Discord 平台适配器在热重载或终止时,能优雅地依次完成所有清理步骤,不会因某一步阻塞导致整个流程卡死。 --- .../discord/discord_platform_adapter.py | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/astrbot/core/platform/sources/discord/discord_platform_adapter.py b/astrbot/core/platform/sources/discord/discord_platform_adapter.py index d605ee621..2ba833d65 100644 --- a/astrbot/core/platform/sources/discord/discord_platform_adapter.py +++ b/astrbot/core/platform/sources/discord/discord_platform_adapter.py @@ -46,6 +46,8 @@ class DiscordPlatformAdapter(Platform): self.enable_command_register = self.config.get("discord_command_register", True) self.guild_id = self.config.get("discord_guild_id_for_debug", None) self.activity_name = self.config.get("discord_activity_name", None) + self.shutdown_event = asyncio.Event() + self._polling_task = None @override async def send_by_session( @@ -106,7 +108,6 @@ class DiscordPlatformAdapter(Platform): @override async def run(self): """主要运行逻辑""" - # 初始化回调函数 async def on_received(message_data): logger.debug(f"[Discord] 收到消息: {message_data}") @@ -137,13 +138,15 @@ class DiscordPlatformAdapter(Platform): self.client.on_ready_once_callback = callback try: - await self.client.start_polling() + self._polling_task = asyncio.create_task(self.client.start_polling()) + await self.shutdown_event.wait() except discord.errors.LoginFailure: logger.error("[Discord] 登录失败。请检查你的 Bot Token 是否正确。") except discord.errors.ConnectionClosed: logger.warning("[Discord] 与 Discord 的连接已关闭。") except Exception as e: logger.error(f"[Discord] 适配器运行时发生意外错误: {e}", exc_info=True) + # finally: 不再自动调用 self.terminate(),只允许外部统一调度 def _get_message_type( self, channel: Messageable, guild_id: int | None = None @@ -166,7 +169,6 @@ class DiscordPlatformAdapter(Platform): content = message.content - # 如果机器人被@,移除@部分 # 剥离 User Mention (<@id>, <@!id>) if self.client and self.client.user: @@ -262,27 +264,39 @@ class DiscordPlatformAdapter(Platform): self.commit_event(message_event) - @override async def terminate(self): """终止适配器""" - logger.info("[Discord] 正在终止适配器...") - + logger.info("[Discord] 正在终止适配器... (step 1: cancel polling task)") + self.shutdown_event.set() + # 优先 cancel polling_task + if self._polling_task: + self._polling_task.cancel() + try: + await asyncio.wait_for(self._polling_task, timeout=10) + except asyncio.CancelledError: + logger.info("[Discord] polling_task 已取消。") + except Exception as e: + logger.warning(f"[Discord] polling_task 取消异常: {e}") + logger.info("[Discord] 正在清理已注册的斜杠指令... (step 2)") # 清理指令 if self.enable_command_register and self.client: - logger.info("[Discord] 正在清理已注册的斜杠指令...") try: - # 传入空的列表来清除所有全局指令 - # 如果指定了 guild_id,则只清除该服务器的指令 - await self.client.sync_commands( - commands=[], guild_ids=[self.guild_id] if self.guild_id else None + await asyncio.wait_for( + self.client.sync_commands( + commands=[], guild_ids=[self.guild_id] if self.guild_id else None + ), + timeout=10 ) logger.info("[Discord] 指令清理完成。") except Exception as e: logger.error(f"[Discord] 清理指令时发生错误: {e}", exc_info=True) - + logger.info("[Discord] 正在关闭 Discord 客户端... (step 3)") if self.client and hasattr(self.client, "close"): - await self.client.close() + try: + await asyncio.wait_for(self.client.close(), timeout=10) + except Exception as e: + logger.warning(f"[Discord] 客户端关闭异常: {e}") logger.info("[Discord] 适配器已终止。") def register_handler(self, handler_info): From 62d8cf79ef0a6e68cf62f0aa90c5b178f93b370f Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Fri, 27 Jun 2025 14:31:35 +0800 Subject: [PATCH 5/7] fix: remove deprecated pre_send and post_send calls for specific platforms --- astrbot/core/pipeline/respond/stage.py | 20 ++++++++----------- .../core/pipeline/result_decorate/stage.py | 6 +++++- astrbot/core/pipeline/waking_check/stage.py | 2 -- astrbot/core/platform/astr_message_event.py | 4 ++-- .../qqofficial/qqofficial_message_event.py | 6 ++---- 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/astrbot/core/pipeline/respond/stage.py b/astrbot/core/pipeline/respond/stage.py index ad0a62c8b..794095268 100644 --- a/astrbot/core/pipeline/respond/stage.py +++ b/astrbot/core/pipeline/respond/stage.py @@ -128,9 +128,7 @@ class RespondStage(Stage): "streaming_segmented", False ) logger.info(f"应用流式输出({event.get_platform_name()})") - await event._pre_send() await event.send_streaming(result.async_stream, use_fallback) - await event._post_send() return elif len(result.chain) > 0: # 检查路径映射 @@ -141,8 +139,6 @@ class RespondStage(Stage): component.file = path_Mapping(mappings, component.file) event.get_result().chain[idx] = component - await event._pre_send() - # 检查消息链是否为空 try: if await self._is_empty_message_chain(result.chain): @@ -158,9 +154,14 @@ class RespondStage(Stage): c for c in result.chain if not isinstance(c, Comp.Record) ] - if self.enable_seg and ( - (self.only_llm_result and result.is_llm_result()) - or not self.only_llm_result + if ( + self.enable_seg + and ( + (self.only_llm_result and result.is_llm_result()) + or not self.only_llm_result + ) + and event.get_platform_name() + not in ["qq_official", "weixin_official_account", "dingtalk"] ): decorated_comps = [] if self.reply_with_mention: @@ -207,14 +208,9 @@ class RespondStage(Stage): logger.error(traceback.format_exc()) logger.error(f"发送消息失败: {e} chain: {result.chain}") - await event._post_send() logger.info( f"AstrBot -> {event.get_sender_name()}/{event.get_sender_id()}: {event._outline_chain(result.chain)}" ) - else: - # 对使用 qq_official 适配器的会话控制器发送消息的特殊处理 - if event.get_platform_name() == "qq_official": - await event._post_send() handlers = star_handlers_registry.get_handlers_by_event_type( EventType.OnAfterMessageSentEvent, platform_id=event.get_platform_id() diff --git a/astrbot/core/pipeline/result_decorate/stage.py b/astrbot/core/pipeline/result_decorate/stage.py index 7a12788a0..23a9bed4b 100644 --- a/astrbot/core/pipeline/result_decorate/stage.py +++ b/astrbot/core/pipeline/result_decorate/stage.py @@ -141,7 +141,11 @@ class ResultDecorateStage(Stage): break # 分段回复 - if self.enable_segmented_reply: + if self.enable_segmented_reply and event.get_platform_name() not in [ + "qq_official", + "weixin_official_account", + "dingtalk", + ]: if ( self.only_llm_result and result.is_llm_result() ) or not self.only_llm_result: diff --git a/astrbot/core/pipeline/waking_check/stage.py b/astrbot/core/pipeline/waking_check/stage.py index e654d07ce..14a9423fb 100644 --- a/astrbot/core/pipeline/waking_check/stage.py +++ b/astrbot/core/pipeline/waking_check/stage.py @@ -125,7 +125,6 @@ class WakingCheckStage(Stage): f"插件 {star_map[handler.handler_module_path].name}: {e}" ) ) - await event._post_send() event.stop_event() passed = False break @@ -140,7 +139,6 @@ class WakingCheckStage(Stage): f"您(ID: {event.get_sender_id()})的权限不足以使用此指令。通过 /sid 获取 ID 并请管理员添加。" ) ) - await event._post_send() logger.info( f"触发 {star_map[handler.handler_module_path].name} 时, 用户(ID={event.get_sender_id()}) 权限不足。" ) diff --git a/astrbot/core/platform/astr_message_event.py b/astrbot/core/platform/astr_message_event.py index 40aab6443..7a3102de5 100644 --- a/astrbot/core/platform/astr_message_event.py +++ b/astrbot/core/platform/astr_message_event.py @@ -235,10 +235,10 @@ class AstrMessageEvent(abc.ABC): self._has_send_oper = True async def _pre_send(self): - """调度器会在执行 send() 前调用该方法""" + """调度器会在执行 send() 前调用该方法 deprecated in v3.5.18""" async def _post_send(self): - """调度器会在执行 send() 后调用该方法""" + """调度器会在执行 send() 后调用该方法 deprecated in v3.5.18""" def set_result(self, result: Union[MessageEventResult, str]): """设置消息事件的结果。 diff --git a/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py b/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py index d55c2671b..9bb68a040 100644 --- a/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py +++ b/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py @@ -28,10 +28,8 @@ class QQOfficialMessageEvent(AstrMessageEvent): self.send_buffer = None async def send(self, message: MessageChain): - if not self.send_buffer: - self.send_buffer = message - else: - self.send_buffer.chain.extend(message.chain) + self.send_buffer = message + await self._post_send() async def send_streaming(self, generator, use_fallback: bool = False): """流式输出仅支持消息列表私聊""" From 8c7cf51958ebd8ef2f31bdf1da0e418c6d3be090 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Fri, 27 Jun 2025 14:46:23 +0800 Subject: [PATCH 6/7] chore: code format --- .../discord/discord_platform_adapter.py | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/astrbot/core/platform/sources/discord/discord_platform_adapter.py b/astrbot/core/platform/sources/discord/discord_platform_adapter.py index 2ba833d65..ab7c95b31 100644 --- a/astrbot/core/platform/sources/discord/discord_platform_adapter.py +++ b/astrbot/core/platform/sources/discord/discord_platform_adapter.py @@ -108,6 +108,7 @@ class DiscordPlatformAdapter(Platform): @override async def run(self): """主要运行逻辑""" + # 初始化回调函数 async def on_received(message_data): logger.debug(f"[Discord] 收到消息: {message_data}") @@ -165,7 +166,6 @@ class DiscordPlatformAdapter(Platform): def _convert_message_to_abm(self, data: dict) -> AstrBotMessage: """将普通消息转换为 AstrBotMessage""" message: discord.Message = data["message"] - is_mentioned = data.get("is_mentioned", False) content = message.content @@ -175,18 +175,26 @@ class DiscordPlatformAdapter(Platform): mention_str = f"<@{self.client.user.id}>" mention_str_nickname = f"<@!{self.client.user.id}>" if content.startswith(mention_str): - content = content[len(mention_str):].lstrip() + content = content[len(mention_str) :].lstrip() elif content.startswith(mention_str_nickname): - content = content[len(mention_str_nickname):].lstrip() + content = content[len(mention_str_nickname) :].lstrip() # 剥离 Role Mention(bot 拥有的任一角色被提及,<@&role_id>) - if hasattr(message, "role_mentions") and hasattr(message, "guild") and message.guild: - bot_member = message.guild.get_member(self.client.user.id) if self.client and self.client.user else None + if ( + hasattr(message, "role_mentions") + and hasattr(message, "guild") + and message.guild + ): + bot_member = ( + message.guild.get_member(self.client.user.id) + if self.client and self.client.user + else None + ) if bot_member and hasattr(bot_member, "roles"): for role in bot_member.roles: role_mention_str = f"<@&{role.id}>" if content.startswith(role_mention_str): - content = content[len(role_mention_str):].lstrip() + content = content[len(role_mention_str) :].lstrip() break # 只剥离第一个匹配的角色 mention abm = AstrBotMessage() @@ -240,7 +248,11 @@ class DiscordPlatformAdapter(Platform): # 检查是否被@(User Mention 或 Bot 拥有的 Role Mention) is_mention = False # User Mention - if self.client and self.client.user and hasattr(message.raw_message, "mentions"): + if ( + self.client + and self.client.user + and hasattr(message.raw_message, "mentions") + ): if self.client.user in message.raw_message.mentions: is_mention = True # Role Mention(Bot 拥有的角色被提及) @@ -248,13 +260,19 @@ class DiscordPlatformAdapter(Platform): bot_member = None if hasattr(message.raw_message, "guild") and message.raw_message.guild: try: - bot_member = message.raw_message.guild.get_member(self.client.user.id) + bot_member = message.raw_message.guild.get_member( + self.client.user.id + ) except Exception: bot_member = None if bot_member and hasattr(bot_member, "roles"): bot_roles = set(bot_member.roles) mentioned_roles = set(message.raw_message.role_mentions) - if bot_roles and mentioned_roles and bot_roles.intersection(mentioned_roles): + if ( + bot_roles + and mentioned_roles + and bot_roles.intersection(mentioned_roles) + ): is_mention = True # 如果是斜杠指令或被@的消息,设置为唤醒状态 @@ -284,9 +302,10 @@ class DiscordPlatformAdapter(Platform): try: await asyncio.wait_for( self.client.sync_commands( - commands=[], guild_ids=[self.guild_id] if self.guild_id else None + commands=[], + guild_ids=[self.guild_id] if self.guild_id else None, ), - timeout=10 + timeout=10, ) logger.info("[Discord] 指令清理完成。") except Exception as e: From cb04dd2b83a500b78bcd3deca6337abcdc3d2f83 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Fri, 27 Jun 2025 14:59:08 +0800 Subject: [PATCH 7/7] chore: remove unnecessary codes --- astrbot/core/config/default.py | 6 +----- .../platform/sources/discord/discord_platform_adapter.py | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/astrbot/core/config/default.py b/astrbot/core/config/default.py index b2ce1bfe0..ea93c75ef 100644 --- a/astrbot/core/config/default.py +++ b/astrbot/core/config/default.py @@ -12,7 +12,7 @@ DB_PATH = os.path.join(get_astrbot_data_path(), "data_v3.db") DEFAULT_CONFIG = { "config_version": 2, "platform_settings": { - "plugin_enable":[], + "plugin_enable": [], "unique_session": False, "rate_limit": { "time": 60, @@ -388,10 +388,6 @@ CONFIG_METADATA_2 = { "type": "string", "hint": "可选的 Discord 活动名称。留空则不设置活动。", }, - "discord_guild_id_for_debug": { - "description": "【开发用】指定一个服务器(Guild)ID。在此服务器注册的指令会立刻生效,便于调试。留空则注册为全局指令。", - "type": "string", - }, }, }, "platform_settings": { diff --git a/astrbot/core/platform/sources/discord/discord_platform_adapter.py b/astrbot/core/platform/sources/discord/discord_platform_adapter.py index ab7c95b31..6764eda61 100644 --- a/astrbot/core/platform/sources/discord/discord_platform_adapter.py +++ b/astrbot/core/platform/sources/discord/discord_platform_adapter.py @@ -147,7 +147,6 @@ class DiscordPlatformAdapter(Platform): logger.warning("[Discord] 与 Discord 的连接已关闭。") except Exception as e: logger.error(f"[Discord] 适配器运行时发生意外错误: {e}", exc_info=True) - # finally: 不再自动调用 self.terminate(),只允许外部统一调度 def _get_message_type( self, channel: Messageable, guild_id: int | None = None