DOCS/journey/troubleshooting/250820_happybell80_Gmail아이템연동문제해결.md
Claude-51124 22557e7132 docs: 오래된 트러블슈팅 아카이브 및 구조 정리
- 7-8월 초기 구축 문서 12개를 _archive/troubleshooting/2025_07-08_initial_setup/로 이동
- book/300_architecture/390_human_in_the_loop_intent_learning.md를 journey/research/intent_classification/로 이동 (개발 여정 문서)
- 빈 폴더 제거 (journey/assets/*)
2025-11-17 14:06:05 +09:00

190 lines
4.7 KiB
Markdown

# Gmail 아이템 연동 문제 해결
## 작성일: 2025-08-20
## 작성자: happybell80
## 관련 서비스: rb10508_micro, robeing-monitor, skill-email
---
## 오전 10시 40분
### Gmail 아이템 확인 실패 문제
#### 문제 상황
- rb10508_micro에서 Gmail 아이템 장착 여부를 확인할 수 없음
- "Gmail을 먼저 연결해주세요!" 메시지만 반복 출력
- 실제로는 Gmail 아이템이 정상적으로 장착된 상태
#### 원인 분석
1. **포트 불일치**
- rb10508_micro의 growth.py: `http://localhost:8090` 호출
- robeing-monitor 실제 포트: 9024
- 연결 실패로 인해 아이템 미장착으로 판단
#### 해결 방법
1. growth.py에서 포트 수정 (8090 → 9024)
2. 환경변수로 관리하도록 개선
```python
# app/config.py에 추가
MONITOR_SERVICE_URL: str = "http://localhost:9024"
# growth.py 수정
response = await client.get(
f"{settings.MONITOR_SERVICE_URL}/api/items/{item_type}",
params={"user_id": user_id}
)
```
3. docker-compose.yml에 환경변수 추가
```yaml
- MONITOR_SERVICE_URL=http://localhost:9024
```
---
## 오전 11시 00분
### robeing-monitor API 인증 방식 불일치
#### 문제 상황
- 포트 수정 후에도 401 에러 발생
- "User ID required" 에러 메시지
#### 원인 분석
1. **API 인증 방식 차이**
- rb10508_micro: user_id를 쿼리 파라미터로 전송
- robeing-monitor: X-User-Id 헤더 요구
2. **테스트 결과**
```bash
# 실패 (쿼리 파라미터)
curl "http://localhost:9024/api/items/gmail?user_id=xxx"
{"detail":"User ID required"}
# 성공 (헤더)
curl -H "X-User-Id: xxx" "http://localhost:9024/api/items/gmail"
{"equipped":{...}, "available":[]}
```
#### 해결 방법
1. growth.py의 API 호출 방식 변경
```python
# 기존 (쿼리 파라미터)
response = await client.get(
f"{settings.MONITOR_SERVICE_URL}/api/items/{item_type}",
params={"user_id": user_id}
)
# 수정 (헤더 사용)
response = await client.get(
f"{settings.MONITOR_SERVICE_URL}/api/items/{item_type}",
headers={"X-User-Id": user_id}
)
```
2. 응답 형식 변경에 따른 파싱 로직 수정
```python
# 기존 (배열 형식 가정)
items = response.json()
equipped = any(item.get('is_equipped') for item in items)
# 수정 (객체 형식 처리)
data = response.json()
equipped_item = data.get('equipped')
equipped = equipped_item is not None and equipped_item.get('is_equipped', False)
```
3. capabilities 처리 로직 개선
```python
# capabilities가 딕셔너리인 경우 처리
capabilities = equipped_item.get('capabilities', {})
if isinstance(capabilities, dict):
capabilities_list = [k for k, v in capabilities.items() if v]
else:
capabilities_list = capabilities
```
---
## 최종 결과
### ✅ 완료된 작업
1. **robeing-monitor 포트 수정**
- 8090 → 9024로 변경
- 환경변수 MONITOR_SERVICE_URL 추가
2. **API 인증 방식 통일**
- 쿼리 파라미터 → X-User-Id 헤더
- check_item_equipped, get_item_capabilities 함수 수정
3. **응답 파싱 로직 개선**
- items 배열 → {equipped, available} 구조
- capabilities 딕셔너리 처리 추가
### 📊 테스트 결과
- Gmail 아이템 장착 확인: ✅ 성공
- 권한 인식 (send, read, modify): ✅ 성공
- skill-email 서비스 호출: ✅ 성공
- 응답 메시지 변화:
- 이전: "Gmail을 먼저 연결해주세요!"
- 현재: "이메일 처리를 완료했습니다."
### 🔄 시스템 흐름
```
사용자 요청
rb10508_micro
growth.py: check_item_equipped()
↓ (X-User-Id 헤더)
robeing-monitor (포트 9024)
Gmail 아이템 확인
skill-email 호출 (포트 8501)
이메일 처리 완료
```
---
## 교훈
### 1. API 통신 시 인증 방식 확인 필수
- 쿼리 파라미터 vs 헤더 방식 차이
- API 문서나 실제 구현 코드 확인 필요
- curl 테스트로 사전 검증
### 2. 포트 설정은 환경변수로 관리
- 하드코딩 방지
- 환경별 유연한 설정 가능
- docker-compose.yml과 config.py 동기화
### 3. API 응답 형식 변경 대응
- 배열 vs 객체 구조 차이 주의
- 타입 체크를 통한 안전한 처리
- 로그를 통한 디버깅 활용
### 4. 서비스 간 통신 흐름 파악
- 포트 매핑 문서화 필요
- 인증 방식 표준화
- 응답 형식 일관성 유지
### 5. 단계별 테스트의 중요성
- curl로 직접 API 테스트
- 로그 확인으로 문제 지점 파악
- 점진적 문제 해결
---
## 관련 커밋
- rb10508_micro: `d1d9b2c` - robeing-monitor 포트 수정 및 환경변수화
- rb10508_micro: `d1ff710` - API 인증 방식 변경 (쿼리 파라미터 → 헤더)
---
**문서 끝**