10 KiB
10 KiB
NAVER WORKS → Slack 연동 [1/3] 기본 구성
날짜: 2025-09-19
작성자: Claude (51123 서버 관리자)
관련 서비스: rb8001, skill-email, auth-server
상태: 기본 구조 구현 필요
관련 문서
1. 현재 구현 상태 (코드 분석 기준)
구현 완료
- 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()) 등록됨
- NAVER WORKS Mail API:
- ✅ 올바른 엔드포인트 확인:
/mail/mailfolders/{folderId}/children - ✅ mailAddress null 문제 해결 (API 사용에 영향 없음)
- ✅ 9,192개 메일 정상 조회 확인
- ✅ 올바른 엔드포인트 확인:
미구현/불일치
- rb8001: provider=naverworks 미지정 → 기본 Gmail만 사용
- skill-email:
/mail-summary엔드포인트 없음 (문서에만 제안) - 식별자: Slack ID → UUID 변환이 send에만 부분 적용
- 보안 위험: NaverWorksProvider.DEFAULT_USER_ID 하드코딩 존재
잘못된 전제 정정
- ❌ "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. 오케스트레이션 구조와 skill-slack 통합
3.1 rb8001 오케스트레이션 흐름
Slack 요청 → rb8001 (중앙 오케스트레이터)
├→ skill-email (메일 데이터 조회)
├→ 필터링/분석 (rb8001 내부)
├→ skill-slack (Slack 포맷팅)
└→ Slack 응답
rb8001의 역할:
- 사용자 의도 파악
- 스킬 조합 결정
- 데이터 가공 및 필터링
- 최종 응답 전송
3.2 skill-slack 현재 구조 및 추가 역할
실제 파일 구조 (포트 8502):
skill-slack/
├── app/
│ ├── main.py # FastAPI 앱, API 버전 설정
│ ├── api/
│ │ └── endpoints/
│ │ ├── messages.py # /messages/send, /messages/update
│ │ ├── summarize.py # /summarize
│ │ └── digest.py # /digest
│ ├── services/
│ │ ├── slack_service.py # SlackService 클래스
│ │ ├── message_formatter.py # 메시지 포맷 헬퍼
│ │ └── summarize_service.py # 요약 서비스
│ ├── models/
│ │ └── slack_models.py # BaseSkillRequest 등 Pydantic 모델
│ └── core/
│ └── config.py # Settings 설정
기존 엔드포인트 (모두 /api/v1 prefix):
| 엔드포인트 | 역할 | 현재 상태 | Request Body |
|---|---|---|---|
POST /api/v1/messages/send |
Slack 메시지 전송 | ✅ 구현됨 | BaseSkillRequest + message |
POST /api/v1/messages/update |
메시지 업데이트 | ✅ 구현됨 | BaseSkillRequest + ts + message |
POST /api/v1/summarize |
대화 요약 | ✅ 구현됨 | BaseSkillRequest + messages |
POST /api/v1/digest |
스레드 다이제스트 | ✅ 구현됨 | BaseSkillRequest + thread_ts |
BaseSkillRequest 구조:
class BaseSkillRequest(BaseModel):
team_id: str
user_id: str
channel_id: str
thread_ts: Optional[str] = None
추가 필요 엔드포인트:
| 엔드포인트 | 역할 | 입력 | 출력 |
|---|---|---|---|
POST /api/v1/format/mail-list |
메일 목록을 Slack 블록으로 변환 | BaseSkillRequest + mails | Block Kit JSON |
POST /api/v1/format/cold-mail |
콜드메일 테이블 포맷 생성 | BaseSkillRequest + cold_mails | Table Block |
POST /api/v1/format/briefing |
일일 브리핑 포맷 생성 | BaseSkillRequest + briefing_data | Briefing Block |
3.3 skill-email 파일별 역할 (최소 변경 원칙)
| 파일 경로 | 역할 | 구현 내용 | 예상 코드 줄 수 |
|---|---|---|---|
main.py |
앱 실행, 라우터 등록 | 기존 엔드포인트 유지, 새 라우터만 추가 | +5줄 추가 |
routers/naverworks_mail.py (신규) |
HTTP 요청 처리 | /cold-mail-list, /daily-briefing 엔드포인트 |
30-40줄 |
services/naverworks_mail_service.py (신규) |
비즈니스 로직 | 콜드메일 필터링, 브리핑 생성 로직 | 100-150줄 |
services/naverworks_provider.py |
NAVER WORKS API 연동 | 기존 파일 활용, 메서드만 추가 | +50줄 추가 |
repositories/mail_cache_repository.py (신규) |
DB CRUD 작업 | 메일 캐시 저장/조회 SQL | 50-60줄 |
models/mail_cache.py (신규) |
DB 테이블 정의 | SQLAlchemy ORM 모델 (mail_cache 테이블) | 15-20줄 |
schemas/naverworks_schemas.py (신규) |
API 입출력 형식 | Pydantic 모델 (Request/Response) | 30-40줄 |
core/slack_formatter.py (신규) |
Slack 포맷터 | 메일→Slack 블록 변환 | 50-70줄 |
3.4 데이터 계층 구분
| 계층 | 파일 종류 | 역할 | 비유 |
|---|---|---|---|
| Model | models/*.py |
DB 테이블 구조 정의 (SQLAlchemy ORM) | 창고 선반 설계도 (내부용) |
| Schema | schemas/*.py |
API 요청/응답 형식 (Pydantic) | 손님 주문서 양식 (외부용) |
| Repository | repositories/*.py |
DB 접근 로직 (CRUD) | 창고 관리 직원 |
| Database | db/session.py |
DB 연결 관리 | 창고 출입문 열쇠 |
데이터 흐름 예시
1. API 요청 → Schema (검증)
2. Service → Repository (DB 작업 요청)
3. Repository → Model (ORM으로 DB 테이블 접근)
4. Model → Database (실제 SQL 실행)
5. 결과 → Schema (응답 포맷) → API 응답
3.5 rb8001 파일별 역할
| 파일 경로 | 역할 | 구현 내용 |
|---|---|---|
app/main.py |
메시지 라우팅 | Slack 메시지 수신 및 처리 |
app/skills/email_integration.py |
이메일 스킬 통합 | NaverWorks 지원 추가 |
app/services/scheduler.py |
스케줄러 | 일일 브리핑 자동 실행 |
app/schemas/skill_schemas.py |
스킬 요청/응답 형식 | SkillRequest, SkillResponse |
3.6 auth-server 파일별 역할
| 파일 경로 | 역할 | 현재 상태 |
|---|---|---|
app/providers/naverworks.py |
OAuth 로그인 | ✅ 구현됨 |
app/providers/naverworks_passport.py |
Passport 시스템 | ✅ 구현됨 |
4. 기본 연동 테스트 시나리오
4.1 자동 Provider 감지 테스트 (skill-slack 포함)
- Slack: "@로빙 메일 확인"
- rb8001 흐름:
- DB 조회 (gmail_token, naverworks_token)
- provider 자동 결정
- skill-email 호출 → 메일 데이터 획득
- skill-slack
/format-mail-list→ Slack 블록 생성 - Slack 응답
4.2 명시적 Provider 지정
- Slack: "@로빙 네이버웍스 메일 확인"
- DB 조회 없이 바로 provider=naverworks 사용
- 오버라이드로 특정 provider 강제 지정
4.3 DB 조회 로직 구현
- rb8001/app/skills/email_integration.py에 detect_email_provider 메서드 추가
- gmail_token 테이블에서 is_equipped=true인 계정 확인
- naverworks_token 테이블에서 사용자 계정 확인
- 둘 다 있으면 "both", 하나만 있으면 해당 provider, 없으면 "none" 반환
5. 기본 구성 구현 체크리스트
5.1 rb8001 수정
app/skills/email_integration.py수정detect_email_provider()함수 추가 - DB 기반 자동 감지- get_messages()에 자동 provider 선택 로직
- send_email()에 자동 provider 선택 로직
- 둘 다 있을 때 선택 UI 구현
- DB 조회 로직 구현
- gmail_token 테이블 조회
- naverworks_token 테이블 조회
- 결과 기반 provider 자동 결정
- Slack ID → UUID 변환 일관성 확보
- get_uuid_from_slack() 활용 확대
- 모든 skill-email 호출에 UUID 사용
5.2 skill-slack 구현
- 새 엔드포인트 추가 (
/api/v1prefix 필수)- POST
/api/v1/format/mail-list- 기본 메일 목록 포맷 - POST
/api/v1/format/cold-mail- 콜드메일 테이블 포맷 - POST
/api/v1/format/briefing- 일일 브리핑 포맷
- POST
- BaseSkillRequest 상속 모델 구현
- MailListRequest(BaseSkillRequest)
- ColdMailRequest(BaseSkillRequest)
- BriefingRequest(BaseSkillRequest)
- Slack Block Kit Builder 구현
- Section blocks
- Divider blocks
- Context blocks
5.3 skill-email 수정
services/naverworks_provider.py수정- DEFAULT_USER_ID 하드코딩 제거
- account_id 없을 시 명확한 에러 처리
- 에러 응답 표준화
- 400: 잘못된 요청
- 422: 필수 정보 누락
6. 환경 설정 및 주의사항
6.1 환경 설정 확인
- skill-email .env 파일에 NAVER WORKS 관련 설정 확인
- rb8001에서 skill-email 호출 시 포트 8501 사용
- auth-server의 NAVER WORKS OAuth 설정 확인
6.2 보안 주의사항
- 계정 오매핑 방지: DEFAULT_USER_ID 제거로 잘못된 계정 접근 차단
- UUID 검증: 모든 사용자 식별자를 UUID로 표준화
- 에러 처리: 명확한 HTTP 상태 코드로 문제 진단 용이