Skip to content

refactor: resolves user mentions in message text to display names#233

Open
psyberck wants to merge 2 commits intokorotovsky:masterfrom
psyberck:refactor/user-mentions
Open

refactor: resolves user mentions in message text to display names#233
psyberck wants to merge 2 commits intokorotovsky:masterfrom
psyberck:refactor/user-mentions

Conversation

@psyberck
Copy link
Copy Markdown

@psyberck psyberck commented Mar 10, 2026

Summary (Close Issue #222 )

Reading messages via conversations_history, conversations_search_messages, or conversations_replies, user mentions embedded in message text will be displayed as usernames.

Implementations

  • ProcessText now delegates entirely to filterSpecialChars instead of having its own mention-handling logic
  • filterSpecialChars gained a userMaps map[string]slack.User parameter — user mention resolution (<@U...> → @name) happens in a single pass alongside link/special-char processing

Pros

  • Single pass: mention resolution and special-char filtering happen together — fewer string iterations

Cons

  • filterSpecialChars is no longer pure: it now takes external state (userMaps), making it harder to test in isolation from user data
  • filterSpecialChars remains untouched

Test plan

  • go build ./... — compiles cleanly
  • go vet ./... — no warnings
  • TestFilterSpecialCharsWithCommas — updated to add 9 new test cases for user mentions
  • All existing unit tests still pass
  • Manual testing with xoxc/xoxd tokens
  • Manual testing with xoxp/xoxb tokens

Let me know what you think, thanks!

Copy link
Copy Markdown

@chriscoey chriscoey left a comment

Choose a reason for hiding this comment

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

Nice work — the placeholder approach is clean, follows the existing URL protection pattern, and the test coverage is solid. A few suggestions:

1. Display name vs username

u.Name is the Slack username (e.g., chris.coey), but what users see in the UI is Profile.DisplayName or RealName. Consider:

name := u.Profile.DisplayName
if name == "" {
    name = u.RealName
}
if name == "" {
    name = u.Name
}

This matches how Slack itself renders mentions.

2. Pipe-label format

Slack sometimes encodes mentions as <@U12345|display_name> (with a pipe and label). The current regex <@([UW][A-Z0-9]+)> won't match these. A small tweak:

regexp.MustCompile(`<@([UW][A-Z0-9]+)(?:\|[^>]+)?>`)

3. Pre-compile regex

userMentionRegex is compiled inside filterSpecialChars on every call. Moving it to a package-level var avoids repeated compilation:

var userMentionRegex = regexp.MustCompile(`<@([UW][A-Z0-9]+)(?:\|[^>]+)?>`)

(Same applies to the URL and clean regexes, but that's a pre-existing issue — not your problem to fix here.)

4. Minor: slack.User dependency in text package

Threading userMaps into filterSpecialChars adds a slack-go/slack import to the text package, which was previously independent of Slack types. An alternative would be resolving mentions in convertMessagesFromHistory before calling ProcessText, keeping the text package stateless. But the placeholder approach is well-contained and consistent with how URLs are handled, so this is a trade-off I think is acceptable.

Overall this is in good shape. The test cases are thorough — particularly liked the "normal text same to user ID" and "invalid Slack user mention format" cases. Would be great to see this merged.

@psyberck
Copy link
Copy Markdown
Author

Thanks for the thorough comments. @chriscoey:). I will update the code accordingly.

@psyberck
Copy link
Copy Markdown
Author

Hey @chriscoey, I have refactored the implementations to resolve above concerns and feel like it's much cleaner. Let me know if there are more I can improve. Thanks!

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.

2 participants