diff --git a/troubleshooting/250914_happybell80_Slack_이벤트_중복_및_슬래시_명령어_문제.md b/troubleshooting/250914_happybell80_Slack_이벤트_중복_및_슬래시_명령어_문제.md new file mode 100644 index 0000000..ff285cc --- /dev/null +++ b/troubleshooting/250914_happybell80_Slack_이벤트_중복_및_슬래시_명령어_문제.md @@ -0,0 +1,114 @@ +# 트러블슈팅: Slack 이벤트 중복 및 슬래시 명령어 처리 문제 + +## 발생 시간 +- 2025년 9월 14일 14:15 + +## 문제 상황 + +### 1. 중복 응답 문제 +`@Ro-being /search 에이전트 acp` 입력 시 동일한 응답이 2번 전송됨 + +### 2. 로그 분석 +``` +14:15:52 - app_mention 이벤트 (Event ID: Ev09EPV4FU6T) +14:15:53 - message 이벤트 (Event ID: Ev09EPV4GB1V) +14:15:57 - 첫 번째 응답 전송 +14:15:58 - 두 번째 응답 전송 +``` + +## 원인 분석 + +### 1. Slack Event Subscriptions 설정 +``` +Subscribe to bot events: +✅ app_mention - 멘션 감지용 +✅ message.channels - 채널의 모든 메시지 +✅ message.groups - 비공개 채널 메시지 +✅ message.im - DM 메시지 +✅ message.mpim - 그룹 DM 메시지 +``` + +### 2. 이벤트 발생 패턴 +- **멘션 포함 메시지**: `app_mention` + `message.channels` 동시 발생 +- **일반 메시지**: `message.channels`만 발생 +- **DM**: `message.im`만 발생 +- **쓰레드**: `message` 이벤트에 `thread_ts` 포함 + +### 3. 현재 처리 로직 문제 +```python +# slack_handler.py:212 +if event_type == "app_mention" or (event_type == "message" and is_dm) or is_thread_message: + # 모든 조건에서 처리 → 중복 발생 +``` + +## 슬래시 명령어 문제 + +### 1. Slack 기본 명령어 충돌 +- `/search`: Slack 내장 검색 기능과 충돌 +- `/help`: Slack 도움말과 충돌 +- 사용자가 `/search` 입력 시 Slack이 가로챔 + +### 2. 현재 상황별 처리 +``` +채널: +- @robeing 필수 (app_mention만 처리) +- /search 단독 사용 불가 + +DM: +- 멘션 불필요 (message.im 처리) +- /search 사용 가능 + +쓰레드: +- 멘션 불필요 (thread_ts 있으면 처리) +- /search 사용 가능 +``` + +## 해결 방안 + +### 1. 중복 방지 (즉시 적용 가능) +```python +# slack_handler.py에 추가 +processed_messages = set() # 또는 Redis 캐시 + +async def handle_slack_events(request: Request): + # ... + client_msg_id = event.get("client_msg_id") + + # 중복 체크 + if client_msg_id and client_msg_id in processed_messages: + return JSONResponse({"status": "ok"}) + + if client_msg_id: + processed_messages.add(client_msg_id) + # 5분 후 제거 (메모리 관리) + asyncio.create_task(remove_after_delay(client_msg_id, 300)) +``` + +### 2. 이벤트 우선순위 정리 +```python +# 개선된 로직 +is_mention = event_type == "app_mention" +is_dm = event.get("channel_type") == "im" +is_thread = event.get("thread_ts") is not None + +# 우선순위: app_mention > thread > dm +if is_mention: + # 멘션은 항상 처리, 단 client_msg_id 중복 체크 + if not is_duplicate(event): + process_message() +elif is_thread and event_type == "message": + # 쓰레드 메시지 처리 + process_message() +elif is_dm and event_type == "message": + # DM 처리 + process_message() +``` + +### 3. 자연어 명령어 지원 +- IntentAnalyzer 활성화로 "검색해줘" → `/search` 변환 +- 슬래시 명령어 대신 자연어 사용 유도 + +## 교훈 +1. **Event Subscriptions 이해**: 하나의 메시지가 여러 이벤트 생성 가능 +2. **중복 처리 필수**: client_msg_id 또는 timestamp로 중복 방지 +3. **Slack 기본 명령어 회피**: 커스텀 명령어는 `/rb-*` 형식 권장 \ No newline at end of file