# Slack User ID → 이름 매핑 문제 해결 ## 문제점 rb8001에서 Slack 사용자 ID (예: U0925SXQFDK)를 실제 이름으로 변환하지 못함 ## 현재 상태 1. **메모리 검색**: ✅ 정상 작동 - ChromaDB에 22개 메모리 저장됨 - search_memories() 함수 정상 작동 - 과거 대화 검색 가능 2. **사용자 이름 매핑**: ❌ 미구현 - slack_user_mapping 테이블 없음 - Slack API를 통한 사용자 정보 조회 미구현 ## 해결 방안 ### 1. slack_user_mapping 테이블 생성 ```sql CREATE TABLE slack_user_mapping ( id SERIAL PRIMARY KEY, slack_user_id VARCHAR(50) UNIQUE NOT NULL, user_name VARCHAR(100), display_name VARCHAR(100), real_name VARCHAR(100), email VARCHAR(100), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); ``` ### 2. Slack API로 사용자 정보 가져오기 ```python from slack_sdk import WebClient class SlackUserService: def __init__(self, slack_token): self.client = WebClient(token=slack_token) async def get_user_info(self, user_id: str): """Slack API로 사용자 정보 조회""" try: response = self.client.users_info(user=user_id) if response["ok"]: user = response["user"] return { "slack_user_id": user_id, "user_name": user.get("name"), "display_name": user["profile"].get("display_name"), "real_name": user["profile"].get("real_name"), "email": user["profile"].get("email") } except Exception as e: logger.error(f"Failed to get user info: {e}") return None ``` ### 3. 캐싱 전략 ```python class UserNameCache: def __init__(self): self.cache = {} # {user_id: user_info} self.db = StateServiceClient() async def get_user_name(self, user_id: str) -> str: # 1. 캐시 확인 if user_id in self.cache: return self.cache[user_id]["display_name"] # 2. DB 확인 user_info = await self.db.get_user_mapping(user_id) if user_info: self.cache[user_id] = user_info return user_info["display_name"] # 3. Slack API 호출 slack_service = SlackUserService(settings.SLACK_BOT_TOKEN) user_info = await slack_service.get_user_info(user_id) if user_info: # DB에 저장 await self.db.save_user_mapping(user_info) self.cache[user_id] = user_info return user_info["display_name"] return user_id # 실패 시 ID 반환 ``` ### 4. 메시지 처리 시 이름 변환 ```python # slack_handler.py async def handle_message(event): user_id = event.get("user") # 사용자 이름 가져오기 user_name = await user_name_cache.get_user_name(user_id) # 메시지 처리 message = event.get("text") logger.info(f"Message from {user_name} ({user_id}): {message}") # 메모리 저장 시 이름 포함 await memory_manager.add_memory( content=f"{user_name}: {message}", metadata={ "user_id": user_id, "user_name": user_name, "channel_id": channel_id } ) ``` ## 구현 우선순위 1. **Phase 1**: 인메모리 캐시만 구현 - Slack API로 실시간 조회 - 메모리에 캐싱 2. **Phase 2**: DB 저장 추가 - PostgreSQL에 slack_user_mapping 테이블 생성 - 조회한 정보 영구 저장 3. **Phase 3**: 배치 업데이트 - 주기적으로 사용자 정보 갱신 - 변경사항 감지 ## 테스트 시나리오 ```python # 1. 새로운 사용자 메시지 assert get_user_name("U0925SXQFDK") == "희재" # 2. 캐시된 사용자 assert get_user_name("U0925SXQFDK") == "희재" # API 호출 없음 # 3. 알 수 없는 사용자 assert get_user_name("UNKNOWN") == "UNKNOWN" ``` ## 참고 사항 - Slack API rate limit: 1분당 50회 - users.info API는 user:read 스코프 필요 - 사용자 정보는 변경될 수 있으므로 주기적 갱신 필요