8.7 KiB
8.7 KiB
NAVER WORKS → Slack 연동 [1/3] 기본 구성
날짜: 2025-09-19 (완료: 2025-09-10)
작성자: Claude (51123 서버 관리자) / happybell80
관련 서비스: rb8001, skill-email, skill-slack, auth-server, robeing-gateway
상태: ✅ 구현 완료 및 테스트 성공
관련 문서
1. 현재 구현 상태 (2025-01-09 확인)
구현 완료
- auth-server:
naverworks.py,naverworks_passport.py파일 존재- NAVER WORKS OAuth 환경변수 설정 (CLIENT_ID, CLIENT_SECRET, REDIRECT_URI, TENANT_ID)
- 토큰 갱신: POST
/auth/naverworks/passport/refresh동작
- skill-email (포트 8501):
services/naverworks_provider.pyNaverWorksProvider 클래스 구현- GET
/messages엔드포인트 (provider 파라미터 지원) - POST
/send엔드포인트 - registry.register("naverworks", NaverWorksProvider()) 등록됨
- skill-slack (포트 8502):
- POST
/api/v1/send토큰 파라미터 지원 (2025-01-09) - 멀티 워크스페이스 지원 가능
- POST
- NAVER WORKS Mail API:
- ✅ 올바른 엔드포인트 확인:
/mail/mailfolders/{folderId}/children - ✅ mailAddress null 문제 해결 (API 사용에 영향 없음)
- ✅ 9,192개 메일 정상 조회 확인
- ✅ 올바른 엔드포인트 확인:
미구현/문제점
- rb8001: provider 파라미터 없음, UUID 변환 누락 (list 경로)
- skill-slack: rb8001과 미연동 (직접 WebClient 사용)
- 24시간 필터: 어디에도 구현 안 됨
- 토큰 갱신: 자동 호출 없음 (수동 함수만 존재)
잘못된 전제 정정
- ❌ "skill-naverworks(8511) 구현 완료" → ✅ skill-email(8501) 멀티 프로바이더로 통합
- ❌ "Service Account 설정 완료" → ✅ 사용자 OAuth 토큰 기반 (SA는 Phase 3 계획)
- ❌ 별도 skill-naverworks 필요 → ✅ skill-email의 provider 파라미터로 처리
2. 기본 구성 구현 사항
2.1 rb8001 수정 - 자동 Provider 감지
app/skills/email_integration.py에 DB 기반 자동 분기 로직 추가- 사용자의 메일 계정을 DB에서 조회하여 자동 선택
- 분기 로직:
1. DB에서 user_id로 메일 계정 조회 2. Gmail만 있음 → provider=gmail 3. NaverWorks만 있음 → provider=naverworks 4. 둘 다 있음 → 사용자에게 선택 요청 5. 둘 다 없음 → 메일 계정 설정 안내 - 명시적 키워드("네이버웍스", "Gmail")는 오버라이드용
2.2 skill-email 수정 - 안전성 개선
- NaverWorksProvider.DEFAULT_USER_ID 제거
- account_id 누락 시 400/422 에러 반환
- 모든 요청에 UUID 검증 로직 추가
3. 정확한 구현 경로
3.1 전체 데이터 흐름 (토큰 갱신 포함)
시나리오: 슬랙에서 "네이버웍스 메일 확인" 메시지를 보내면 최근 24시간 이내 받은 메일 전체가 슬랙 채널에 표시
상세 흐름:
- 슬랙 "네이버웍스 메일 확인" → Gateway
- Gateway가 slack_user_mapping에서 UUID 조회 → X-User-Id 헤더
- Gateway가 slack_workspace에서 봇 토큰 조회 → X-Slack-Bot-Token 헤더
- Gateway가 X-Source: "slack" 헤더 추가
- Gateway → rb8001 (헤더 + 메시지)
- rb8001이 X-Source 확인 → slack 요청임을 인지
- rb8001 → skill-email:8501/messages?provider=naverworks&user_id={uuid}
- skill-email이 naverworks_token에서 액세스 토큰 조회
- 토큰 만료 체크 → 만료시 auth-server:8000/auth/naverworks/passport/refresh 호출
- auth-server가 naverworks_token 테이블 업데이트 → 새 토큰 반환
- NaverWorks API 호출 → 24시간 이내 메일 전체 반환
- rb8001이 메일 데이터를 슬랙 메시지 형식으로 포맷팅 (blocks, markdown)
- rb8001 → skill-slack:8502/api/v1/send (channel, text, blocks, token)
- skill-slack이 슬랙 API 형식에 맞게 최종 포맷팅
- skill-slack → 슬랙 채널에 메일 표시
Gateway → rb8001 전달 정보:
Headers:
X-User-Id: UUID (Slack user를 UUID로 변환)X-Slack-Bot-Token: 봇 토큰 (Gateway가 DB에서 조회)X-Source: "slack" (요청 출처 구분)X-Slack-Signature: Slack 서명X-Slack-Request-Timestamp: 타임스탬프
Body (원본 그대로):
{
"team": {"id": "T0925SXPS4D"},
"event": {
"user": "U0928DT3MDW",
"channel": "C07V9F3V21V",
"text": "네이버웍스 메일 확인"
}
}
프론트엔드 요청 경로:
Frontend → Gateway → rb8001 → skill-email → rb8001 → skill-slack → Slack
Gateway → rb8001 전달 정보:
- Headers:
X-User-Id,X-Source: "frontend" - Body:
{"text": "메시지", "user_id": "UUID", "context": {}}
3.2 현재 사용 가능한 엔드포인트
skill-email (포트 8501):
- GET
/messages?provider=naverworks&user_id={uuid}- 메일 목록 조회 - POST
/send- 메일 발송 (provider 필드 포함)
skill-slack (포트 8502):
- POST
/api/v1/send- Slack 메시지 전송- 필수: channel, text
- 선택: token, thread_ts, blocks
3.3 수정 필요 위치
rb8001/app/skills/email_integration.py:
- 262행: GET
/messages호출 시 provider 파라미터 누락 - 현재 코드:
params={"user_id": user_id, "limit": 5}(Gmail만 조회) - 필요한 수정: provider=naverworks 파라미터 추가
rb8001/app/router/slack_handler.py:
- 274행:
local_client.chat_postMessage()직접 호출 - 311행:
WebClient(token=custom_token)직접 생성 - skill-slack 사용 안 함
robeing-gateway/app/main.py:
- 553, 560, 611, 615행: X-User-Id, X-Slack-Bot-Token 헤더 설정
- X-Source 헤더 없음 (요청 출처 구분 불가)
4. 확인된 사실과 구현 체크리스트
코드 분석 결과 (2025-01-09)
- skill-slack: 8502 포트 엔드포인트 구현됨, rb8001은 직접 WebClient 사용 중 (미연동)
- provider 구분: 미구현, 기본 Gmail만 동작 (rb8001/app/skills/email_integration.py:260-266)
- 24시간 필터: 목록 API는 날짜 파라미터 미지원 → 클라이언트(receivedTime) 기준 필터 적용
- 토큰 갱신: NaverWorks는 auth-server 위임, 자동 호출 없음
- UUID 변환: list 경로에서 변환 없음 (263행 user_id는 입력 그대로 전달)
구현 완료 사항 (2025-09-10)
P0 (완료):
- ✅ skill-slack thread_ts 버그 수정 (messages.py:36-48)
- ✅ skill-slack API Key 인증 추가 (/send, /update)
P1 (완료):
- ✅ Gateway X-Source 헤더 추가 (main.py:552, 240)
- ✅ rb8001 provider 로직 구현 (email_integration.py:70-130)
- ✅ skill-email 24시간 로컬 필터(응답 후 receivedTime 비교)
- ✅ skill-email DEFAULT_USER_ID 제거 (31행 삭제)
- ✅ skill-email 401 에러 시 토큰 갱신 (194-210행)
P2 (완료):
- ✅ send_naverworks_to_slack() 함수 구현 (email_integration.py:433-524)
- ✅ slack_handler.py 키워드 연결 (213-228행)
테스트 결과
- ✅ "네이버웍스 메일 확인" 명령어 정상 작동
- ✅ 24시간 이내 메일 조회 성공
- ✅ 메일 없을 시 안내 메시지 표시
- ⚠️ 메일 있을 시 이중 전송 가능성 (send_naverworks_to_slack + slack_handler)
- 📝 skill-slack은 메일이 있을 때만 호출됨 (없으면 직접 응답)
5. 주요 파일 위치와 역할
rb8001 (포트 8001)
- app/skills/email_integration.py: Gmail 스킬 통합 (네이버웍스 추가 필요)
- app/router/slack_handler.py: Slack 이벤트 처리 (현재 직접 호출)
skill-email (포트 8501)
- services/naverworks_provider.py: 네이버웍스 Provider 구현
- 270행: refresh_token() 함수 존재 (auth-server의
/auth/naverworks/passport/refresh호출) - 150행: list_messages() - 토큰 만료 체크 없이 바로 사용
- 31행: DEFAULT_USER_ID 하드코딩 문제
- 270행: refresh_token() 함수 존재 (auth-server의
- main.py: 엔드포인트 정의
- 210행: GET
/messages- provider 파라미터로 gmail/naverworks 분기 - POST
/send
- 210행: GET
- services/gmail_service.py
- 60-72행: 토큰 자동 갱신 구현 (creds.expired 체크 후 refresh)
skill-slack (포트 8502)
- app/api/endpoints/messages.py: 메시지 전송 엔드포인트
- app/models/requests.py: SlackMessageRequest 모델 (token 필드 포함)
6. 결정 사항 (2025-01-09)
구현 결정
- Provider 선택: 키워드 우선 → DB 조회 → 둘 다 있으면 질문
- 24시간 필터: skill-email에서 응답 후 receivedTime 기준 클라이언트 필터 처리
- 토큰 갱신: 401 에러 후 재시도 (1회)
- UUID 변환: Gateway에서 모두 변환
- skill-slack 전환: 단계적 (새 기능부터)
- 메일 표시: 5개 요약 + "더보기" 버튼