# Slack 봇 메시지 403 에러 처리

## 발생 일시
2025-10-02 13:29 ~ 13:31

## 현상
robeing-gateway 로그에서 지속적인 403 Forbidden 에러 발생

### 에러 로그
```
app.services.slack_proxy - WARNING - No UUID found for Slack user U0935RJ60V6
app.routers.slack - ERROR - User not registered: team_id=T0925SXPS4D, slack_user_id=U0935RJ60V6
```

### 패턴
- **빈도**: 1-2분마다 반복 발생
- **HTTP 응답**: 403 Forbidden
- **영향**: 불필요한 에러 로그 생성, 리소스 낭비

## 원인 분석

### 문제의 핵심
`U0935RJ60V6`는 로빙(Robeing) 봇의 Slack User ID로, 봇이 메시지를 보낼 때마다 게이트웨이가 이를 일반 사용자 메시지로 처리하려고 시도

### 상세 분석
1. **현재 로직**
   - 모든 Slack 이벤트에 대해 UUID 매핑 요구
   - 봇 메시지도 사용자 등록 검증 시도
   - UUID가 없으면 403 반환

2. **정상 동작 vs 비정상 동작**
   - 정상: `U0925SXQFDK`(사용자) → UUID 변환 성공 → rb8001 전달 → 200 OK
   - 비정상: `U0935RJ60V6`(로빙) → UUID 찾기 실패 → 403 Forbidden

## 해결 방법 (2025-10-12 완료)

### 수정 파일
- robeing-gateway/app/settings.py:43 - ROBEING_SLACK_ID 환경변수 추가
- robeing-gateway/app/routers/slack.py:18,23,65-67 - 환경변수 사용

### 구현 내용
- UUID 검증 전에 로빙 메시지 필터링 추가
- bot_id, ROBEING_SLACK_ID, subtype 체크
- 하드코딩 제거: 환경변수 ROBEING_SLACK_ID 사용

### 결과
- ✅ 로빙 메시지 403 에러 해결
- ✅ 불필요한 에러 로그 제거
- ✅ 리소스 낭비 방지
- ✅ 하드코딩 제거 (FUNCTIONAL PROGRAMMING 원칙 준수)

## 관련 파일
- `/home/happybell/projects/ivada/robeing-gateway/app/routers/slack.py` (line 59-67)
- `/home/happybell/projects/ivada/DOCS/troubleshooting/250721_happybell80_로빙기억력문제및nginx포트추가.md` (3중 봇 필터링 참고)

---

# rb8001 EmotionState 객체 생성 에러

## 발생 일시
2025-10-02 13:29:52, 13:30:01 (KST)
- 서버: 51124
- 컨테이너: rb8001 (Up About an hour, healthy)
- 발생 빈도: 10월 1일 이후 2회

## 현상
- 입력: "로빙 하이"
- 응답: "죄송합니다. 요청을 처리할 수 없습니다."
- 연속 입력 "왜?"에도 동일한 에러 응답

## 에러 추적

### 1. 인사 패턴 미인식
- decision_engine.py의 GREETING 패턴: "안녕", "hello", "hi", "반가워"
- "로빙 하이"는 전체가 UNKNOWN으로 분류됨
- UNKNOWN 타입은 LLM 처리로 넘어감

### 2. EmotionState 생성자 불일치
**rb8001/app/core/emotion/base.py:16-23** (51124 서버 확인)
```python
class EmotionState(NamedTuple):
    basic_dist: List[float]  # 5개 기본정서 분포
    social_dist: List[float]  # 4개 사회기능 분포
    combined_dist: List[float]  # 9개 통합 분포
    entropy: float  # 엔트로피 값
    dominant: str  # 주요 감정
    mode: str  # 'basic', 'social', 'combined'
```

**에러 발생 위치 (4곳)**

**rb8001/app/llm/emotion_llm.py:35**
```python
emotion_state = EmotionState(
    emotions=result['probs'],  # 잘못된 필드명, 3개 인자만 전달
    dominant=result['top_label'],
    entropy=result['entropy']
)
```

**rb8001/app/llm/emotion_llm.py:67**
```python
except Exception as e:
    logger.error(f"감정 분석 실패: {e}")
    return EmotionState()  # 빈 생성자 호출 - 6개 인자 필요
```

**rb8001/app/llm/emotion_llm.py:80-83**
```python
emotion_state = EmotionState(
    emotions=user_emotion.get('probs', {}),  # 잘못된 필드명, 3개 인자만 전달
    dominant=user_emotion.get('top_label', 'neutral'),
    entropy=user_emotion.get('entropy', 1.0)
)
```

**rb8001/app/llm/emotion_llm.py:89**
```python
else:
    emotion_state = EmotionState()  # 빈 생성자 호출
```

### 3. 에러 발생 순서
1. "로빙 하이" → UNKNOWN 분류 (DecisionEngine)
2. LLM 처리 시도 (app.llm.llm_service)
3. EmotionState() 빈 생성자 호출 또는 3개 인자만 전달
4. TypeError: EmotionState.__new__() missing 6 required positional arguments: 'basic_dist', 'social_dist', 'combined_dist', 'entropy', 'dominant', and 'mode'
5. fallback_message 반환: "죄송합니다. 요청을 처리할 수 없습니다."

## 문제 파일
- `/home/happybell/projects/ivada/rb8001/app/llm/emotion_llm.py` (line 35, 67, 80-83, 89)
- `/home/happybell/projects/ivada/rb8001/app/core/emotion/base.py` (line 16-23)

## 해결 전략

### EmotionState 기본값 함수 추가
**rb8001/app/core/emotion/base.py**에 추가:
```python
def create_default_emotion_state() -> EmotionState:
    basic_dist = [0.2] * 5
    social_dist = [0.25] * 4
    combined_dist = [1.0/9] * 9
    return EmotionState(basic_dist, social_dist, combined_dist, 2.197, 'neutral', 'combined')
```

### emotion_llm.py 수정
- Line 67: `return create_default_emotion_state()`
- Line 89: `emotion_state = create_default_emotion_state()`
- Line 80-84: 올바른 필드명으로 재구성

### 인사 패턴 추가
**rb8001/app/brain/decision_engine.py:103-105**
```python
IntentType.GREETING: [
    r"안녕", r"hello", r"hi", r"반가워", r"하이", r"로빙.*하이"
]
```

## 추가 검토 사항 (2025-10-02 14:30)

### 수정 완료 항목
- ✅ create_default_emotion_state 함수 추가 및 __init__.py export
- ✅ emotion_llm.py 4곳 EmotionState 생성 수정 (6개 필수 인자)
- ✅ test_endpoint.py await 누락 수정 (line 132)
- ✅ test_endpoint.py emotions 속성 → basic_emotions로 변경 (line 137)
- ✅ 인사 패턴에 '하이', '로빙' 추가

### 잔여 이슈
1. **BASIC_EMOTIONS 불일치**: 환경변수 기본값 'disgust' vs 코드 'surprise' 매핑
2. **dominant 확률 계산**: 'neutral', 'happiness'가 ALL_EMOTIONS에 없음 (joy는 있음)
3. **이모지 사용**: format_emotion_info 함수 정의됨 (실제 호출 없어 안전)
4. **asyncio.new_event_loop()**: emotion_classifier.py:52에 있지만 predict_async만 사용하므로 안전