开发复盘:做QQ机器人挖到的两个奇葩Bug,复制全是null?
最近在折腾QQ机器人,特别是想实现那种类似ChatGPT的“流式输出”效果——就是字一个一个往外蹦的那种体验。本来以为只是简单的API调用,结果在最新版手Q(9.3.15.37995)上测试时,直接给我整不会了,一连踩了两个坑。
既然踩了坑,就得复盘一下,顺便给同样在做Bot开发的朋友们提个醒。
Bug 一:复制出来的全是“null”?
现象描述 这个Bug非常魔幻。机器人在私聊里发送流式Markdown消息时,乍一看一切正常:
- 聊天窗口里显示没问题,排版整齐;
- Markdown的加粗、斜体渲染也完全正常;
- 甚至直接在QQ内部把这条消息转发给别人,也没毛病。
但是! 当你长按这条消息,选择“复制文字”,然后去别的地方粘贴时,神奇的事情发生了。
- 原消息:“晚上好呀,雪雪。茶给你温着。”
- 复制结果:“null**”
不仅是文本丢失,还硬生生多出了个“null”。有时候更严重,直接只剩下开头几个字,比如复制“当然可以呀,像这样:这是一段加粗的文字。”,结果剪切板里只有“null当然”。
原因分析与推测 作为一名开发者,看到“null”这个词,脑子里马上就有画面了。这里大概率是手Q客户端在处理富文本消息时,对不同数据字段的引用出了问题。
通常Bot发送的消息结构里,会有用于渲染的Markdown字段,也会有用于复制/检索的纯文本字段。我在排查时发现,流式输出和一次性发送在数据包的处理上可能存在差异。
我的推测是:
- 字段缺失:在流式发送过程中,用于“复制文本”的备用字段可能根本没有赋值,或者被赋值为“null”。
- 渲染层与数据层脱节:显示层读取了正确的Markdown数据进行渲染,但复制功能直接去读了那个为空的字段,导致用户拿到的是“null”。
- 流式切片问题:也可能是流式传输时的切片只保留了最后一部分数据,导致复制时只读取到了残缺的片段。
目前的解决思路 既然鹅厂的客服邮件暂时没回(懂得都懂),我们自己只能迂回解决。目前想到的方案是在Bot端发送消息时,强制构建完整的纯文本结构体,或者尝试在消息末尾追加一个不可见的特殊字符,强制客户端刷新缓存。如果你有更好的方案,欢迎在评论区交流。
Bug 二:转发消息“时光倒流”了?
如果说第一个Bug还能勉强解释是数据处理失误,那这个就纯属是逻辑层面的“灵异事件”了。
现象描述 我在群里吐槽上面那个复制Bug的时候,一连发了三条消息,顺序是 1、2、3。
结果当我选中这三条消息,一起转发到隔壁大群时,顺序竟然变成了:3、2、1。
这真的很让人头大。消息转发这种高频功能,按理说时间戳和ID的排序逻辑应该是健壮的,结果它给我来了个“后进先出”(LIFO)?
原因分析 这大概率是客户端在处理“多选合并转发”时的渲染逻辑错误。可能在生成转发消息卡片时,遍历消息数组的顺序写反了,或者是根据某种倒序索引去组装的数据包。
这也提醒我们,如果是依赖消息顺序来执行任务的Bot逻辑(比如步骤解析),在目前的版本上可能会出现严重的逻辑错误。
写在最后
这两个Bug虽然看似很小,一个是复制失败,一个是顺序颠倒,但对于做机器人和自动化工具的开发者来说,简直是灾难。特别是那个复制出“null”的问题,直接影响了用户获取信息的效率。
如果你也在调试QQ相关的API,不妨留意一下这两个坑,说不定能帮你节省几个晚上的脱发时间。希望下个版本官方能悄悄修好吧。
如果有鹅厂的大佬路过,求个内推提单通道,这就去提Issue!
评论已关闭