Skip to content

远程聊天列表里同一个群重复显示很多行(同名多条,疑似按成员发布/ handle 未归一) #2797

Closed

Description

@Birfy

Written-by: Chief

用户 2026-11-10 16:47(上海)/ 08:47Z 报:同一个群聊在列表里重复显示很多遍,附截图(16:47 那张)。

截图里的现象:

  • 一列里连续 8 行以上同名条目,标题都是 123456 · 刘红升 2, flybot682b8a43, FlyBot,每行右侧都带同一个"远程/链接"标记,头像都是 Bot 头像;
  • 同一张截图最下面一行是 zhangyi 的 bot (flybot98b…),带地球图标 —— 说明这个列表是 FlyBot 侧的远程聊天(Bot Social / 好友 Bot)列表,不是飞书客户端自己的会话列表;
  • 用户的原话是"这个群聊重复显示很多遍",即他认为这是同一个群,被列了多行。

代码线索(main 2cd5c298 读)

  • core/src/host/remote-chat.js:一个远程聊天 = 一个带 remote.handle 的 Bot 记录;open({handle,name,…}) 先用 chatOfHandle(handle)(normRemoteHandle 归一化后比较)查重,命中就复用,所以同名不同 handle 就会变成多行。
  • open() 里还有一条:isHomeLevelRemote({ handle, home }) 为真时直接返回 undefined(不建档)。
  • sync() 按发布方给的 members 逐条 open({...member, plugin}),handles.add(normRemoteHandle(member.handle))。
  • 显示名来自发布方的 name,不是由 handle 推出来的。

最像的一条:发布方按"房间成员"逐个发布 —— 每个成员一个 handle,但 name 都用同一个房间标题,于是同一个房间在列表里出现 N 行。次要可能:handle 里混进了成员 id / 时间戳,normRemoteHandle 归一化后仍然各不相同;或 open() 并发时两次都没查到 existing,建了两条。

要做

  1. 先复现:在 core/test/remote-chat.test.js(或新文件)里用现有注入面模拟"同一房间连续/并发发布两次"和"同一房间按成员发布"两种情形,写出一条当前会红的断言:同一房间在 list() 里只能有一行。
  2. 修在源头优先:列表层(不是显示层)保证「同一房间一行」——要么 open() 的键包含房间而不是成员,要么 sync() 以房间去重;不要靠 UI 折叠重复行掩盖。
  3. 不要顺手改 Bot Social 的发布协议;只在 FlyBot 侧收敛。行为变更必须带测试,红先证据写进 PR 正文。

需要用户补的(有就更快,不阻塞开工)

  • 点其中两行进去,是不是同一个群/同一个会话?
  • 那 8 行是一直都在,还是每发一条消息就多一行?

Activity

  1. added
    bugSomething isn't working
    needs-infoWaiting for the reporter or a maintainer decision
    area:socialFriends, invites, grants, Bot Social
    on Nov 10, 2026
  2. Birfy commented on Nov 10, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: FlyBot 实现线

    根因(main 5b8d980 读的代码,PR #2801 已开):

    • core/src/host/remote-chat.js 里一个远程聊天是按 handle 查重的(chatOfHandle → normRemoteHandle 归一化后比较),所以同一个人/同一个房间换一个 handle 发布就会多一条聊天记录,而显示名来自发布方的 name,不从 handle 推导。
    • 发布方按「房间的每个成员」逐条发布:每条记录 name 都是同一个房间标题,home 也相同(mapRemoteBot 把 home 固定成所属 home 条目的 handle),只有成员 handle 不同。所以同一个群在列表里就是 N 行、每行同名 —— 和你截图里的 123456 · 刘红升 2, flybot682b8a43, FlyBot 连 8 行完全对得上;这些行不是 UI 重复渲染,而是真的存了 N 条远程聊天记录。
    • 次要路径同样会累积:如果房间这次用成员 A 的 handle 发布、下次换成成员 B,sync() 找不到旧 handle 就把旧记录标成 gone 留在列表里,于是旧行 + 新行并存。

    修法(列表层/源头,不在 UI 折叠):

    • 去重键从「成员 handle」改成「房间」=同一个 home 上的同一个发布名。open() 先按 handle 找,找不到就复用持有该房间的聊天;sync() 每个房间只开一次,并且只要该房间还有任一成员在发布列表里就不标 gone。
    • 聊天记录里存的 remote.handle 不重写(聊天自己的模型路由 flybot-remote/<handle> 用它),所以历史、未读、等待回复都留在原来那一行;另一成员发来的消息也落进这一条聊天。
    • 回退对比写在测试里:同一 home 两个不同名字、同一个名字两个 home(两个好友)仍然是两行 —— 房间规则不会把列表折平。
    • 没有动 Bot Social 的发布协议;只改 FlyBot 侧(core/src/host/remote-chat.js),docs/subsystems/core-host.md 同步、changelog.d/2797-remote-room-one-row.fixed.md 一片。

    红先证据(main 5b8d980 的干净解包 + 新测试,实现未改):core/test/remote-chat.test.js 25 例中 3 例红 —— 同房间 4 个成员 → list().length 实际 4(期望 1);成员 handle 变了 → 实际 2 行(期望 1 行且同一个 id);另一成员的消息 → 落进 b2(期望 b1)。修后同文件 25/25 绿。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:socialFriends, invites, grants, Bot SocialbugSomething isn't workingneeds-infoWaiting for the reporter or a maintainer decision

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions