feat(feed): add feed +create shortcut for app feed card#526
feat(feed): add feed +create shortcut for app feed card#526jinzemo wants to merge 7 commits intolarksuite:mainfrom
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Shortcuts() aggregator in shortcuts/feed/shortcuts.go and register feed.Shortcuts() in shortcuts/register.go so `lark-cli feed +create` is available at runtime. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use auth status to get userOpenId instead of contact API - Fix JSON path: data.biz_id and data.failed_cards - Passes all 6 feed E2E scenarios in sandbox Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdds a new Changes
Sequence Diagram(s)sequenceDiagram
participant User as User/CLI
participant CLI as Shortcut Runtime
participant API as Lark Open API
User->>CLI: run `feed +create` with flags (--as bot, --user-ids, --link, --title, ...)
CLI->>CLI: validate flags (user count, https link, lengths)
alt dry-run
CLI->>User: print prepared POST /open-apis/im/v2/app_feed_card request JSON
else execute
CLI->>API: POST /open-apis/im/v2/app_feed_card (user_id_type=open_id, body=app_feed_card)
API-->>CLI: response JSON (biz_id, failed_cards)
CLI->>User: print biz_id and failed_cards
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
skills/lark-feed/references/lark-feed-create.md (1)
81-81: Use “Dry Run” as the section title for consistency.The flag is
--dry-run; matching the heading style (Dry Run) improves scanability across docs.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@skills/lark-feed/references/lark-feed-create.md` at line 81, Rename the section heading currently written as "## DryRun" to "## Dry Run" to match the flag `--dry-run` and overall docs style; update the heading text in the lark-feed-create.md file so the section title reads "Dry Run" for consistency and better scanability with the `--dry-run` flag.shortcuts/feed/feed_create_test.go (1)
114-148: Optional-fields test should assert request shape, not only response text.
TestFeedCreate_SuccessWithOptionalFieldswould still pass if--preview/--time-sensitivestopped being included in the outgoing body. Please assert payload content forapp_feed_card.previewandapp_feed_card.time_sensitive.As per coding guidelines, “Every behavior change must have an accompanying test.”
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@shortcuts/feed/feed_create_test.go` around lines 114 - 148, Update TestFeedCreate_SuccessWithOptionalFields to assert the outgoing request payload includes the optional fields: capture or inspect the request sent by runMountedFeedShortcut (via reg.Register's request handler or the httpmock stub mechanism used in other tests) and assert that the JSON body contains app_feed_card.preview == "这是预览文字" and app_feed_card.time_sensitive == true; modify the existing reg.Register call in the test (where the POST to /open-apis/im/v2/app_feed_card is registered) to inspect the incoming request body and fail the test if those two fields are missing or incorrect while still returning the same response.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@shortcuts/feed/feed_create.go`:
- Around line 42-45: The loop that calls common.ValidateUserID on each entry in
userIDs currently discards the trimmed/normalized return value, so raw values
(e.g., " ou_abc ") are later sent in the API body via
runtime.StrArray("user-ids"); update the validation loop in feed_create.go to
capture and replace each userIDs[i] with the cleaned value returned from
common.ValidateUserID (use the validated string result) so the array used to
build runtime.StrArray("user-ids") contains normalized IDs before sending.
In `@tests/cli_e2e/feed/2026_04_16_feed_create_test.go`:
- Around line 147-167: TestFeed_CreateDryRun relies on runtime auth and
discoverFeedRecipientOpenID; replace the dynamic recipient lookup with a static
valid ou_... recipient ID and set the required dry-run environment variables on
the clie2e request to isolate the test. In the TestFeed_CreateDryRun function,
remove the call to discoverFeedRecipientOpenID and use a constant
recipientOpenID string (ou_...), and add the env map entries
LARKSUITE_CLI_APP_ID, APP_SECRET and BRAND to the clie2e.Request (or equivalent
request.Env) so the RunCmd invocation runs with those vars and --dry-run to
validate request structure without hitting real APIs.
---
Nitpick comments:
In `@shortcuts/feed/feed_create_test.go`:
- Around line 114-148: Update TestFeedCreate_SuccessWithOptionalFields to assert
the outgoing request payload includes the optional fields: capture or inspect
the request sent by runMountedFeedShortcut (via reg.Register's request handler
or the httpmock stub mechanism used in other tests) and assert that the JSON
body contains app_feed_card.preview == "这是预览文字" and app_feed_card.time_sensitive
== true; modify the existing reg.Register call in the test (where the POST to
/open-apis/im/v2/app_feed_card is registered) to inspect the incoming request
body and fail the test if those two fields are missing or incorrect while still
returning the same response.
In `@skills/lark-feed/references/lark-feed-create.md`:
- Line 81: Rename the section heading currently written as "## DryRun" to "##
Dry Run" to match the flag `--dry-run` and overall docs style; update the
heading text in the lark-feed-create.md file so the section title reads "Dry
Run" for consistency and better scanability with the `--dry-run` flag.
🪄 Autofix (Beta)
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
Run ID: e476e47c-f539-400a-8f59-49df8d2f82c3
📒 Files selected for processing (7)
shortcuts/feed/feed_create.goshortcuts/feed/feed_create_test.goshortcuts/feed/shortcuts.goshortcuts/register.goskills/lark-feed/SKILL.mdskills/lark-feed/references/lark-feed-create.mdtests/cli_e2e/feed/2026_04_16_feed_create_test.go
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #526 +/- ##
=======================================
Coverage ? 59.09%
=======================================
Files ? 386
Lines ? 32693
Branches ? 0
=======================================
Hits ? 19320
Misses ? 11562
Partials ? 1811 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
🚀 PR Preview Install Guide🧰 CLI updatenpm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@fa4aaf12577a53ca9ce31a25091e0c66f74b36f6🧩 Skill updatenpx skills add yxzhaao/cli#feat/feed-app-feed-card -y -g |
- Remove net/http import, use string literal for HTTP method - Add user ID normalization with strings.TrimSpace - Fix docs: "DryRun" -> "Dry Run" in reference doc - Add request payload assertions in optional fields test - Use static user ID for dry-run E2E test Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
♻️ Duplicate comments (1)
tests/cli_e2e/feed/2026_04_16_feed_create_test.go (1)
149-161:⚠️ Potential issue | 🟠 MajorSet required dry-run E2E env vars explicitly in-test.
Line 153 constructs the dry-run invocation without setting
LARKSUITE_CLI_APP_ID,APP_SECRET, andBRAND, so this test can still depend on ambient machine state.🔧 Proposed fix
func TestFeed_CreateDryRun(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) t.Cleanup(cancel) + t.Setenv("LARKSUITE_CLI_APP_ID", "cli_e2e_dryrun_app_id") + t.Setenv("APP_SECRET", "cli_e2e_dryrun_app_secret") + t.Setenv("BRAND", "feishu") result, err := clie2e.RunCmd(ctx, clie2e.Request{ Args: []string{"feed", "+create", "--user-ids", "ou_test_dry_run_static",As per coding guidelines, “Dry-run E2E tests must set env vars
LARKSUITE_CLI_APP_ID,APP_SECRET,BRANDand use--dry-runflag to validate request structure without calling real APIs.”🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/cli_e2e/feed/2026_04_16_feed_create_test.go` around lines 149 - 161, The TestFeed_CreateDryRun test builds a dry-run invocation but doesn't set required E2E env vars, so it can leak ambient state; before calling clie2e.RunCmd in TestFeed_CreateDryRun, set LARKSUITE_CLI_APP_ID, APP_SECRET, and BRAND (use t.Setenv or os.Setenv + t.Cleanup to restore) so the clie2e.Request/Args call always runs with those explicit dry-run credentials; keep the existing "--dry-run" arg and then call clie2e.RunCmd as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@tests/cli_e2e/feed/2026_04_16_feed_create_test.go`:
- Around line 149-161: The TestFeed_CreateDryRun test builds a dry-run
invocation but doesn't set required E2E env vars, so it can leak ambient state;
before calling clie2e.RunCmd in TestFeed_CreateDryRun, set LARKSUITE_CLI_APP_ID,
APP_SECRET, and BRAND (use t.Setenv or os.Setenv + t.Cleanup to restore) so the
clie2e.Request/Args call always runs with those explicit dry-run credentials;
keep the existing "--dry-run" arg and then call clie2e.RunCmd as before.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ec6d28fa-27b8-4f70-8856-69b41e142836
📒 Files selected for processing (4)
shortcuts/feed/feed_create.goshortcuts/feed/feed_create_test.goskills/lark-feed/references/lark-feed-create.mdtests/cli_e2e/feed/2026_04_16_feed_create_test.go
✅ Files skipped from review due to trivial changes (1)
- skills/lark-feed/references/lark-feed-create.md
🚧 Files skipped from review as they are similar to previous changes (1)
- shortcuts/feed/feed_create.go
|
This PR introduces improvements to the CLI around event handling and command structure. Overall, the changes make the interface more consistent and align better with common CLI design patterns (resource-oriented commands like The implementation looks clean and follows the existing architecture, with clear separation between command definition and execution logic. From a usability perspective, this should improve discoverability and reduce confusion for both human users and AI agents. Impact is mostly localized to the event-related commands and should be backward-compatible (if aliases or migration paths are handled properly). Nice work overall 👍 |
Summary
feeddomain with+createshortcut to send app feed cards to usersim:app_feed_card:writescope--user-ids,--title,--link--preview,--time-sensitiveTest plan
go test ./shortcuts/feed/...)Files changed
shortcuts/feed/feed_create.goshortcuts/feed/feed_create_test.goshortcuts/feed/shortcuts.goshortcuts/register.goskills/lark-feed/SKILL.mdskills/lark-feed/references/lark-feed-create.mdtests/cli_e2e/feed/2026_04_16_feed_create_test.go🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
feed +createcommand to send app feed card messages to Lark users, supporting multiple recipients (up to 20), title, HTTPS link, optional preview and time-sensitive flag, and dry-run preview.Documentation
Tests
Chores