Skip to content

fix(slack): resolve Slack Connect sender names from inline user_profile#55

Merged
meidad merged 1 commit into
mainfrom
fix/slack-sender-name-from-user-profile
May 27, 2026
Merged

fix(slack): resolve Slack Connect sender names from inline user_profile#55
meidad merged 1 commit into
mainfrom
fix/slack-sender-name-from-user-profile

Conversation

@meidad
Copy link
Copy Markdown
Collaborator

@meidad meidad commented May 27, 2026

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

  • Have a Slack Connect contact DM you. Verify the default-channel notification reads `Nomos DM from Their Real Name` instead of the U-id fallback.
  • Have a regular intra-workspace user DM you. Verify their name still resolves correctly (no regression).
  • Restart the daemon and confirm sender names persist via the cache across multiple messages from the same user.

🤖 Generated with Claude Code

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>
@meidad meidad merged commit 4d22803 into main May 27, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant