Skip to content

feat: add chat-members-add shortcut - #2214

Closed
zhangheng023 wants to merge 14 commits into
mainfrom
feat/im-add-members-shortcut
Closed

feat: add chat-members-add shortcut#2214
zhangheng023 wants to merge 14 commits into
mainfrom
feat/im-add-members-shortcut

Conversation

@zhangheng023

@zhangheng023 zhangheng023 commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a new im +chat-members-add shortcut that adds users and/or bots to an existing group chat. It replaces the raw im chat.members create meta API call — which requires two separate JSON blobs (--params for chat_id/member_id_type/succeed_type, --data for id_list) and an implicit rule that a user ID's format must match member_id_type while bot IDs are always app_id — with two plain flags (--users, --bots) and a fixed member_id_type=open_id, removing that footgun entirely.

Changes

  • New shortcut shortcuts/im/im_chat_members_add.go: --chat-id (required), --users (comma-separated ou_xxx, max 50), --bots (comma-separated cli_xxx, max 5), --succeed-type (0 = strict / 1 = partial-success, default 1)
  • Partial-failure reporting via an ok:false ledger envelope (mirrors the existing +feed-shortcut-create convention), covering all three server response buckets (invalid_id_list, not_existed_id_list, pending_approval_id_list) so a member that failed to join is never miscounted as succeeded
  • Registered in shortcuts/im/shortcuts.go
  • New skill reference doc skills/lark-im/references/lark-im-chat-members-add.md; SKILL.md Shortcuts/permission tables updated
  • Two existing docs (lark-im-chat-create.md, affordance/im.md) updated to point their two-step invite examples at the new shortcut instead of the raw meta command
  • Incidental fix: an unrelated, pre-existing doc-drift bug on +messages-search (its affordance example still pinned --as user after a recent PR made it dual-identity) was also corrected, since it was blocking a clean go test signal for this branch

Test Plan

  • Unit tests pass (go test ./shortcuts/im/..., go test ./internal/affordance/...) — covers flag validation, dry-run, the full ledger (all-success / partial-failure across all three failure buckets), and the --succeed-type strict/partial modes
  • Build and static checks pass
  • Manual verification: lark-cli im +chat-members-add --chat-id oc_xxx --users ou_xxx --bots cli_xxx against a real Feishu tenant — confirmed the partial-failure ledger output and the empty --users/--bots validation error

Related Issues

  • None

Summary by CodeRabbit

  • New Features

    • Added a shortcut for adding users and bots to existing group chats.
    • Supports validation, dry runs, success and partial-failure reporting, and pending-approval results.
    • Added controls for success handling and clear output for invalid or unavailable member IDs.
  • Documentation

    • Added command usage, permissions, examples, identity requirements, and recovery guidance.
    • Updated group chat invitation instructions to use the new shortcut.

@github-actions github-actions Bot added domain/im PR touches the im domain size/L Large or sensitive change across domains or core paths labels Aug 6, 2026
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

The PR adds the +chat-members-add IM shortcut. It validates user and bot identifiers, submits additions, supports dry runs, reports partial failures, registers the shortcut, updates affordance counts, and adds usage and permission documentation.

IM chat member addition

Layer / File(s) Summary
Shortcut validation and execution
shortcuts/im/im_chat_members_add.go, shortcuts/im/im_chat_members_add_test.go
The shortcut validates chat IDs, member IDs, limits, and succeed_type. It builds and submits the request, supports dry-run output, and tests request behavior.
Result processing and validation coverage
shortcuts/im/im_chat_members_add.go, shortcuts/im/im_chat_members_add_test.go
The result handler reports successes, failures, pending approvals, invalid IDs, and partial failures. Tests cover server anomalies and output invariants.
Shortcut registration and guidance
shortcuts/im/shortcuts.go, shortcuts/im/affordance_migration_test.go, shortcuts/im/helpers_test.go, internal/affordance/im_source_test.go, affordance/im.md, skills/lark-im/SKILL.md, skills/lark-im/references/lark-im-chat-create.md, skills/lark-im/references/lark-im-chat-members-add.md
The shortcut is registered. Affordance tests and counts are updated. IM guidance documents syntax, permissions, recovery behavior, and identifier formats.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant ImChatMembersAdd
  participant ChatMembersAPI
  CLI->>ImChatMembersAdd: provide chat, user, bot, and succeed_type flags
  ImChatMembersAdd->>ImChatMembersAdd: validate inputs and build request
  ImChatMembersAdd->>ChatMembersAPI: POST chat members with open_id identifiers
  ChatMembersAPI-->>ImChatMembersAdd: return addition results
  ImChatMembersAdd-->>CLI: render success and failure output
Loading

Suggested reviewers: liangshuo-1

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description check ✅ Passed The description includes the required Summary, Changes, Test Plan, and Related Issues sections with specific implementation and verification details.
Title check ✅ Passed The title clearly identifies the main change: adding the chat-members-add shortcut.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/im-add-members-shortcut

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.57692% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.41%. Comparing base (70ca6e2) to head (689595e).

Files with missing lines Patch % Lines
shortcuts/im/im_chat_members_add.go 85.43% 8 Missing and 7 partials ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             main    #2214    +/-   ##
========================================
  Coverage   76.40%   76.41%            
========================================
  Files        1012     1013     +1     
  Lines      111565   111669   +104     
========================================
+ Hits        85241    85330    +89     
- Misses      19832    19840     +8     
- Partials     6492     6499     +7     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@689595e7bed4fd886fe232ed3616b048b1162692

🧩 Skill update

npx skills add larksuite/cli#feat/im-add-members-shortcut -y -g

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown

PR Quality Summary

CI did not complete successfully. Use the failed check links below to decide whether this PR needs a code change or a rerun.

Failed checks

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
shortcuts/im/im_chat_members_add_test.go (3)

521-539: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the dry-run payload; the test name promises body coverage.

TestImChatMembersAddDryRunRendersBody only checks that DryRun returns a non-nil value. The test passes even if the method, path, member_id_type, succeed_type, or id_list change. Assert those fields so a regression in DryRun fails the test.

As per coding guidelines: "contract tests must assert the changed field or behavior directly so reverting the implementation causes failure".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/im/im_chat_members_add_test.go` around lines 521 - 539, Strengthen
TestImChatMembersAddDryRunRendersBody by asserting the returned dry-run request
payload, including the HTTP method, path, member_id_type, succeed_type, and
id_list fields. Keep the existing no-API-call setup, and make each expected
value explicit so reverting ImChatMembersAdd.DryRun causes the test to fail.

Source: Coding guidelines


349-398: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Parse the JSON output instead of scanning substrings.

extractArrayField, extractIntField, and the strings.Contains assertions depend on key order, spacing, and formatting of the emitted JSON. Decode the captured stdout with encoding/json and assert on typed values. Also, joinComma duplicates strings.Join.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/im/im_chat_members_add_test.go` around lines 349 - 398, Replace the
substring-based helpers extractArrayField and extractIntField, along with
related strings.Contains assertions, by decoding captured stdout through
encoding/json into typed values and asserting against those values independent
of JSON formatting or key order. Remove joinComma and use strings.Join for
comma-separated IDs.

96-119: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use distinct IDs in the over-limit fixture.

"ou_"+string(rune('a'+i%26)) produces duplicate IDs for i >= 26. The test then depends on common.SplitCSV not deduplicating. Generate 51 unique IDs, for example with fmt.Sprintf("ou_%d", i), so the fixture tests the cap and not the split behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/im/im_chat_members_add_test.go` around lines 96 - 119, Update the
fixture in TestCollectChatMembersToAddRejectsTooManyUsers to generate 51
distinct user IDs, replacing the rune-based ID construction with a numeric
format such as fmt.Sprintf("ou_%d", i); add or reuse the required fmt import.
Keep the test focused on rejecting the user-count limit.
shortcuts/im/im_chat_members_add.go (2)

85-119: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Confirm the intent of the stderr failure count.

failedIDs includes IDs returned by the server that were never requested. failure_count counts only requested IDs. When the server echoes an unrequested ID, the stderr warning count and the JSON failure_count differ. The test TestEmitChatMembersAddResultInvariantHoldsUnderServerAnomalies covers this case for the JSON invariant but not for the warning text. Consider filtering failedIDs to requested IDs, or keep the current behavior deliberately.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/im/im_chat_members_add.go` around lines 85 - 119, Align the stderr
warning count with the requested-member failure count in the result-building
flow around failedSet, failedIDs, and outData. Filter server-reported failures
to IDs present in requested before calculating the warning count, while
preserving deduplication and the existing failure lists and JSON counts.

46-57: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a shared bot-ID validator for shortcut flags.

--users calls common.ValidateUserIDTyped, while both +chat-create and this shortcut use inline strings.HasPrefix(id, "cli_") checks. Introduce a shared common.ValidateBotIDTyped helper and use it here so bot-ID validation, normalization, and error text stay consistent.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/im/im_chat_members_add.go` around lines 46 - 57, Add a shared
common.ValidateBotIDTyped helper for bot-ID validation, normalization, and
consistent error text, then replace the inline strings.HasPrefix check in the
bots parsing block with that helper. Preserve the existing --bots count limit
and append each validated/normalized bot ID to bots.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@skills/lark-im/references/lark-im-chat-create.md`:
- Around line 89-93: Update the recovery guidance near the default
`--succeed-type 1` behavior to name all failure lists: `invalid_id_list`,
`not_existed_id_list`, and `pending_approval_ids`. State that any non-empty list
represents users not successfully added and causes `+chat-members-add` to exit
non-zero, matching the rule documented in `lark-im-chat-members-add.md`.

---

Nitpick comments:
In `@shortcuts/im/im_chat_members_add_test.go`:
- Around line 521-539: Strengthen TestImChatMembersAddDryRunRendersBody by
asserting the returned dry-run request payload, including the HTTP method, path,
member_id_type, succeed_type, and id_list fields. Keep the existing no-API-call
setup, and make each expected value explicit so reverting
ImChatMembersAdd.DryRun causes the test to fail.
- Around line 349-398: Replace the substring-based helpers extractArrayField and
extractIntField, along with related strings.Contains assertions, by decoding
captured stdout through encoding/json into typed values and asserting against
those values independent of JSON formatting or key order. Remove joinComma and
use strings.Join for comma-separated IDs.
- Around line 96-119: Update the fixture in
TestCollectChatMembersToAddRejectsTooManyUsers to generate 51 distinct user IDs,
replacing the rune-based ID construction with a numeric format such as
fmt.Sprintf("ou_%d", i); add or reuse the required fmt import. Keep the test
focused on rejecting the user-count limit.

In `@shortcuts/im/im_chat_members_add.go`:
- Around line 85-119: Align the stderr warning count with the requested-member
failure count in the result-building flow around failedSet, failedIDs, and
outData. Filter server-reported failures to IDs present in requested before
calculating the warning count, while preserving deduplication and the existing
failure lists and JSON counts.
- Around line 46-57: Add a shared common.ValidateBotIDTyped helper for bot-ID
validation, normalization, and consistent error text, then replace the inline
strings.HasPrefix check in the bots parsing block with that helper. Preserve the
existing --bots count limit and append each validated/normalized bot ID to bots.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d91f20e9-2f48-4657-a542-e12a85dde6b9

📥 Commits

Reviewing files that changed from the base of the PR and between 70ca6e2 and 689595e.

📒 Files selected for processing (10)
  • affordance/im.md
  • internal/affordance/im_source_test.go
  • shortcuts/im/affordance_migration_test.go
  • shortcuts/im/helpers_test.go
  • shortcuts/im/im_chat_members_add.go
  • shortcuts/im/im_chat_members_add_test.go
  • shortcuts/im/shortcuts.go
  • skills/lark-im/SKILL.md
  • skills/lark-im/references/lark-im-chat-create.md
  • skills/lark-im/references/lark-im-chat-members-add.md

Comment on lines +89 to +93
lark-cli im +chat-members-add --chat-id <chat_id from step 2> \
--users ou_aaa,ou_bbb --as user
```

`succeed_type=1` ensures reachable users are added successfully; unreachable ones are returned in `invalid_id_list` instead of failing the whole request.
By default (`--succeed-type 1`), reachable users are added successfully; unreachable ones are returned in `invalid_id_list` instead of failing the whole request.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Name all three failure lists in the recovery step.

Line 93 mentions only invalid_id_list. +chat-members-add also reports not_existed_id_list and pending_approval_ids, and it exits non-zero when any of the three is non-empty. skills/lark-im/references/lark-im-chat-members-add.md states this rule. Update the text so the two documents agree.

📝 Proposed doc fix
-   By default (`--succeed-type 1`), reachable users are added successfully; unreachable ones are returned in `invalid_id_list` instead of failing the whole request.
+   By default (`--succeed-type 1`), reachable users are added successfully; unreachable ones are returned in `invalid_id_list`, `not_existed_id_list`, or `pending_approval_ids` instead of failing the whole request. The command exits non-zero with `ok:false` when any of the three lists is non-empty.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
lark-cli im +chat-members-add --chat-id <chat_id from step 2> \
--users ou_aaa,ou_bbb --as user
```
`succeed_type=1` ensures reachable users are added successfully; unreachable ones are returned in `invalid_id_list` instead of failing the whole request.
By default (`--succeed-type 1`), reachable users are added successfully; unreachable ones are returned in `invalid_id_list` instead of failing the whole request.
lark-cli im +chat-members-add --chat-id <chat_id from step 2> \
--users ou_aaa,ou_bbb --as user
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/lark-im/references/lark-im-chat-create.md` around lines 89 - 93,
Update the recovery guidance near the default `--succeed-type 1` behavior to
name all failure lists: `invalid_id_list`, `not_existed_id_list`, and
`pending_approval_ids`. State that any non-empty list represents users not
successfully added and causes `+chat-members-add` to exit non-zero, matching the
rule documented in `lark-im-chat-members-add.md`.

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

Labels

domain/im PR touches the im domain feature size/L Large or sensitive change across domains or core paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant