# NAVER WORKS → Slack 연동 [2/3] 일일 브리핑 ## 날짜: 2025-09-19 (구현: 2025-09-23) ## 작성자: Claude / happybell80 ## 관련 서비스: rb8001, skill-email, skill-slack ## 상태: 구현 완료, 테스트 진행 중 --- ## 1. 일일 브리핑 개요 ### 목적 회사 대표메일 중요사항을 매일 아침 자동으로 요약하여 Slack 지정 채널에 브리핑 ### 핵심 기능 - 최근 24시간 메일 전체 요약 (10개 제한 제거) - AI 요약 생성 - 우선순위별 정렬 - Slack 지정 채널 자동 포스팅 --- ## 2. 구현 방식 ### 2.1 트리거 방식 - 매일 09:00 KST 자동 실행 - APScheduler 사용 (mon-fri 형식 권장) ### 2.2 처리 흐름 1. 09:00 스케줄러 트리거 2. DB에서 info@company-x.partners 계정 UUID 조회 3. skill-email `/messages` 호출 (provider=naverworks), 응답을 24시간(receivedTime) 기준 클라이언트 필터 4. 중요 메일 필터링 (긴급/계약/결제/공지) 5. Gemini 요약 생성 6. SlackFormatter.briefing()으로 포맷팅 7. skill-slack `/api/v1/send`로 채널 전송 (C09C98KK2TT) --- ## 3. 구현 파일 구조 ### 첫 구현 (최소) - **app/scheduler/jobs/naverworks_briefing.py**: register(scheduler) 함수와 로깅 래퍼 - **app/skills/naverworks_briefing.py**: 실제 브리핑 로직 - **main.py**: 2줄 추가 (import + register 호출) ### 나중 확장 - **app/formatters/slack_formatter.py**: 다른 스킬과 공유 시 - **app/scheduler/registry.py**: 스케줄 2개 이상일 때 --- ## 4. 구현 체크리스트 ### 4.1 최소 구현 - [ ] app/scheduler/jobs/ 디렉토리 생성 - [ ] naverworks_briefing.py 파일 (등록 + 래퍼) - [ ] main.py 2줄 추가 ### 4.2 브리핑 로직 - [ ] app/skills/naverworks_briefing.py 생성 - [ ] register() 함수: 환경변수 읽기, 스케줄 등록 - [ ] 래퍼 함수: 로그 추가 ("Running job" 이슈 해결) - [ ] DB 조회: info@company-x.partners UUID - [ ] 중요 메일 필터: 긴급/계약/결제/공지 - [ ] 통합: skill-email, Gemini, skill-slack --- ## 5. 구현 원칙 - **최소 변경**: main.py 2줄만, 기존 코드 유지 - **단순 구조**: register(scheduler) 하나, 환경변수는 함수 내부 - **로그 해결**: 래퍼 함수로 "Running job" 추가 - **점진 확장**: 작동 확인 후 registry, formatter 추가 ## 6. 구현 준비도 (90%) ### 확인된 사항 - **skill-email**: NaverWorksProvider 구현 완료, 토큰 갱신 로직 존재 - **skill-slack**: /api/v1/send 엔드포인트 구현 완료 (API 키 인증 없음) - **DB 접근**: DATABASE_URL 환경변수, asyncpg 사용 - **DB 데이터**: naverworks_token 테이블에 user_id, account_id 저장됨 - **NAVER WORKS API**: /mail/mailfolders/0/children 엔드포인트 확인 - **24시간 필터**: 목록 API는 날짜 파라미터 미지원 → 클라이언트(receivedTime) 기준 필터 필요 - **LLM 서비스**: process_request() 메서드, model="gemini-2.5-flash-lite", 필수 필드: message, user_id, robeing_id - **skill-slack**: X-API-Key 헤더로 SERVICE_API_KEY 필요 ### 필요 환경변수 (서버 설정) - NAVERWORKS_BRIEFING_ENABLED=true - NAVERWORKS_BRIEFING_CHANNEL_ID=C09C98KK2TT # _ID 붙여야 함! - NAVERWORKS_BRIEFING_SCHEDULE="0 9 * * mon-fri" # 1-5 아님! - COMPANYX_SLACK_BOT_TOKEN (Company-X 봇 토큰) - SERVICE_API_KEY (skill-slack 인증용) ## 7. 참고 - [DB 기반 스케줄러 관리](./250919_naverworks_slack_04_db_scheduler_management.md) - [기본 구성 완료](./250919_naverworks_slack_01_base_configuration.md) - [NAVER WORKS API 이슈 해결](./250918_naverworks_mail_api_mailaddress_null_issue.md) ## 8. 구현 내역 (2025-09-23) ### 생성 파일 - `app/scheduler/jobs/naverworks_briefing.py`: 스케줄러 등록 및 래퍼 함수 - `app/skills/naverworks_briefing.py`: 브리핑 비즈니스 로직 - `app/state/database.py`: get_naverworks_user_uuid() 추가 - `test_naverworks_briefing.py`: 테스트 스크립트 - `main.py`: 2줄 추가 (import + register) ### 주요 결정사항 - naverworks_token 테이블 직접 사용 (email_accounts 테이블 없음) - DB 접근 로직은 database.py에 위치 - 하드코딩 없이 에러 발생으로 처리 - Company-X 봇 토큰 사용 (COMPANYX_SLACK_BOT_TOKEN) - from 필드: NAVER WORKS API가 반환하는 {name, email} 객체 그대로 사용 ### ⚠️ 치명적 실수 방지 - **skill-email API**: `response.json().get("emails", [])` (messages 아님!) - **Slack 마크다운**: Gemini 응답의 `**` → `*` 변환 필수 - **중요 메일 없을 때**: 전체 메일 중 10개 사용 (return 하지 말 것) ### 테스트 명령 ```bash # 24서버에서 실행 python test_naverworks_briefing.py --test all ```