Skip to content

feat: resolve @mentions in direct reply to Feishu at tags - #155

Merged
lishuceo merged 2 commits into
mainfrom
feat/resolve-mentions-in-direct-reply
Mar 17, 2026
Merged

feat: resolve @mentions in direct reply to Feishu at tags#155
lishuceo merged 2 commits into
mainfrom
feat/resolve-mentions-in-direct-reply

Conversation

@lishuceo

Copy link
Copy Markdown
Owner

Summary

  • 新增 mention-resolver.ts:解析 bot 输出文本中的 @姓名,通过群成员列表匹配 open_id,转换为飞书 post 格式的结构化 <at> 标签
  • client.ts 新增 replyPost() / replyPostInThread() 方法
  • 修改 sendDirectReply() 短文本分支:检测到 @mention 时用 post 格式发送,无匹配时 fallback 纯文本
  • 按姓名长度降序贪婪匹配,避免 @张三丰@张三 先截断
  • 任何环节失败(API 调不通、名字不匹配)均 fallback 到原有纯文本逻辑,不会 regression

Test plan

  • 11 个单元测试覆盖 convertTextWithMentions 纯函数
  • 完整回归测试 1074/1075 通过(唯一失败为已有 flaky test memory/quality

🤖 Generated with Claude Code

lishuceo and others added 2 commits March 17, 2026 19:56
When bot output contains @username that matches a chat member,
convert plain text to Feishu post format with structured at elements,
so mentions render as blue links with notifications instead of plain text.

Falls back to plain text when no mentions found or API fails.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
11 test cases covering: single/multiple mentions, greedy name matching,
multi-line text, empty map, no-match fallback, and edge cases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude

claude Bot commented Mar 17, 2026

Copy link
Copy Markdown

Claude finished @lishuceo's task in 1m 21s —— View job


Code Review: PR #155 — Resolve @mentions in direct reply

  • Check for previous review comments
  • Read and review all changed files
  • Post review findings

✅ Approved — Clean, well-structured PR

Overall assessment: This is a solid implementation. The code follows existing patterns in the codebase, has proper error handling with graceful fallback to plain text at every failure point, and ships with good test coverage (11 unit tests on the pure function).

What works well:

  • Greedy longest-match-first strategy via name length sorting prevents @张三 from eating @张三丰
  • convertTextWithMentions is a pure function, cleanly separated from the async resolveMentions wrapper — easy to test
  • replyPost() / replyPostInThread() follow the exact same pattern as existing client methods
  • Regex special characters in names are properly escaped (line 61 of mention-resolver.ts)
  • Every failure path (API errors, no matches, empty member list) falls back to the original plain text behavior — zero regression risk

Minor observations (not blocking):

  • getChatMembers() paginates through all group members on every @-containing reply. For large groups this adds latency. A short-lived cache (e.g., 60s TTL per chatId) could help if this becomes a bottleneck in practice — but fine to defer.
  • Test case on line 88-96 (mention-resolver.test.ts) documents that @张三丰 with only 张三 in the map will partially match, leaving as trailing text. The comment acknowledges this as acceptable, which is fair — in practice both names would be in the member list.

No issues with confidence ≥ 75 found. LGTM.

@lishuceo
lishuceo merged commit 0ba9881 into main Mar 17, 2026
4 checks passed
lishuceo added a commit that referenced this pull request Apr 8, 2026
* feat: resolve @mentions in direct reply to proper Feishu at tags

When bot output contains @username that matches a chat member,
convert plain text to Feishu post format with structured at elements,
so mentions render as blue links with notifications instead of plain text.

Falls back to plain text when no mentions found or API fails.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: add unit tests for mention-resolver

11 test cases covering: single/multiple mentions, greedy name matching,
multi-line text, empty map, no-match fallback, and edge cases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant