feat(im): add +chat-list and --exclude-muted to filter muted chats#820
feat(im): add +chat-list and --exclude-muted to filter muted chats#820shifengjuan-dev wants to merge 1 commit intolarksuite:mainfrom
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (12)
✅ Files skipped from review due to trivial changes (5)
🚧 Files skipped from review as they are similar to previous changes (7)
📝 WalkthroughWalkthroughThis PR adds a new ChangesIM Mute Filtering and Chat List
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Adds a new im +chat-list shortcut (wraps GET /open-apis/im/v1/chats) and a --exclude-muted flag on both +chat-list and the existing +chat-search to drop chats the current user has muted. Native chat search/list APIs do not return mute status, so the filter is applied client-side after each page: extract chat_ids, call POST /open-apis/im/v1/chat_user_setting/batch_get_mute_status, drop is_muted=true rows. Output adds a "filter" sub-object only when --exclude-muted is set (backward compatible). Pretty output appends a single hint line below the table summary; json keeps it under filter.hint. table/ndjson/csv do not surface it, consistent with the existing pagination hint behavior. Behavior: - Bot identity (--as bot): mute API is UAT-only, so the filter is skipped with filter.skipped=true and skip_reason "bot_identity_no_mute_data". - --search-types public_not_joined alone: all results are non-member public groups; batch call is pre-skipped with skip_reason "all_non_member_search_types". - Empty page: short-circuits to avoid the upstream "chat_ids is empty" InvalidParam, returns counts=0. - Non-member chats (invalid_id_list from default queries containing public_not_joined): silently retained, not counted in filtered_count; surfaced in the hint when filtered_count > 0. - Invariant: fetched_count == returned_count + filtered_count always holds. No top-up loop -- callers continue via page_token if needed. Filter is purely client-side: request body and search_types are unchanged regardless of --exclude-muted. No new scopes required; reuses im:chat:read. Introduces shortcuts/im/mute_filter.go with pure helpers (BuildMuteFilterHint covering all 8 hint states, BuildBatchGetMuteStatusBody, ParseBatchGetMuteStatusResponse, ApplyMuteFilter, ExtractChatIDs, MuteFilterMetaToMap) plus the FetchMuteStatus API wrapper and MaybeApplyMuteFilter orchestrator. ~27 unit tests cover all hint states, orchestrator branches (bot-skip / pre-skip / empty / default), codec round-trip, page-size bounds, and dry-run non-pollution. Change-Id: Ia98980a8dbf8fc34d5614573201fb81eecd60a75 Spec: docs/specs/2026-05-09-im-chats-filter-muted-design.md Plan: docs/specs/2026-05-09-im-chats-filter-muted-plan.md
689ac26 to
4c0ed06
Compare
Summary
im +chat-listshortcut wrappingGET /open-apis/im/v1/chats(previously not exposed via lark-cli).--exclude-mutedto both+chat-searchand+chat-list: client-side filter that callsPOST /open-apis/im/v1/chat_user_setting/batch_get_mute_statusafter each page and dropsis_muted=truechats.shortcuts/im/mute_filter.gowith pure helpers and an orchestrator (MaybeApplyMuteFilter) shared by both shortcuts.Design highlights
--page-size; the JSON output adds afiltersub-object withapplied/skipped/fetched_count/returned_count/filtered_count/hintso AI/scripts can chainpage_token.fetched_count == returned_count + filtered_countalways holds.--as bot):batch_get_mute_statusis UAT-only, so the filter is skipped withfilter.skipped=true, skip_reason="bot_identity_no_mute_data". All chats returned unfiltered.--search-types public_not_joinedalone: pre-skipped withskip_reason="all_non_member_search_types"(the batch call would 100% returnnot_a_member).filtered_count; surfaced in thehinttext only.--exclude-mutednever injectssearch_typesor any other field into the search/list request. Verified via dry-run tests.BatchGetChatMuteStatusalready has metrics (mute_status.go:60-62). CLI does not duplicate.Output schema (only when
--exclude-mutedis set){ "chats": [...], "filter": { "applied": "exclude_muted", "skipped": false, "fetched_count": 20, "returned_count": 19, "filtered_count": 1, "hint": "Filtered out 1 muted chat(s) on this page (19 remaining, including 2 non-member public group(s)); use --page-token to fetch more." } }Hint is shown in
--format json(field) and--format pretty(line below summary). Not shown in--format table/ndjson/csv— consistent with the existing pagination hint behavior.Test plan
go test ./shortcuts/im/...— passesgo build ./...— cleango vet ./...— clean+chat-list --dry-run— endpoint + params correct+chat-search --query foo --exclude-muted --dry-run— request body unchanged, nosearch_typesinjection+chat-search --search-types public_not_joined --exclude-muted --dry-run—search_typespresent as user requested, no auto-injection+chat-list --helpexposes--exclude-mutedwith correct descriptionbatch_get_mute_statusis GA (currently UAT-only)--as botcall confirmsfilter.skipped=truewithbot_identity_no_mute_dataRisks
batch_get_mute_statusis currently UAT-only (TAT/bot rejected at the API gateway). The CLI handles this gracefully (bot identity skips the filter), but the API itself must be GA before this feature is broadly usable.im:chat:readscope is assumed to coverchat_user_settingreads. If the gateway requires a separate scope, users will see99991679/99991672and we will need a follow-up to add the right scope.meta_data.chat_idfrom each item; if the v2 search response schema changes the wrapping, the filter helper needs updating.Spec docs
docs/specs/2026-05-09-im-chats-filter-muted-design.mddocs/specs/2026-05-09-im-chats-filter-muted-plan.mdThese reference the earlier exploration at
docs/specs/2026-04-28-search-filter-muted-chats-design.md— this PR is the CLI-side variant (option D — pure transparent reporting) that does not block on the search-team-side option B.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation