feat(feishu): display group name instead of chat_id in session labels#51032
feat(feishu): display group name instead of chat_id in session labels#51032BunsDev merged 7 commits intoopenclaw:mainfrom
Conversation
Greptile SummaryThis PR resolves human-readable group chat names from the Feishu Key findings:
Confidence Score: 3/5
Prompt To Fix All With AIThis is a comment left during a code review.
Path: extensions/feishu/src/bot.ts
Line: 162-164
Comment:
**TTL-based eviction only runs when cache is at capacity**
`evictGroupNameCache()` (which includes Phase 1 — removing expired entries) is only called when `groupNameCache.size > GROUP_NAME_CACHE_MAX_SIZE`. This means stale entries that have exceeded their 30-minute TTL will remain in memory indefinitely as long as the cache never reaches 500 entries. In a typical single-account deployment with far fewer than 500 group chats, expired entries will never be purged.
This is the opposite of the intended TTL behaviour: the cache will always serve entries within their 30-minute window (since `resolveGroupName` checks `expiresAt` on read), but the underlying `Map` will silently accumulate stale objects forever.
Consider calling `evictGroupNameCache()` unconditionally (or periodically), and only making the Phase 2 eviction conditional on the size check:
```ts
// Always run Phase 1 (TTL cleanup); only gate Phase 2 on size
evictGroupNameCache();
```
Or, alternatively, call Phase 1 unconditionally at the top of `resolveGroupName` and only trigger the full eviction when the cap is exceeded.
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: extensions/feishu/src/bot.ts
Line: 167-168
Comment:
**Missing blank line before `export type FeishuMessageEvent`**
There is no blank line separating the end of `resolveGroupName` from the `FeishuMessageEvent` type declaration, making the module-level code hard to scan visually.
```suggestion
return result;
}
export type FeishuMessageEvent = {
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: extensions/feishu/src/bot.ts
Line: 120-126
Comment:
**No `account.configured` guard before making the API call**
`bot-sender-name.ts` (the pattern this PR is explicitly modelled after) guards its API call with:
```ts
if (!account.configured) {
return {};
}
```
`resolveGroupName` makes no such check. If an unconfigured account somehow reaches this code path (e.g., account added but keys not yet set), `createFeishuClient` may produce a client that issues requests with invalid credentials, causing a noisy `getChatInfo` failure that gets negative-cached for 30 minutes. Adding the guard here keeps the behaviour consistent and avoids an unnecessary API round-trip.
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: extensions/feishu/src/bot.ts
Line: 1002-1005
Comment:
**Double blank line is a minor style nit**
There are two consecutive blank lines between the `resolveGroupName` call block and the `buildCtxPayloadForAgent` comment. A single blank line is the convention in the rest of the file.
```suggestion
}
// --- Shared context builder for dispatch ---
```
How can I resolve this? If you propose a fix, please make it concise.Last reviewed commit: "feat(feishu): displa..." |
ff6206f to
bccb2c9
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bccb2c9238
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
bccb2c9 to
c0983cd
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c0983cdc93
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Resolve human-readable Feishu group names via getChatInfo and display them in the Chat page session dropdown, replacing raw chat_id values. Changes: - Import getChatInfo from chat.ts - Add resolveGroupName() with account-scoped TTL cache (30 min) - Guard with account.configured check (consistent with bot-sender-name.ts) - Two-phase eviction enforcing a hard 500-entry cap - Unconditional Phase 1 (TTL cleanup) on every resolve call - setCacheEntry() with delete-before-set for correct Map insertion order - Negative caching (empty-string sentinel) to avoid API hammering - Set GroupSubject (with fallback to chat_id) in buildCtxPayloadForAgent - Set ConversationLabel only for non-topic group sessions to preserve ThreadLabel disambiguation in group_topic / group_topic_sender flows - 7 unit tests covering success, failure, cache, and isolation paths Closes openclaw#35675
c0983cd to
9ef7c5e
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9ef7c5e6f2
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
Hi @BunsDev — this PR includes a detailed design write-up covering cache strategy, eviction correctness, and multi-account isolation. I've also verified the end-to-end behavior on a live Feishu deployment. Would love your review when you free. Thanks! CI note: The 1 remaining failed checks are pre-existing and unrelated to this PR. |
BunsDev
left a comment
There was a problem hiding this comment.
Approved after maintainer follow-up.
Bug/behavior: Feishu group sessions were showing raw chat IDs in the chat/session label surface instead of a human-readable group name for PR #51032 / issue #35675.
What changed: the PR now resolves Feishu group names through getChatInfo, keeps the lookup account-scoped and cached, preserves topic/thread label priority, and defers the group-name lookup until after the broadcast dedup claim so duplicate account deliveries do not waste Feishu API calls.
Evidence: local pnpm test extensions/feishu/src/bot-group-name.test.ts extensions/feishu/src/bot.broadcast.test.ts passed, local pnpm check:changed passed, all review threads are resolved, and GitHub CI is green on c154dc0a41 with mergeStateStatus: CLEAN.
|
Codex automated review: keeping this open. Current main still uses the raw Feishu Best possible solution: Keep this PR open for maintainer review. The best path is to compare it with #38958, pick the canonical Feishu display-name implementation, remove unrelated root guidance changes, preserve thread-label priority, place group-name lookup after broadcast dedup, and land the focused Feishu code/tests if that remains the chosen approach. What I checked:
Remaining risk / open question:
Codex Review notes: model gpt-5.5, reasoning high; reviewed against d3fd275aa5fc. |
Summary
Resolves #35675 — Auto-populate session label with chat/group name from messaging providers.
When a Feishu group chat sends a message, the Chat page session dropdown currently shows the raw
chat_id(e.g.oc_***). This PR resolves human-readable group names via the existinggetChatInfoAPI and displays them instead.Before → After
GroupSubjectoc_***(raw ID)"Engineering Team"(human-readable, falls back to ID)ConversationLabel"Engineering Team"(set only when name is available)After fixed:

Design
Architecture
Cache Design — Key Decisions
accountId:chatId)senderNameCachepattern inbot-sender-name.ts.Eviction Strategy — Two-Phase with Insertion-Order Awareness
The cache uses JavaScript
Map, which iterates in insertion order. This creates a subtle correctness concern addressed below.Phase 1 — Expire stale entries:
Phase 2 — Evict oldest if still over cap:
Insertion-order correctness (
setCacheEntryhelper):Map.set()on an existing key updates the value but preserves its original insertion position. If a stale entry is refreshed, it remains at the "oldest" position and Phase 2 would immediately evict it — dropping the just-written result.Fix:
setCacheEntry()doesdelete(key)thenset(key, value), which moves the entry to the end of iteration order. The refreshed entry is now treated as newest and survives eviction.Result-before-eviction guarantee:
As an additional safety net,
resolveGroupName()reads the cache result into a local variable before callingevictGroupNameCache(). Even in edge cases, the return value is never lost.Call-Site Placement
resolveGroupName()is called after all group gating checks (permission errors, cooldowns, dedup) but beforebuildCtxPayloadForAgent(). This ensures:Session Label Priority
OpenClaw resolves session labels with this priority:
ConversationLabel>ThreadLabel>SenderName(DM) >GroupSubject(group).This PR sets both:
GroupSubject:groupName || ctx.chatId(always has a value for groups)ConversationLabel:groupNameonly when available (highest priority, shows the friendly name)Files Changed
extensions/feishu/src/bot.tsgetChatInfo; add cache +resolveGroupName(); call beforebuildCtxPayloadForAgent; updateGroupSubject/ConversationLabelextensions/feishu/src/bot-group-name.test.tsTest Coverage
undefined, logs error with account IDundefined{ name: undefined })getChatInforeturns object but name isundefinedchatIdunder different accounts → separate cache entries and API callsRun tests:
Checklist
bot-group-name.test.ts)chat_idon any failureaccountId:chatIdsenderNameCacheinbot-sender-name.ts)