docs: Slack 이벤트 중복 및 슬래시 명령어 문제 트러블슈팅
- app_mention과 message 이벤트 중복 발생 원인 분석 - client_msg_id 기반 중복 방지 방안 제시 - Slack 기본 명령어 충돌 문제 정리
This commit is contained in:
parent
ab9464cc3f
commit
322dc1aecd
114
troubleshooting/250914_happybell80_Slack_이벤트_중복_및_슬래시_명령어_문제.md
Normal file
114
troubleshooting/250914_happybell80_Slack_이벤트_중복_및_슬래시_명령어_문제.md
Normal file
@ -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-*` 형식 권장
|
||||
Loading…
x
Reference in New Issue
Block a user