diff --git a/troubleshooting/250930_naverworks_slack_03_cold_mail_list.md b/troubleshooting/250930_naverworks_slack_03_cold_mail_list.md index 684cfb5..3d0cd64 100644 --- a/troubleshooting/250930_naverworks_slack_03_cold_mail_list.md +++ b/troubleshooting/250930_naverworks_slack_03_cold_mail_list.md @@ -21,12 +21,13 @@ NAVER WORKS 메일 중 투자 제안(콜드메일) 수신 시: ## 구현 완료 (2025-09-30) -### skill-email (커밋: a535732, c498ea2) +### skill-email (커밋: a535732, c498ea2, 926cd69, 30619a3, e2eace3) - GET /messages/{message_id}: routers/mail_detail_router.py 생성, main.py:311-312 등록 - GET /messages/{message_id}/attachments/{attachment_id}: routers/mail_detail_router.py - download_attachment 메서드: services/naverworks_provider.py:357-388 -- attachments 필드 추가: services/naverworks_provider.py:326 -- mail_detail_router.py: main.get_email_provider() 사용 (initialize_providers 호출, c498ea2) +- attachCount 필드 추가: services/naverworks_provider.py:277, main.py:266 (926cd69, 30619a3) +- attachments 필드 수정: get_message()에서 data.get("attachments") 사용 (e2eace3) +- mail_detail_router.py: main.get_email_provider() 사용 (c498ea2) ### rb8001 (커밋: 19304ea, 1980a4e, d88615e, 276b258, d0b8605, a6998ed, b4ed61d, 3507ed0) - app/services/coldmail_filter.py: Incremental Naive Bayes (단어 빈도 기반, Counter 사용, a6998ed), 확률값 로깅 (b4ed61d) @@ -55,8 +56,7 @@ NAVER WORKS 메일 중 투자 제안(콜드메일) 수신 시: **메일 상세 조회 API 응답 확인 (실제 테스트)** - **attachments 필드 존재 확인**: 원본 API 응답에 attachments 배열 포함 - **확인된 첨부파일 정보**: attachmentId: 2, filename: "04-2. 투자자검토보고서_군돌이.pdf", contentType: "application/pdf", size: 872235 -- **문제점**: naverworks_provider.py:288-329의 get_message()가 Gmail 형식 변환 중 attachments 필드 누락 -- **해결 방안**: get_message() 응답에 attachments 필드 추가 필요 +- **✅ 해결 완료**: get_message()에서 data.get("attachments") 사용 (e2eace3) **Slack Lists API** - **메서드**: `slackLists.items.create`, `slackLists.items.update` @@ -64,7 +64,10 @@ NAVER WORKS 메일 중 투자 제안(콜드메일) 수신 시: - **제약**: 유료 플랜 필요 - **문서**: https://docs.slack.dev/reference/methods/slackLists.items.create/ -**구현 가능성**: 100% (API 스펙 및 실제 응답 구조 검증 완료) +### 첨부파일 처리 검증 완료 (2025-10-03) +- ✅ GET /messages: 30개 메일 중 5개 첨부파일 감지 (attachCount) +- ✅ GET /messages/{id}: attachments 배열 정상 반환 (인라인 이미지/일반 첨부 구분) +- ✅ GET /messages/{id}/attachments/{attachmentId}: 38KB HTML 파일 다운로드 성공 ### 환경 설정 완료 (2025-09-30, 51124 서버) - **DB 테이블**: coldmail_classifier, startup_valuation (51123 서버) @@ -74,7 +77,7 @@ NAVER WORKS 메일 중 투자 제안(콜드메일) 수신 시: - COLDMAIL_CHANNEL_ID=C09HR9BMT51 - SLACK_LIST_ID=F09J1HPPQJG - NAVERWORKS_COMPANY_EMAIL (하드코딩 제거됨) -- **Slack 앱 스코프**: lists:write, lists:read, files:read +- **Slack 앱 스코프**: lists:write, lists:read, files:read (files:write 추가 필요) - **배포**: docker-compose.yml env_file: .env (line 6-7), Dockerfile COPY ./tests (line 30) --- @@ -94,8 +97,9 @@ NAVER WORKS 메일 중 투자 제안(콜드메일) 수신 시: 6. process_naverworks_attachments() → PDF만 선택 → skill-rag-file POST /api/upload 7. extract_ir_metrics() → skill-rag-file RAG 쿼리 6회 → LLM 요약 8. valuate_startup() → Bayesian VC Method (Prior × Likelihood = Posterior) → startup_valuation 테이블 저장 -9. create_coldmail_list_item() → Slack Lists API (lists.items.create) -10. skill-slack POST /api/v1/send → 처리 완료 요약 메시지 +9. ❌ **미구현**: Slack 파일 업로드 (아래 참조) +10. create_coldmail_list_item() → Slack Lists API (lists.items.create) - 현재 document_id 텍스트만 저장 +11. skill-slack POST /api/v1/send → 처리 완료 요약 메시지 ### Naive Bayes 학습 루프 - initialize_seed_data(): *.vc 도메인, 투자/IR 키워드 시드 (수동 DB INSERT) @@ -109,6 +113,67 @@ NAVER WORKS 메일 중 투자 제안(콜드메일) 수신 시: --- +## Slack 파일 업로드 구현 가이드 (미구현) + +### API 변경 사항 (2025) +- **files.upload 폐기**: 2025-11-12부터 사용 불가, 신규 앱 접근 차단 +- **신규 방식**: files.getUploadURLExternal + files.completeUploadExternal + +### 구현 순서 +1. **파일 업로드 URL 획득** + ```python + # files.getUploadURLExternal 호출 + response = client.files_getUploadURLExternal( + filename="ir_document.pdf", + length=file_size + ) + upload_url = response["upload_url"] + file_id = response["file_id"] + ``` + +2. **파일 데이터 업로드** + ```python + # POST binary data to upload_url + async with session.post(upload_url, data=file_binary) as resp: + # 성공 시 200 응답 + ``` + +3. **업로드 완료 처리** + ```python + # files.completeUploadExternal 호출 + client.files_completeUploadExternal( + files=[{"id": file_id, "title": "IR 문서"}], + channel_id=COLDMAIL_CHANNEL_ID # 선택: 채널 공유 + ) + ``` + +4. **Slack Lists에 파일 첨부** + ```python + # slackLists.items.create 호출 + fields = { + "company": {"text": company_name}, + "attachments": {"attachment": [file_id]} # 방법 1 + # 또는 + "files": {"reference": [{"file": {"file_id": file_id}}]} # 방법 2 + } + ``` + +### 필수 스코프 추가 +- 현재: `lists:write`, `lists:read`, `files:read` +- 추가 필요: `files:write` + +### 구현 위치 +- **skill-slack**: POST /api/v1/upload-file 엔드포인트 추가 +- **rb8001/coldmail_briefing.py**: 9번 단계에 파일 업로드 로직 추가 +- **rb8001/services/slack_lists_client.py**: create_coldmail_list_item()에 file_id 파라미터 추가 + +### 참고 문서 +- files.getUploadURLExternal: https://api.slack.com/methods/files.getUploadURLExternal +- files.completeUploadExternal: https://api.slack.com/methods/files.completeUploadExternal +- slackLists.items.create: https://docs.slack.dev/reference/methods/slackLists.items.create/ + +--- + ## 테스트 ### 테스트 파일