From 8ca42561ea16972fae092d355640b4774fa6283d Mon Sep 17 00:00:00 2001 From: happybell80 Date: Fri, 19 Sep 2025 19:01:54 +0900 Subject: [PATCH] =?UTF-8?q?Refactor:=20=EB=84=A4=EC=9D=B4=EB=B2=84?= =?UTF-8?q?=EC=9B=8D=EC=8A=A4=E2=86=92Slack=20=EC=97=B0=EB=8F=99=20?= =?UTF-8?q?=EB=AC=B8=EC=84=9C=EB=A5=BC=203=EA=B0=9C=EB=A1=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20=EB=B0=8F=20DB=20=EA=B8=B0=EB=B0=98=20=EC=9E=90?= =?UTF-8?q?=EB=8F=99=20Provider=20=EA=B0=90=EC=A7=80=20=EB=B0=A9=EC=8B=9D?= =?UTF-8?q?=20=EB=8F=84=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기본구성: DB 조회로 자동 provider 선택 (키워드 감지 대체) - 일일브리핑: 매일 09:00 중요 메일 요약 - 콜드메일: 스타트업 콜드메일 자동 필터링 - mailAddress null 문제 해결 상태 업데이트 --- ...erworks_mail_api_mailaddress_null_issue.md | 2 +- ..._naverworks_slack_01_base_configuration.md | 170 ++++++++++++++++++ ...0919_naverworks_slack_02_daily_briefing.md | 112 ++++++++++++ ...0919_naverworks_slack_03_cold_mail_list.md | 130 ++++++++++++++ 4 files changed, 413 insertions(+), 1 deletion(-) create mode 100644 troubleshooting/250919_naverworks_slack_01_base_configuration.md create mode 100644 troubleshooting/250919_naverworks_slack_02_daily_briefing.md create mode 100644 troubleshooting/250919_naverworks_slack_03_cold_mail_list.md diff --git a/troubleshooting/250918_naverworks_mail_api_mailaddress_null_issue.md b/troubleshooting/250918_naverworks_mail_api_mailaddress_null_issue.md index eb79023..779854e 100644 --- a/troubleshooting/250918_naverworks_mail_api_mailaddress_null_issue.md +++ b/troubleshooting/250918_naverworks_mail_api_mailaddress_null_issue.md @@ -3,7 +3,7 @@ ## 날짜: 2025-09-18 ## 작성자: Claude (51123 서버 관리자) ## 관련 서비스: auth-server, skill-naverworks (예정) -## 상태: 미해결 - 네이버웍스 지원팀 문의 진행 중 +## 상태: ✅ 해결됨 (2025-09-18 20:15) --- diff --git a/troubleshooting/250919_naverworks_slack_01_base_configuration.md b/troubleshooting/250919_naverworks_slack_01_base_configuration.md new file mode 100644 index 0000000..874fa54 --- /dev/null +++ b/troubleshooting/250919_naverworks_slack_01_base_configuration.md @@ -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 상태 코드로 문제 진단 용이 \ No newline at end of file diff --git a/troubleshooting/250919_naverworks_slack_02_daily_briefing.md b/troubleshooting/250919_naverworks_slack_02_daily_briefing.md new file mode 100644 index 0000000..7ec34bf --- /dev/null +++ b/troubleshooting/250919_naverworks_slack_02_daily_briefing.md @@ -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건 +━━━━━━━━━━━━━━━━━━━━━━━━━━━ +``` \ No newline at end of file diff --git a/troubleshooting/250919_naverworks_slack_03_cold_mail_list.md b/troubleshooting/250919_naverworks_slack_03_cold_mail_list.md new file mode 100644 index 0000000..bfbac69 --- /dev/null +++ b/troubleshooting/250919_naverworks_slack_03_cold_mail_list.md @@ -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개│ +└─────────────┴──────────┴─────────────────┴────────┘ +``` \ No newline at end of file