@@ -18,7 +18,8 @@ import (
1818
1919// Client wraps discordgo.Session with a clean interface for bot operations.
2020type Client struct {
21- session * discordgo.Session
21+ session session
22+ realSession * discordgo.Session // Keep reference for Session() method
2223 channelCache map [string ]string // channel name -> ID
2324 channelTypeCache map [string ]discordgo.ChannelType // channel ID -> type
2425 userCache map [string ]string // username -> ID
@@ -42,7 +43,8 @@ func New(token string) (*Client, error) {
4243 discordgo .IntentsMessageContent
4344
4445 return & Client {
45- session : session ,
46+ session : & sessionAdapter {Session : session },
47+ realSession : session ,
4648 channelCache : make (map [string ]string ),
4749 channelTypeCache : make (map [string ]discordgo.ChannelType ),
4850 userCache : make (map [string ]string ),
@@ -106,7 +108,7 @@ func (c *Client) Close() error {
106108
107109// Session returns the underlying discordgo session.
108110func (c * Client ) Session () * discordgo.Session {
109- return c .session
111+ return c .realSession
110112}
111113
112114// PostMessage sends a plain text message to a channel with link embeds suppressed.
@@ -423,7 +425,7 @@ func (c *Client) LookupUserByUsername(ctx context.Context, username string) stri
423425 "guild_id" , guildID ,
424426 "total_members" , len (members ))
425427
426- // Tier 1: Exact match (Username takes precedence over GlobalName)
428+ // Tier 1: Exact match (Username takes precedence over GlobalName, then Nick )
427429 for _ , member := range members {
428430 if member .User .Username != username {
429431 continue
@@ -456,8 +458,25 @@ func (c *Client) LookupUserByUsername(ctx context.Context, username string) stri
456458
457459 return member .User .ID
458460 }
461+ for _ , member := range members {
462+ if member .Nick != username {
463+ continue
464+ }
465+ c .mu .Lock ()
466+ c .userCache [username ] = member .User .ID
467+ c .mu .Unlock ()
468+
469+ slog .Debug ("found user by exact nickname match" ,
470+ "username" , username ,
471+ "user_id" , member .User .ID ,
472+ "discord_username" , member .User .Username ,
473+ "discord_global_name" , member .User .GlobalName ,
474+ "discord_nick" , member .Nick )
475+
476+ return member .User .ID
477+ }
459478
460- // Tier 2: Case-insensitive match (Username takes precedence over GlobalName)
479+ // Tier 2: Case-insensitive match (Username takes precedence over GlobalName, then Nick )
461480 for _ , member := range members {
462481 if ! strings .EqualFold (member .User .Username , username ) {
463482 continue
@@ -490,6 +509,23 @@ func (c *Client) LookupUserByUsername(ctx context.Context, username string) stri
490509
491510 return member .User .ID
492511 }
512+ for _ , member := range members {
513+ if ! strings .EqualFold (member .Nick , username ) {
514+ continue
515+ }
516+ c .mu .Lock ()
517+ c .userCache [username ] = member .User .ID
518+ c .mu .Unlock ()
519+
520+ slog .Info ("found user by case-insensitive nickname match" ,
521+ "username" , username ,
522+ "user_id" , member .User .ID ,
523+ "discord_username" , member .User .Username ,
524+ "discord_global_name" , member .User .GlobalName ,
525+ "discord_nick" , member .Nick )
526+
527+ return member .User .ID
528+ }
493529
494530 lowerUsername := strings .ToLower (username )
495531
@@ -503,11 +539,14 @@ func (c *Client) LookupUserByUsername(ctx context.Context, username string) stri
503539 for _ , member := range members {
504540 usernamePrefix := strings .HasPrefix (strings .ToLower (member .User .Username ), lowerUsername )
505541 globalNamePrefix := strings .HasPrefix (strings .ToLower (member .User .GlobalName ), lowerUsername )
542+ nickPrefix := strings .HasPrefix (strings .ToLower (member .Nick ), lowerUsername )
506543
507544 if usernamePrefix {
508545 matches = append (matches , prefixMatch {member : member , matchType : "username_prefix" })
509546 } else if globalNamePrefix {
510547 matches = append (matches , prefixMatch {member : member , matchType : "global_name_prefix" })
548+ } else if nickPrefix {
549+ matches = append (matches , prefixMatch {member : member , matchType : "nick_prefix" })
511550 }
512551 }
513552
@@ -551,6 +590,7 @@ func (c *Client) LookupUserByUsername(ctx context.Context, username string) stri
551590 "index" , i ,
552591 "discord_username" , member .User .Username ,
553592 "discord_global_name" , member .User .GlobalName ,
593+ "discord_nick" , member .Nick ,
554594 "user_id" , member .User .ID )
555595 }
556596
@@ -563,11 +603,11 @@ func (c *Client) LookupUserByUsername(ctx context.Context, username string) stri
563603
564604// IsBotInChannel checks if the bot has permission to send messages in a channel.
565605func (c * Client ) IsBotInChannel (ctx context.Context , channelID string ) bool {
566- if c .session .State == nil || c .session .State .User == nil {
606+ if c .session .GetState () == nil || c .session .GetState () .User == nil {
567607 return false
568608 }
569609
570- perms , err := c .session .UserChannelPermissions (c .session .State .User .ID , channelID )
610+ perms , err := c .session .UserChannelPermissions (c .session .GetState () .User .ID , channelID )
571611 if err != nil {
572612 slog .Debug ("failed to check channel permissions" ,
573613 "channel_id" , channelID ,
@@ -618,7 +658,7 @@ func (c *Client) IsUserActive(ctx context.Context, userID string) bool {
618658 }
619659
620660 // Get guild from state
621- guild , err := c .session .State .Guild (guildID )
661+ guild , err := c .session .GetState () .Guild (guildID )
622662 if err != nil {
623663 slog .Debug ("failed to get guild from state" ,
624664 "guild_id" , guildID ,
@@ -681,13 +721,13 @@ type BotInfo struct {
681721
682722// BotInfo returns the bot's user information.
683723func (c * Client ) BotInfo (ctx context.Context ) (BotInfo , error ) {
684- if c .session .State == nil || c .session .State .User == nil {
724+ if c .session .GetState () == nil || c .session .GetState () .User == nil {
685725 return BotInfo {}, errors .New ("bot user not available" )
686726 }
687727
688728 return BotInfo {
689- UserID : c .session .State .User .ID ,
690- Username : c .session .State .User .Username ,
729+ UserID : c .session .GetState () .User .ID ,
730+ Username : c .session .GetState () .User .Username ,
691731 }, nil
692732}
693733
@@ -707,7 +747,7 @@ func (c *Client) FindForumThread(ctx context.Context, forumID, prURL string) (th
707747 var threads * discordgo.ThreadsList
708748 err := retryableCtx (ctx , func () error {
709749 var err error
710- threads , err = c .session .GuildThreadsActive (c .guildID )
750+ threads , err = c .session .ThreadsActive (c .guildID )
711751 return err
712752 })
713753 if err != nil {
@@ -733,10 +773,11 @@ func (c *Client) FindForumThread(ctx context.Context, forumID, prURL string) (th
733773 }
734774
735775 // Also check archived threads (recently archived) with retry
776+ // Use realSession directly since ThreadsArchived is not in the session interface
736777 var archivedThreads * discordgo.ThreadsList
737778 err = retryableCtx (ctx , func () error {
738779 var err error
739- archivedThreads , err = c .session .ThreadsArchived (forumID , nil , 50 )
780+ archivedThreads , err = c .realSession .ThreadsArchived (forumID , nil , 50 )
740781 return err
741782 })
742783 if err != nil {
@@ -776,8 +817,8 @@ func (c *Client) FindChannelMessage(ctx context.Context, channelID, prURL string
776817 }
777818
778819 var botID string
779- if c .session .State != nil && c .session .State .User != nil {
780- botID = c .session .State .User .ID
820+ if c .session .GetState () != nil && c .session .GetState () .User != nil {
821+ botID = c .session .GetState () .User .ID
781822 }
782823
783824 slog .Info ("searching for existing channel message" ,
@@ -838,8 +879,8 @@ func (c *Client) FindDMForPR(ctx context.Context, userID, prURL string) (channel
838879 }
839880
840881 var botID string
841- if c .session .State != nil && c .session .State .User != nil {
842- botID = c .session .State .User .ID
882+ if c .session .GetState () != nil && c .session .GetState () .User != nil {
883+ botID = c .session .GetState () .User .ID
843884 }
844885
845886 var messages []* discordgo.Message
0 commit comments