Skip to content

feat: resolve bot sender names in message list#823

Open
os-zzw wants to merge 1 commit into
larksuite:mainfrom
os-zzw:feat/bot-sender-name
Open

feat: resolve bot sender names in message list#823
os-zzw wants to merge 1 commit into
larksuite:mainfrom
os-zzw:feat/bot-sender-name

Conversation

@os-zzw
Copy link
Copy Markdown

@os-zzw os-zzw commented May 11, 2026

As requested, this PR resolves bot sender names in chat-messages-list and related commands by extracting app/bot IDs and querying their names via the Application OpenAPI.

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Improved sender name resolution to properly display app and bot sender identities in messages, in addition to user senders.

Review Change Stack

Implement bot/app sender name enrichment for IM message listing.

- Extend ResolveSenderNames to collect sender_type=app|bot IDs in addition to users
- Fetch app/bot display names via application v6 get endpoint and merge into the shared cache
- Prefer bot identity when available (falls back to current identity) and keep failures non-fatal
- Update unit tests to cover bot/app sender name resolution

Co-Authored-By: Aime <aime@bytedance.com>
Change-Id: I2cfc68abc4af90e9377cd2ad3c59f05cb7cfd12d
@github-actions github-actions Bot added domain/im PR touches the im domain size/M Single-domain feat or fix with limited business impact labels May 11, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

📝 Walkthrough

Walkthrough

ResolveSenderNames is extended to resolve display names for app and bot senders in addition to users. Missing sender IDs are tracked separately by type, resolved via conditional user or app batch APIs, with a new helper routing requests through bot or standard API endpoints based on runtime capability.

Changes

App/Bot Sender Name Resolution

Layer / File(s) Summary
Resolution Entry Point
shortcuts/im/convert_lib/helpers.go
ResolveSenderNames tracks missing user and app/bot IDs separately, skips cached senders, exits early when both lists are empty, and dispatches missing users to bot/contact resolution or missing apps to the new batchResolveApps.
API Helper Functions
shortcuts/im/convert_lib/helpers.go
batchResolveApps resolves app display names from the application API response into the shared name map. doAPIJSONAsBotIfPossible conditionally routes API requests through runtime.DoAPIAsBot if available, otherwise falls back to runtime.DoAPIJSON, validates the envelope and code, and returns the data field.
Test Coverage
shortcuts/im/convert_lib/helpers_test.go
HTTP mock routes extended to handle /open-apis/application/v6/applications/cli_bot (with lang=zh_cn query) and /cli_app endpoints. Test fixtures include cli_bot and cli_app senders. Assertions verify resolved names for both app and bot senders match expected values.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 App and bot names now shine so bright,
Resolved in batches through the night,
With conditional APIs routing with care,
And tests to prove they're handled fair! 🎉

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is missing critical sections from the template (Changes, Test Plan, and Related Issues) and does not fully explain the implementation details or testing approach. Expand the description to include: detailed list of changes made, test plan confirming unit tests pass and manual verification, and any related issues or GitHub issue links.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: resolve bot sender names in message list' accurately and concisely describes the main change—extending sender name resolution to include bot senders.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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 and usage tips.

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


zhangzhewei seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (4)
shortcuts/im/convert_lib/helpers.go (4)

75-85: ⚡ Quick win

Refresh the ResolveSenderNames doc block to mention bot/app resolution.

The doc currently describes only Step 1 (mentions) and Step 2 (contact batch API for users), but the body now also has a Step 3 that resolves app/bot senders via the application API. Worth bringing the comment in line with the new behavior — including the API permissions required (e.g., application:application:readonly) so callers aren't surprised when bot/app names silently fail to resolve.

📝 Suggested doc tweak
 // ResolveSenderNames batch-resolves sender open_ids to display names.
 // The cache map is used to share already-resolved IDs across calls; newly resolved
 // names are written back into it. Pass an empty map if no prior cache exists.
 //
 // Step 1: extract names from message mentions (free, no API call).
-// Step 2: for remaining unresolved IDs, call contact batch API (requires contact:user.base:readonly).
+// Step 2: for remaining user sender IDs, call contact batch API
+//         (requires contact:user.base:readonly).
+// Step 3: for remaining bot/app sender IDs, call application API
+//         (requires application:application:readonly; routed via bot identity when available).
 // Silently returns partial results on API error.
🤖 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/convert_lib/helpers.go` around lines 75 - 85, Update the
ResolveSenderNames doc block to reflect the current three-step behavior: Step 1
extracts display names from message mentions, Step 2 batch-resolves user IDs via
the contact API (requires contact:user.base:readonly), and Step 3 resolves
bot/app senders via the application API (requires
application:application:readonly); also note that newly resolved names are
written back into the provided cache map, and that the function may return
partial results if any API call fails.

247-251: 💤 Low value

Confirm whether the data.app_name top-level fallback is reachable.

The application v6 GET endpoint nests the app metadata under data.app, so data["app_name"] at line 250 looks like dead defensive code. If you've actually observed a response shape where app_name lives at the top level (e.g., different API version or routing), consider adding a comment noting that; otherwise the fallback can go.

🤖 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/convert_lib/helpers.go` around lines 247 - 251, The fallback to
data["app_name"] appears unreachable given the v6 API nests app metadata under
data["app"]; verify by checking observed response shapes and, if no responses
place app_name at the top level, remove the fallback lines (the cast of
data["app_name"] and the alternate assignment) and rely on app["app_name"];
otherwise keep the fallback but add a clarifying comment above this block
stating which API versions or endpoints produce a top-level app_name so future
readers know it's intentional (referencing the variables data, app and the
app_name assignment in helpers.go).

240-256: 💤 Low value

Function name batchResolveApps is misleading — it's per-ID serial.

There's no batch endpoint here (one HTTP request per app id, sequentially). For a chat-messages-list with many distinct bot senders, this becomes N round-trips on the critical path. The chill-mode acceptance is fine, but worth either renaming (e.g., resolveAppsSerially) for honesty, or adding a small concurrency layer (errgroup with a low limit) if you expect more than a handful of bot senders per page.

🤖 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/convert_lib/helpers.go` around lines 240 - 256, The function
batchResolveApps is misleading because it performs serial per-ID requests;
either rename it to resolveAppsSerially (and update all callers) or add limited
concurrency: use an errgroup (or goroutine pool) to issue
doAPIJSONAsBotIfPossible calls concurrently for elements of appIDs while
protecting writes to nameMap with a mutex and bounding parallelism (e.g., a
semaphore channel or worker pool) to avoid overwhelming the API; keep the same
signature (runtime *common.RuntimeContext, appIDs []string, nameMap
map[string]string) and ensure errors are handled/ignored consistently as before.

134-147: ⚡ Quick win

The assumption that bot/app sender id is always an app_id is correct per the API contract.

The Lark IM v1 messages-list response guarantees that when sender_type is "app" or "bot", id_type will be "app_id" and sender.id will contain the application id—never an open_id like ou_.... The code is safe as written.

That said, adding explicit validation (e.g., checking id_type == "app_id" or validating the id prefix) would improve defensive consistency with the user branch and protect against unexpected edge cases.

🤖 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/convert_lib/helpers.go` around lines 134 - 147, The switch
handling senderType ("user"/"app"/"bot") assumes app/bot ids are always app IDs;
add a defensive check in the "app" and "bot" branch to verify the id is an app
ID (e.g., check id_type == "app_id" if that variable exists or assert the id
does not have the "ou_" prefix) before marking seenApps and appending to
missingAppIDs; if the validation fails, skip the id (similar to the user branch)
so seenApps, missingAppIDs, seenUsers, and missingUserIDs updates remain
consistent.
🤖 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.

Nitpick comments:
In `@shortcuts/im/convert_lib/helpers.go`:
- Around line 75-85: Update the ResolveSenderNames doc block to reflect the
current three-step behavior: Step 1 extracts display names from message
mentions, Step 2 batch-resolves user IDs via the contact API (requires
contact:user.base:readonly), and Step 3 resolves bot/app senders via the
application API (requires application:application:readonly); also note that
newly resolved names are written back into the provided cache map, and that the
function may return partial results if any API call fails.
- Around line 247-251: The fallback to data["app_name"] appears unreachable
given the v6 API nests app metadata under data["app"]; verify by checking
observed response shapes and, if no responses place app_name at the top level,
remove the fallback lines (the cast of data["app_name"] and the alternate
assignment) and rely on app["app_name"]; otherwise keep the fallback but add a
clarifying comment above this block stating which API versions or endpoints
produce a top-level app_name so future readers know it's intentional
(referencing the variables data, app and the app_name assignment in helpers.go).
- Around line 240-256: The function batchResolveApps is misleading because it
performs serial per-ID requests; either rename it to resolveAppsSerially (and
update all callers) or add limited concurrency: use an errgroup (or goroutine
pool) to issue doAPIJSONAsBotIfPossible calls concurrently for elements of
appIDs while protecting writes to nameMap with a mutex and bounding parallelism
(e.g., a semaphore channel or worker pool) to avoid overwhelming the API; keep
the same signature (runtime *common.RuntimeContext, appIDs []string, nameMap
map[string]string) and ensure errors are handled/ignored consistently as before.
- Around line 134-147: The switch handling senderType ("user"/"app"/"bot")
assumes app/bot ids are always app IDs; add a defensive check in the "app" and
"bot" branch to verify the id is an app ID (e.g., check id_type == "app_id" if
that variable exists or assert the id does not have the "ou_" prefix) before
marking seenApps and appending to missingAppIDs; if the validation fails, skip
the id (similar to the user branch) so seenApps, missingAppIDs, seenUsers, and
missingUserIDs updates remain consistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ac70bfa5-d62f-47ee-84d8-e2c63f632da1

📥 Commits

Reviewing files that changed from the base of the PR and between 25c72ce and 5ca7686.

📒 Files selected for processing (2)
  • shortcuts/im/convert_lib/helpers.go
  • shortcuts/im/convert_lib/helpers_test.go

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 size/M Single-domain feat or fix with limited business impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants