- gmail-token-slack-id-migration.md → troubleshooting/250825_gmail_token_slack_id_migration.md - postgresql_ssh_tunnel_guide.md → 300_architecture/database/250820_postgresql_ssh_tunnel_guide.md - robeing-monitor-integration.md → troubleshooting/250817_robeing_monitor_integration.md 날짜 prefix 추가 및 적절한 디렉토리로 이동
5.8 KiB
5.8 KiB
Gmail Token 시스템 Slack ID 직접 사용 마이그레이션
개요
2025년 8월 25일, Gmail 토큰 조회 시스템을 UUID 변환 방식에서 Slack ID 직접 사용 방식으로 마이그레이션했습니다.
문제 상황
기존 시스템의 문제점
-
UUID 불일치 문제
- auth-server:
uuid.uuid4()(랜덤 UUID) 사용 - skill-email/rb8001:
uuid.uuid5(namespace, slack_id)(네임스페이스 기반 UUID) 사용 - 결과: 동일한 사용자에 대해 서로 다른 UUID가 생성되어 토큰 조회 실패
- auth-server:
-
데이터베이스 스키마 변경
- 기존:
token_dataJSON 컬럼에 모든 토큰 정보 저장 - 변경: 개별 컬럼으로 분리 (
access_token,refresh_token,oauth_config,scopes,expiry) - 새 컬럼 추가:
slack_id(Slack 사용자 ID 직접 저장)
- 기존:
해결 방안
1. Slack ID 직접 사용
UUID 변환을 완전히 제거하고 Slack ID를 직접 사용하도록 변경
2. 변경된 파일
/home/heejae/skill-email/services/db_credentials_provider.py
제거된 코드:
import uuid
def __init__(self, connection_string: str):
# ...
self.uuid_namespace = uuid.NAMESPACE_DNS # 제거됨
def _convert_to_uuid(self, user_id: str) -> str: # 메서드 전체 제거
"""Slack user_id를 UUID로 변환"""
# ...
변경된 쿼리:
# 이전
user_uuid = self._convert_to_uuid(user_id)
cur.execute("""
SELECT ... FROM gmail_tokens
WHERE user_id = %s AND is_equipped = true
""", (user_uuid,))
# 현재
cur.execute("""
SELECT ... FROM gmail_tokens
WHERE slack_id = %s AND is_equipped = true
""", (user_id,)) # slack_id 직접 사용
/home/heejae/skill-email/services/gmail_service.py
추가된 자동 토큰 갱신:
def _get_gmail_service(self, user_id: str):
# ...
# 토큰이 만료되었거나 곧 만료될 경우 자동 refresh
if creds and creds.expired and creds.refresh_token:
logger.info(f"Refreshing expired token for user: {user_id}")
from google.auth.transport.requests import Request
creds.refresh(Request())
# 갱신된 토큰 저장
if hasattr(self.creds_provider, 'save_credentials'):
self.creds_provider.save_credentials(user_id, creds)
logger.info(f"Refreshed token saved for user: {user_id}")
401 에러 시 재시도 로직:
except HttpError as e:
if e.resp.status == 401:
logger.info(f"Got 401 error, refreshing token for user: {user_id}")
# 캐시 삭제 후 재시도
if user_id in self._service_cache:
del self._service_cache[user_id]
# 토큰 refresh 포함하여 다시 시도
3. 데이터베이스 스키마
gmail_tokens 테이블 구조:
CREATE TABLE gmail_tokens (
id UUID PRIMARY KEY,
slack_id VARCHAR(20) NOT NULL, -- Slack 사용자 ID 직접 저장
email VARCHAR(255),
access_token TEXT,
refresh_token TEXT,
oauth_config JSONB,
scopes JSONB,
expiry TIMESTAMP,
is_equipped BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 인덱스
CREATE INDEX idx_gmail_tokens_slack_id ON gmail_tokens(slack_id);
CREATE INDEX idx_gmail_tokens_equipped ON gmail_tokens(slack_id, is_equipped);
영향 받는 서비스
-
skill-email (포트 8501)
- db_credentials_provider.py 수정
- gmail_service.py 자동 refresh 로직 추가
-
rb8001 (포트 8001)
- dm_skill.py의 일일 요약 기능
- Gmail 이메일 조회 시 skill-email API 사용
-
auth-server (포트 8088)
- 변경 없음 (이미 slack_id 저장 중)
-
robeing-monitor (포트 9024)
- 이미 수정 완료 (새 컬럼 구조 읽기)
테스트 및 검증
1. 이메일 조회 테스트
# 개별 사용자 이메일 조회
curl -X GET "http://localhost:8501/messages?user_id=U091UNVE41M&limit=5&query=category:primary"
2. 일일 요약 DM 테스트
# Cron API 호출로 전체 사용자에게 DM 전송
curl -X POST "http://localhost:8001/api/cron/daily-summary" \
-H "Authorization: Bearer cron-secret-2024" \
-H "Content-Type: application/json"
3. 토큰 자동 갱신 확인
# skill-email 로그에서 자동 refresh 확인
docker logs skill-email | grep "Refreshing"
주요 개선 사항
-
UUID 불일치 문제 해결
- 모든 서비스가 동일한 식별자(slack_id) 사용
- UUID 변환 과정 제거로 오류 가능성 감소
-
자동 토큰 갱신
- 만료된 토큰 자동 감지 및 갱신
- 401 에러 시 자동 재시도
- 갱신된 토큰 DB 자동 저장
-
코드 단순화
- UUID 변환 로직 제거
- 직관적인 slack_id 사용
- 디버깅 용이성 향상
배포 절차
# 1. skill-email 재빌드 및 재시작
cd /home/heejae/skill-email
docker compose down && docker compose up -d --build
# 2. 로그 확인
docker logs skill-email --tail 50
# 3. 헬스체크
curl http://localhost:8501/health
트러블슈팅
SSL SYSCALL error: EOF detected
- 원인: PostgreSQL 연결 풀 타임아웃
- 해결: 재시도 시 정상 작동 (연결 풀 자동 재생성)
토큰 조회 실패
- 확인사항:
slack_id컬럼에 올바른 Slack 사용자 ID 저장 여부is_equipped = true설정 여부- SSH 터널 연결 상태 (포트 5433)
자동 갱신 실패
- 확인사항:
refresh_token존재 여부- Google OAuth 클라이언트 ID/Secret 설정
- 네트워크 연결 상태
참고 사항
- SSH 터널:
localhost:5433 → 124.55.18.179:5432 - 데이터베이스:
main_db - 환경 변수:
/home/heejae/skill-email/.env - Docker 네트워크:
network_mode: host