-
-
Notifications
You must be signed in to change notification settings - Fork 678
fix: qq_official适配器使用SessionController(会话控制)功能时机器人回复消息无法发送到聊天平台 #1709
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
fix: qq_official适配器使用SessionController(会话控制)功能时机器人回复消息无法发送到聊天平台 #1709
Conversation
审查者指南确保通过 SessionController 使用 QQ Official 适配器发送的消息能够实际到达聊天平台,方法是在 respond 阶段调用适配器的 post-send hook。 序列图:修复 QQ Official 适配器在 Respond 阶段的消息发送问题sequenceDiagram
actor User
participant Plugin_SessionController as PluginSC
participant QQOfficialMessageEvent as Event
participant RespondStage
participant QQChatPlatform
User->>PluginSC: 发送命令 (例如,/test)
PluginSC->>Event: event.send(message_result)
Note over PluginSC, Event: 使用 SessionController 的插件尝试发送回复
%% 消息处理管道继续到 RespondStage %%
RespondStage->>RespondStage: process(event, result)
alt If (result 为 null OR result.action != Action.POST_SEND)
RespondStage->>Event: get_platform_name()
Event-->>RespondStage: "qq_official"
opt if platform_name == "qq_official"
Note over RespondStage: 针对使用 SessionController 的 qq_official 适配器的特殊处理
RespondStage->>Event: _post_send()
activate Event
Event->>QQChatPlatform: 传输消息内容
QQChatPlatform-->>Event: Ack (消息已发送)
deactivate Event
end
else result.action == Action.POST_SEND
RespondStage->>RespondStage: 记录消息已处理并发送
end
类图:QQOfficialMessageEvent 的相关方面classDiagram
class QQOfficialMessageEvent {
+get_platform_name() String
+send(message_result) await
#_post_send() await
}
note "PR 描述和 Sourcery 摘要表明 QQOfficialMessageEvent.send() 已被修改为调用 _post_send()。_post_send() 方法也由 RespondStage 中的新逻辑直接调用(来自 diff)。"
文件级别变更
提示和命令与 Sourcery 互动
自定义您的体验访问您的 dashboard 以:
获取帮助
Original review guide in EnglishReviewer's GuideEnsure that messages sent via SessionController using the QQ Official adapter actually reach the chat platform by invoking the adapter’s post-send hook in the respond stage. Sequence Diagram: Message Sending Fix in Respond Stage for QQ Official AdaptersequenceDiagram
actor User
participant Plugin_SessionController as PluginSC
participant QQOfficialMessageEvent as Event
participant RespondStage
participant QQChatPlatform
User->>PluginSC: Sends command (e.g., /test)
PluginSC->>Event: event.send(message_result)
Note over PluginSC, Event: Plugin using SessionController attempts to send reply
%% Message processing pipeline continues to RespondStage %%
RespondStage->>RespondStage: process(event, result)
alt If (result is null OR result.action != Action.POST_SEND)
RespondStage->>Event: get_platform_name()
Event-->>RespondStage: "qq_official"
opt if platform_name == "qq_official"
Note over RespondStage: Special handling for qq_official adapter with SessionController
RespondStage->>Event: _post_send()
activate Event
Event->>QQChatPlatform: Transmit message content
QQChatPlatform-->>Event: Ack (Message Sent)
deactivate Event
end
else result.action == Action.POST_SEND
RespondStage->>RespondStage: Log message already processed for sending
end
Class Diagram: Relevant Aspects of QQOfficialMessageEventclassDiagram
class QQOfficialMessageEvent {
+get_platform_name() String
+send(message_result) await
#_post_send() await
}
note "The PR description and Sourcery summary suggest QQOfficialMessageEvent.send() was modified to call _post_send(). The _post_send() method is also directly called by the new logic in RespondStage (from diff)."
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
嘿 @shuiping233 - 我已经查看了你的更改,它们看起来很棒!
以下是我在审查期间查看的内容
- 🟢 通用问题:一切看起来都不错
- 🟢 安全性:一切看起来都不错
- 🟢 测试:一切看起来都不错
- 🟢 复杂性:一切看起来都不错
- 🟢 文档:一切看起来都不错
帮助我变得更有用!请点击每个评论上的👍或👎,我将使用反馈来改进你的评论。
Original comment in English
Hey @shuiping233 - I've reviewed your changes and they look great!
Here's what I looked at during the review
- 🟢 General issues: all looks good
- 🟢 Security: all looks good
- 🟢 Testing: all looks good
- 🟢 Complexity: all looks good
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
这个其实会影响到分段回复,_post_send 包括 _pre_send 的引入是处理分段回复时对 QQ 官方机器人接口的 workaround(只支持一问一答),具体可以参考:https://vscode.dev/github/Soulter/AstrBot/blob/master/astrbot/core/pipeline/respond/stage.py#L123-L212 我觉得一个可行的解决方案是直接抛弃掉 _pre_send() -> send(), _post_send() 这个模式,然后对 QQ 官方机器人接口的特殊处理:直接在 |
我对Astrbot的内部结构了解的还不深入,所以我这个pr也是“见招拆招”的处理,我可能暂时没法提供其他建议了,不过我还是愿意提交代码pr来帮助解决这个问题的,只是我需要知道大概要做什么,能否在详细讲讲我这边具体能帮忙实现内容什么呢(也就是后续我要做什么事情) |
感谢!现在 AstrMessageEvent 中实现了这两个方法:
其实都只是针对 QQ 官方机器人接口只能一问一答的临时解决方案。具体的逻辑就在 https://vscode.dev/github/Soulter/AstrBot/blob/master/astrbot/core/pipeline/respond/stage.py#L123-L212 这里,然后 astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py 中的 send() 方法会将消息段全部append到一个buffer中,在 post_send 的时候一次性发送出去。然后为了解决这个 PR 遇到的问题,我觉得可以对 qqofficial_message_event 单独处理,在 astrbot/core/pipeline/respond/stage.py 这个文件这里的分段回复逻辑的地方,对 qqofficial 单独进行处理,也就是不分段回复了 |
好的,我这周末会花点时间研究一下再写写看的 |
d7d64c1
to
eb62128
Compare
cdda797
to
1ce95c4
Compare
@@ -211,6 +211,10 @@ async def process( | |||
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": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
想了想core目录的代码不应该依赖外层api级别的类,所以我就没用from astrbot.api.event import filter
filter.PlatformAdapterType
来判断平台类型
会话控制器处理发往qq_official适配器消息的时候才会进入这个这个else
,因为文档里会话控制器发送消息的示例代码写法是await event.send(message_result)
,执行完会话控制器的handler之后不会再进一步处理event了,也就是没有执行event.set_result()
,所以event._result.chain
是空列表,而process
方法并没有处理len(result.chain) > 0
之外的情况,没有调用event._post_event()
,导致了消息发不出去
@sourcery-ai review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
嘿 @shuiping233 - 我已经查看了你的更改,它们看起来很棒!
以下是我在审查期间查看的内容
- 🟢 一般问题:一切看起来都不错
- 🟢 安全性:一切看起来都不错
- 🟢 测试:一切看起来都不错
- 🟢 复杂性:一切看起来都不错
- 🟢 文档:一切看起来都不错
帮助我更有用!请点击每个评论上的👍或👎,我将使用反馈来改进您的评论。
Original comment in English
Hey @shuiping233 - I've reviewed your changes and they look great!
Here's what I looked at during the review
- 🟢 General issues: all looks good
- 🟢 Security: all looks good
- 🟢 Testing: all looks good
- 🟢 Complexity: all looks good
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
这个问题类似 #807
Motivation
如题,使用会话控制时,参照AstrBot文档-会话控制的描述,会话控制器内机器人发送消息是调用
await event.send(message_result)
方法的,但是实际qqofficial_message_event里的send方法缺少了_post_send
的调用,所以消息发不出去实例代码
Modifications
修改了 qqofficial_message_event.QQOfficialMessageEvent的send方法,使其能调用self._post_send方法,能将消息发送至聊天平台
Check
我的commit message写的可能有亿点点随意了(
requirements.txt
和pyproject.toml
文件相应位置。好的,这是翻译成中文的 pull request 摘要:
Sourcery 总结
Bug 修复:
Original summary in English
好的,这是将 pull request 总结翻译成中文的结果:
Sourcery 总结
Bug 修复:
Original summary in English
Summary by Sourcery
Bug Fixes: