Refactor: 네이버웍스→Slack 연동 문서를 3개로 분리 및 DB 기반 자동 Provider 감지 방식 도입

- 기본구성: DB 조회로 자동 provider 선택 (키워드 감지 대체)
- 일일브리핑: 매일 09:00 중요 메일 요약
- 콜드메일: 스타트업 콜드메일 자동 필터링
- mailAddress null 문제 해결 상태 업데이트
This commit is contained in:
happybell80 2025-09-19 19:01:54 +09:00
parent fff4bb417d
commit 8ca42561ea
4 changed files with 413 additions and 1 deletions

View File

@ -3,7 +3,7 @@
## 날짜: 2025-09-18
## 작성자: Claude (51123 서버 관리자)
## 관련 서비스: auth-server, skill-naverworks (예정)
## 상태: 미해결 - 네이버웍스 지원팀 문의 진행 중
## 상태: ✅ 해결됨 (2025-09-18 20:15)
---

View File

@ -0,0 +1,170 @@
# NAVER WORKS → Slack 연동 [1/3] 기본 구성
## 날짜: 2025-09-19
## 작성자: Claude (51123 서버 관리자)
## 관련 서비스: rb8001, skill-email, auth-server
## 상태: 기본 구조 구현 필요
## 관련 문서
- [2/3 일일 브리핑](./250919_naverworks_slack_02_daily_briefing.md)
- [3/3 콜드메일 리스트업](./250919_naverworks_slack_03_cold_mail_list.md)
---
## 1. 현재 구현 상태
### 구현 완료
- **auth-server**:
- `naverworks.py`, `naverworks_passport.py` 파일 존재
- NAVER WORKS OAuth 환경변수 설정 (CLIENT_ID, CLIENT_SECRET, REDIRECT_URI, TENANT_ID)
- **skill-email (포트 8501)**:
- `services/naverworks_provider.py` NaverWorksProvider 클래스 구현
- 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만 사용
- rb8001에서 "네이버웍스" 키워드 감지 로직 없음
- Slack ID → UUID 변환이 일부만 적용 (send만, list는 미적용)
---
## 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. FastAPI 구조에 따른 파일 구성
### 3.1 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.2 데이터 계층 구분
| 계층 | 파일 종류 | 역할 | 비유 |
|------|-----------|------|------|
| **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.3 rb8001 파일별 역할
| 파일 경로 | 역할 | 구현 내용 |
|-----------|------|-----------|
| `app/main.py` | 메시지 라우팅 | Slack 메시지 수신 및 처리 |
| `app/skills/email_integration.py` | 이메일 스킬 통합 | NaverWorks 지원 추가 |
| `app/services/scheduler.py` | 스케줄러 | 일일 브리핑 자동 실행 |
| `app/schemas/skill_schemas.py` | 스킬 요청/응답 형식 | SkillRequest, SkillResponse |
### 3.4 auth-server 파일별 역할
| 파일 경로 | 역할 | 현재 상태 |
|-----------|------|-----------|
| `app/providers/naverworks.py` | OAuth 로그인 | ✅ 구현됨 |
| `app/providers/naverworks_passport.py` | Passport 시스템 | ✅ 구현됨 |
---
## 4. 기본 연동 테스트 시나리오
### 4.1 자동 Provider 감지 테스트
- Slack: "@로빙 메일 확인"
- rb8001이 DB 조회:
- Gmail만: 자동으로 Gmail 메일 표시
- NaverWorks만: 자동으로 NaverWorks 메일 표시
- 둘 다: "Gmail과 네이버웍스 중 어떤 메일을 확인할까요?"
### 4.2 명시적 Provider 지정
- Slack: "@로빙 네이버웍스 메일 확인"
- DB 조회 없이 바로 provider=naverworks 사용
- 오버라이드로 특정 provider 강제 지정
### 4.3 DB 조회 SQL
```sql
-- Gmail 계정 확인
SELECT * FROM gmail_token
WHERE user_id = ? AND is_equipped = true
-- NaverWorks 계정 확인
SELECT * FROM naverworks_token
WHERE user_id = ?
```
---
## 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-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 상태 코드로 문제 진단 용이

View File

@ -0,0 +1,112 @@
# NAVER WORKS → Slack 연동 [2/3] 일일 브리핑
## 날짜: 2025-09-19
## 작성자: Claude (51123 서버 관리자)
## 관련 서비스: rb8001, skill-email
## 상태: 미구현
## 관련 문서
- [1/3 기본 구성](./250919_naverworks_slack_01_base_configuration.md)
- [3/3 콜드메일 리스트업](./250919_naverworks_slack_03_cold_mail_list.md)
---
## 1. 일일 브리핑 개요
### 목적
회사 대표메일 중요사항을 매일 아침 자동으로 요약하여 Slack 전체 채널에 브리핑
### 핵심 기능
- 최근 24시간 메일 중 중요 메일 필터링
- AI 요약 생성
- 우선순위별 정렬
- Slack 전체 채널 자동 포스팅
---
## 2. 구현 방식
### 2.1 트리거 방식
- **스케줄러**: 매일 09:00 KST 자동 실행
- **위치**: rb8001의 app/services/scheduler.py
- **도구**: APScheduler
### 2.2 처리 흐름
1. 스케줄러가 09:00에 rb8001 트리거
2. rb8001이 skill-email `/daily-briefing` 호출
3. skill-email이 NAVER WORKS API로 24시간 메일 조회
4. 중요도 필터링 (긴급, 계약, 결제, 공지 키워드)
5. Gemini API로 요약 생성
6. Slack Block Kit 형식으로 변환
7. rb8001이 Slack 전체 채널에 포스팅
---
## 3. 구현 파일 구조
### skill-email 추가 파일
- `routers/naverworks_mail.py`: POST `/daily-briefing` 엔드포인트
- `services/naverworks_mail_service.py`: `generate_daily_briefing()` 메서드
- `schemas/naverworks_schemas.py`: BriefingRequest/Response 모델
### rb8001 추가 파일
- `app/services/scheduler.py`: APScheduler 설정
---
## 4. 구현 체크리스트
### 4.1 skill-email 구현
- [ ] POST `/daily-briefing` 엔드포인트
- [ ] 24시간 메일 조회 로직
- [ ] 중요도 필터링 알고리즘
- [ ] Gemini API 연동 (요약 생성)
- [ ] Slack Block Kit 포맷터
### 4.2 rb8001 구현
- [ ] APScheduler 설정 (09:00 KST)
- [ ] 스케줄 작업 함수 구현
- [ ] skill-email 호출 로직
- [ ] Slack 전체 채널 전송
---
## 5. 문제점 및 개선 방안
### 5.1 폴링 방식 문제
- **문제**: 9,192개 메일 조회 시 API Rate Limit 위험
- **개선**:
- 최근 24시간 메일만 조회 (limit 파라미터)
- 캐싱 적용 (중복 조회 방지)
### 5.2 인증 방식
- **문제**: 스케줄러는 사용자 로그인 없이 작동 필요
- **개선**: JWT 기반 서비스 계정 도입 권장
### 5.3 보안 우려
- **문제**: 메일 본문이 Gemini API로 전송
- **개선**:
- 민감정보 필터링
- 발신자/제목/키워드만 요약
- 상세 내용은 원본 메일 링크 제공
---
## 6. 예상 출력 형식
```
📅 일일 메일 브리핑 (2025-09-19)
━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔴 긴급 (2건)
• [계약] OO사 계약 검토 요청 - 김과장
• [결제] 월간 서버 비용 승인 필요 - 재무팀
🟡 중요 (3건)
• [공지] 9월 정기 점검 안내 - IT팀
• [미팅] 다음주 프로젝트 킥오프 - PM팀
• [요청] 마케팅 자료 검토 - 마케팅팀
🟢 일반 (5건)
• 기타 일반 메일 5건
━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

View File

@ -0,0 +1,130 @@
# NAVER WORKS → Slack 연동 [3/3] 콜드메일 리스트업
## 날짜: 2025-09-19
## 작성자: Claude (51123 서버 관리자)
## 관련 서비스: rb8001, skill-email
## 상태: 미구현
## 관련 문서
- [1/3 기본 구성](./250919_naverworks_slack_01_base_configuration.md)
- [2/3 일일 브리핑](./250919_naverworks_slack_02_daily_briefing.md)
---
## 1. 콜드메일 리스트업 개요
### 목적
스타트업 콜드메일을 자동으로 수집하여 Slack 리스트 형식으로 전달
### 핵심 기능
- 콜드메일 패턴 감지 (발신자 도메인, 제목 키워드)
- 구조화된 리스트 생성 (회사명, 담당자, 제안내용)
- 첨부파일 정보 표시
- Slack 지정 채널 자동 포스팅
---
## 2. 구현 방식
### 2.1 트리거 방식 (권장: 푸시 알림)
- **현재 계획**: 주기적 폴링
- **권장 변경**: NAVER WORKS 푸시 알림
- Developer Console에서 Webhook URL 등록
- 새 메일 수신 시 즉시 알림
- API 호출 최소화
### 2.2 처리 흐름
1. 새 메일 수신 이벤트 발생
2. skill-email `/cold-mail-list` 엔드포인트 호출
3. 콜드메일 패턴 매칭
4. 메일 정보 추출 및 구조화
5. Slack Block Kit 테이블 형식 변환
6. 지정 채널에 리스트 포스팅
---
## 3. 콜드메일 필터링 규칙
### 3.1 발신자 도메인 패턴
```python
COLD_MAIL_DOMAINS = [
"*.vc", # VC 도메인
"*capital.com", # 투자사
"*ventures.com", # 벤처 캐피털
"*startup.com" # 스타트업
]
```
### 3.2 제목 키워드
```python
COLD_MAIL_KEYWORDS = [
"투자", "제안", "협업", "파트너십",
"investment", "proposal", "partnership"
]
```
---
## 4. 구현 파일 구조
### skill-email 추가 파일
- `routers/naverworks_mail.py`: POST `/cold-mail-list` 엔드포인트
- `services/naverworks_mail_service.py`: `filter_cold_mails()` 메서드
- `models/mail_cache.py`: 콜드메일 캐시 테이블
- `repositories/mail_cache_repository.py`: 캐시 CRUD
- `schemas/naverworks_schemas.py`: ColdMailRequest/Response
---
## 5. 구현 체크리스트
### 5.1 skill-email 구현
- [ ] POST `/cold-mail-list` 엔드포인트
- [ ] 콜드메일 필터링 로직
- [ ] 패턴 매칭 알고리즘
- [ ] 메일 정보 구조화
- [ ] Slack 테이블 포맷터
### 5.2 rb8001 구현
- [ ] 콜드메일 키워드 감지
- [ ] skill-email 호출 로직
- [ ] Slack 채널 라우팅
### 5.3 푸시 알림 설정 (권장)
- [ ] NAVER WORKS Webhook URL 등록
- [ ] 이벤트 수신 엔드포인트 구현
- [ ] 실시간 처리 로직
---
## 6. 보안 및 개선사항
### 6.1 정보 최소화
- **문제**: 메일 본문 전체 노출 위험
- **해결**:
- 발신자, 제목, 회사명만 표시
- 첨부파일은 파일명/크기만
- 상세 내용은 원본 메일 링크
### 6.2 첨부파일 처리
- **문제**: 악성코드 위험
- **해결**:
- 직접 다운로드 금지
- "첨부파일 있음" 표시만
- 파일 형식과 크기 정보만 제공
---
## 7. 예상 출력 형식
```
📨 새로운 콜드메일 (3건)
━━━━━━━━━━━━━━━━━━━━━━━━━━━
┌─────────────┬──────────┬─────────────────┬────────┐
│ 회사명 │ 담당자 │ 제안 내용 │ 첨부 │
├─────────────┼──────────┼─────────────────┼────────┤
│ ABC Ventures│ 김대표 │ 시리즈A 투자제안│ PDF 2개│
│ XYZ Capital │ 이과장 │ 협업 미팅 요청 │ - │
│ 123 Startup │ 박매니저 │ 파트너십 제안 │ PPT 1개│
└─────────────┴──────────┴─────────────────┴────────┘
```