fix(slack): resolve Slack Connect sender names from inline user_profile#55
Merged
Merged
Conversation
Slack Connect DMs surfaced as "external Slack user (U073UDQAT0T)" in default-channel draft notifications because `users.info` returns `user_not_found` for cross-workspace senders in our own workspace and the cross-workspace fallback only worked if we happened to have a token for the sender's home workspace. Slack's `message` event already carries the sender's display info inline as `user_profile` (same shape as `users.info`'s `profile`) plus their home `user_team`. We were ignoring both. Now: on every incoming message we seed the username cache from `user_profile.real_name` (then `display_name`, then `name`) before any handler calls `lookupUserName`. We also remember `user_team` so that when we DO need a cross-workspace API call (e.g., the inline profile was missing), we try that workspace's token first instead of scanning every workspace. Side benefit: if `user_profile.email` matches the owner's email, we mark the foreign user_id as one of our own (was previously handled only after a successful `users.info` resolution). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Slack Connect DMs were rendering in default-channel draft notifications as `Nomos DM from external Slack user (U073UDQAT0T)` instead of the sender's actual name.
Why this happened: `users.info` returns `user_not_found` for cross-workspace senders in our own workspace. The existing cross-workspace fallback only worked if we happened to have a token for the sender's home workspace — for most Slack Connect senders, we don't.
What Slack already gave us: every `message` event already carries the sender's display info inline as `user_profile` (same shape as `users.info`'s `profile`) plus their home `user_team`. We were ignoring both.
Change
src/daemon/channels/slack-user.ts — on every incoming message we now seed the username cache from `event.user_profile.real_name` (then `display_name`, then `name`) BEFORE any handler calls `lookupUserName`. We also remember `event.user_team` so that when we DO need a cross-workspace API call, we try that specific workspace's token first instead of scanning every workspace.
Won't overwrite a previously-resolved real name with an event-provided one (e.g., a name from `users.info` is preferred over the event payload). Only seeds when the cache is empty or holds the `external Slack user (...)` fallback label.
Side benefit: if `user_profile.email` matches the owner's email, we mark the foreign user_id as one of our own, so we skip drafting for messages "from us" arriving via Slack Connect.
Backstory
This commit was orphaned from #54 — I pushed it to that branch after the squash-merge already happened, so it never made it onto main. Same content, fresh branch.
Test plan
🤖 Generated with Claude Code