@@ -4,26 +4,31 @@ import type { Bot } from '@slack/web-api/dist/types/response/BotsInfoResponse.js
44import type { Member } from '@slack/web-api/dist/types/response/UsersListResponse.js'
55import type { User } from '@slack/web-api/dist/types/response/UsersLookupByEmailResponse.js'
66
7+ import { debug } from '@actions/core'
78import { getBatches } from '@krauters/utils'
89import { WebClient } from '@slack/web-api'
910
10- import { type GetUser , SlackAppUrl , type SlackConfig } from './structures.js'
11+ import { type GetUser , SlackAppUrl , type SlackConfig , type UserMapping } from './structures.js'
12+ import { createUserMatchers , logFailedMatches , type MatchParams } from './user-matchers.js'
1113
1214export class SlackClient {
1315 public bot ?: Bot
1416 private channels : string [ ]
1517 private client : WebClient
18+ private userMappings : UserMapping [ ]
1619 private users : undefined | User [ ]
1720
1821 /**
1922 * Slack client for interacting with the Slack API.
2023 *
2124 * @param token Slack token.
2225 * @param channels Slack channel IDs for posting messages in.
26+ * @param userMappings User mappings for the Slack client.
2327 */
24- constructor ( { channels, token } : SlackConfig ) {
28+ constructor ( { channels, token, userMappings = [ ] } : SlackConfig ) {
2529 this . client = new WebClient ( token )
2630 this . channels = channels
31+ this . userMappings = userMappings
2732 }
2833
2934 /**
@@ -101,59 +106,35 @@ export class SlackClient {
101106 * @param [botId] The botId for the bot to find.
102107 */
103108 async getUser ( { email, userId, username } : GetUser ) : Promise < Member | undefined > {
104- console . log ( `Getting Slack UserId for email [${ email } ], username [${ username } ], and userId [${ userId } ]...` )
109+ debug ( `Getting Slack UserId for email [${ email } ], username [${ username } ], and userId [${ userId } ]...` )
105110
106111 const users = this . users ?? ( await this . getAllusers ( ) )
112+ const matchParams : MatchParams = { email, userId, userMappings : this . userMappings , username }
113+ const matchers = createUserMatchers ( matchParams )
107114
108- // Define matching functions for better readability and extensibility
109- const matchById = ( user : Member ) => userId && user . id === userId
110- const matchByEmail = ( user : Member ) => email && user . profile ?. email === email
111- const matchByEmailContainsUsername = ( user : Member ) =>
112- username && String ( user . profile ?. email ?? '' ) . includes ( username )
113- const matchByDisplayName = ( user : Member ) => username && user . profile ?. display_name === username
114- const matchByRealName = ( user : Member ) => username && user . profile ?. real_name === username
115-
116- const user = users . find ( ( user : Member ) => {
117- const idMatch = matchById ( user )
118- const emailMatch = matchByEmail ( user )
119- const emailContainsUsernameMatch = matchByEmailContainsUsername ( user )
120- const displayNameMatch = matchByDisplayName ( user )
121- const realNameMatch = matchByRealName ( user )
122-
123- // Log the first match attempt that succeeds for debugging
124- if ( idMatch && userId ) console . log ( `Match found by userId [${ userId } ] with Slack userId [${ user . id } ]` )
125- else if ( emailMatch && email )
126- console . log ( `Match found by email [${ email } ] with Slack email [${ user . profile ?. email } ]` )
127- else if ( emailContainsUsernameMatch && username )
128- console . log ( `Match found by username [${ username } ] contained in Slack email [${ user . profile ?. email } ]` )
129- else if ( displayNameMatch && username )
130- console . log (
131- `Match found by username [${ username } ] matching Slack display_name [${ user . profile ?. display_name } ]` ,
132- )
133- else if ( realNameMatch && username )
134- console . log (
135- `Match found by username [${ username } ] matching Slack real_name [${ user . profile ?. real_name } ]` ,
136- )
115+ // Find the first user that matches any of our criteria
116+ const matchedUser = users . find ( ( slackUser ) => {
117+ // Find a matching criteria for this Slack user, if any
118+ const matchedCriteria = matchers . find ( ( criteria ) => criteria . check ( slackUser ) )
119+
120+ // If we found a match, log it
121+ if ( matchedCriteria ) {
122+ matchedCriteria . log ( slackUser )
137123
138- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
139- return idMatch || emailMatch || emailContainsUsernameMatch || displayNameMatch || realNameMatch
124+ return true
125+ }
126+
127+ return false
140128 } )
141129
142- if ( user ) {
143- console . log ( `User found with userId [${ user . id } ]` )
130+ if ( matchedUser ) {
131+ debug ( `User found with userId [${ matchedUser . id } ]` )
144132
145- return user
133+ return matchedUser
146134 }
147135
148- console . log ( `No user match found after checking against [${ users . length } ] users` )
149- if ( userId ) console . log ( `Tried to match userId [${ userId } ] against Slack user.id fields` )
150- if ( email ) console . log ( `Tried to match email [${ email } ] against Slack user.profile.email fields` )
151- if ( username )
152- console . log (
153- `Tried to match username [${ username } ] against Slack user.profile.email (contains), display_name and real_name fields` ,
154- )
155-
156- console . log ( `Since no Slack user match found, unable to @mention user or use their profile image` )
136+ // No match found, log the failure
137+ logFailedMatches ( matchParams , users . length )
157138 }
158139
159140 /**
0 commit comments