( slackUserId: string )
| 259 | * Persists to database for future lookups. |
| 260 | */ |
| 261 | export async function resolveSlackUserDisplayName( |
| 262 | slackUserId: string |
| 263 | ): Promise<ResolvedSlackUser | null> { |
| 264 | const db = getSlackDb(); |
| 265 | |
| 266 | // Check database first |
| 267 | const existing = await db.getBySlackUserId(slackUserId); |
| 268 | if (existing) { |
| 269 | return { |
| 270 | slack_user_id: existing.slack_user_id, |
| 271 | display_name: existing.slack_display_name || existing.slack_real_name, |
| 272 | email: existing.slack_email, |
| 273 | }; |
| 274 | } |
| 275 | |
| 276 | // Fetch from Slack API and persist |
| 277 | try { |
| 278 | const slackUser = await getSlackUser(slackUserId); |
| 279 | if (!slackUser) { |
| 280 | return null; |
| 281 | } |
| 282 | |
| 283 | const displayName = slackUser.profile?.display_name || |
| 284 | slackUser.profile?.real_name || |
| 285 | slackUser.real_name || |
| 286 | null; |
| 287 | const email = slackUser.profile?.email || null; |
| 288 | |
| 289 | // Persist for future requests |
| 290 | await db.upsertSlackUser({ |
| 291 | slack_user_id: slackUserId, |
| 292 | slack_email: email, |
| 293 | slack_display_name: slackUser.profile?.display_name || null, |
| 294 | slack_real_name: slackUser.profile?.real_name || slackUser.real_name || null, |
| 295 | slack_is_bot: slackUser.is_bot, |
| 296 | slack_is_deleted: slackUser.deleted, |
| 297 | }); |
| 298 | |
| 299 | logger.debug({ slackUserId, displayName }, 'Resolved and persisted Slack user from API'); |
| 300 | |
| 301 | return { |
| 302 | slack_user_id: slackUserId, |
| 303 | display_name: displayName, |
| 304 | email: email, |
| 305 | }; |
| 306 | } catch (error) { |
| 307 | logger.debug({ slackUserId, error }, 'Failed to resolve Slack user'); |
| 308 | return null; |
| 309 | } |
| 310 | } |
| 311 | |
| 312 | /** |
| 313 | * Resolve multiple Slack user IDs to display names with concurrency limiting. |
no test coverage detected