🐛 [Bot] Feishu reactions API rejects Unicode emoji: every status-reaction swap fails with 231001

这个报错通常出现在 LobeChat 的飞书 / Lark 机器人(webhook 或 websocket)处理消息、需要在用户消息上叠加状态表情(👀 → 🤔 → ⚡)时。飞书 reactions API 不接受 Unicode 表情,只接受飞书的 emoji 标识字符串,因此每次 addReact

快速结论:这个报错通常出现在 LobeChat 的飞书 / Lark 机器人(webhook 或 websocket)处理消息、需要在用户消息上叠加状态表情(👀 → 🤔 → ⚡)时。飞书 reactions API 不接受 Unicode 表情,只接受飞书的 emoji 标识字符串,因此每次 addReaction 都会被服务端以 231001 invalid emoji_type 拒绝。优先排查飞书适配器是否把表情做了映射再调用 API。

适用环境:LobeChat canary(latest);客户端类型为服务端 Bot 集成(飞书 / Lark);Issue 未提供 Python、CUDA、PyTorch、显卡、操作系统发行版等具体版本信息。

最快修复方案:在飞书适配器调用 reactions API 之前,把 Pipeline 的状态表情常量映射为飞书的 emoji_type 标识(👀→Get、🤔→THINKING、⚡→OnIt),对没有飞书等价物的表情直接静默跳过。Issue 讨论中给出了该映射与包装 api.addReaction 的具体代码建议,但尚未确认已合并,可优先尝试。

注意事项:映射值取自飞书 protocol spec 的 emoji 表,需以该表为准;即使映射正确,removeReaction 在飞书客户端中本身就是 no-op,表情会叠加而不是替换,这是既有的独立问题,本次修改不会改变该行为;webhook 与 websocket 客户端共用 createMessenger,一处修改可同时覆盖两者,但改完后两类客户端都要实测。

问题场景

在 LobeChat 中配置飞书(Feishu)或 Lark 机器人频道并接入某个 Agent,然后在该飞书会话里给机器人发消息。机器人 Pipeline 会通过在用户消息上切换状态表情来提示进度(👀 已收到 → 🤔 思考中 → ⚡ 执行中)。实际现象是:飞书侧完全看不到这些状态表情,服务端日志里持续出现 reactions API 的 231001 报错。

报错原文

🐛 [Bot] Feishu reactions API rejects Unicode emoji: every status-reaction swap fails with 231001

{ "code": 231001, "msg": "invalid emoji_type" }

原因分析

飞书的 message-reaction API 要求 reaction_type.emoji_type 传入飞书的 emoji 标识字符串(例如 THINKINGOnItGet),而不是 Unicode 表情字符。而飞书平台客户端与 Discord / Telegram 适配器的处理方式一致,把原始 Unicode 表情(👀 / 🤔 / )直接透传给接口,因此每次调用都被判定为 invalid emoji_type

受影响代码位于 apps/server/src/services/bot/platforms/feishu/client.tscreateMessenger().replaceReaction 直接用 Unicode 表情调用 api.addReaction(messageId, nextEmoji)LarkApiClient.addReaction 也原样透传该字符串。此外 service.tsreactToMessage 同样把 params.emoji 未经转换地传给 api.addReaction,需要一并处理。webhook 与 websocket 两个飞书客户端共用 createMessenger,因此同一处映射问题会同时影响两种接入方式。

环境排查

  • 确认 LobeChat 版本,Issue 中报告为 canary(latest)。
  • 确认接入方式:飞书 webhook 还是 websocket,两者共用 createMessenger,需分别验证。
  • 确认问题发生在飞书 / Lark 平台适配器,而非 Discord / Telegram 等其它平台。
  • 确认服务端日志中 231001 报错来自 reactions API,而不是其它飞书接口。
  • 核对 apps/server/src/services/bot/platforms/feishu/client.tsservice.ts 中调用 api.addReaction 的位置,检查传入的是 Unicode 表情还是飞书标识字符串。
  • 对照飞书 protocol spec 中 emoji_type 的合法取值表,确认映射值有效。

解决步骤

  1. 新增一份状态表情到飞书 emoji_type 的映射表,例如放在飞书适配器的 const.ts'👀': 'Get''🤔': 'THINKING''⚡': 'OnIt'。映射值请以飞书 protocol spec 的 emoji 表为准。
  2. createMessenger 中包装 api.addReaction 调用:先用映射函数把 Unicode 表情转成飞书标识,映射不到时(返回 null)直接 Promise.resolve() 静默跳过,不要发起请求。
  3. replaceReaction 中同样先做转换,再决定是否调用 api.addReaction;如果新旧表情相同可直接返回。
  4. service.tsreactToMessage 中应用同一份映射,避免该路径继续把 params.emoji 原样透传。
  5. 修改后分别用 webhook 和 websocket 两种接入方式重新测试,确认两条路径都被覆盖。

验证方法

在飞书会话中再次向机器人发消息,观察用户消息上是否出现 Get(👀)、THINKING(🤔)、OnIt(⚡)对应的状态表情;同时查看服务端日志,确认不再出现 { "code": 231001, "msg": "invalid emoji_type" }。如果表情出现但切换不生效、表现为逐个叠加,这属于 removeReaction 本身就是 no-op 的既有行为,与本修复无关。

参考来源

lobehub/lobe-chat #18551

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 22579

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注