# Slack Lists 첨부파일 업로드 구현 **날짜**: 2025-10-14 **작성자**: happybell80 **관련 파일**: `rb8001/app/scheduler/jobs/coldmail_briefing.py` **전체 시나리오**: 251014_coldmail_ir_analysis_scenario.md --- ## 문제 상황 coldmail_briefing.py:207에서 document_id를 attachment에 전달하지만, Slack Lists API는 file_id 필요 --- ## 현재 상태 - skill-rag-file/app/main.py:54-55: upload, search만 등록, download 없음 - skill-slack/app/api/__init__.py:4: files import 없음 --- ## 해결 방안 ### 1단계: skill-rag-file 다운로드 API 추가 **파일**: skill-rag-file/app/api/download.py (신규) **참고**: upload.py:80-87 (storage_path 생성 로직) **구현**: - `@router.get("/download/{document_id}")`: UUID로 문서 조회 - DB에서 TeamDocument.storage_path 가져오기 (upload.py:108 참고) - `FileResponse(storage_path, media_type="application/pdf")` 반환 **등록**: skill-rag-file/app/main.py:55 이후 추가 - `app.include_router(download.router, prefix="/api", tags=["download"])` ### 2단계: skill-slack 파일 업로드 API 추가 **파일**: skill-slack/app/api/endpoints/files.py (신규) **참고**: lists.py:47-82 (엔드포인트 구조), slack_lists_service (서비스 패턴) **구현**: - `@router.post("/files/upload", dependencies=[Depends(verify_api_key)])`: UploadFile 받기 - 파라미터: file (UploadFile), title (str), token (Optional[str]) - WebClient(token).files_upload_v2(file=file.file, title=title) 호출 - 반환: `{"file_id": str, "url_private": str}` **등록**: skill-slack/app/api/__init__.py 수정 - 4번 줄: `from .endpoints import summary, digest, actions, messages, lists, files` - 13번 줄 이후: `router.include_router(files.router, tags=["Files"])` ### 3단계: coldmail_briefing.py 통합 - coldmail_briefing.py:207 이전에 파일 변환 로직 추가: 1. document_id → GET skill-rag-file/api/download/{document_id} 2. 다운로드된 파일 → POST skill-slack/api/v1/files/upload 3. file_id 받아서 attachment 필드에 전달 - coldmail_briefing.py:207: `[f"document_{doc_id}"...]` → `[file_id]` 변경 --- ## 테스트 완료 (2025-10-14) ### 테스트 환경 - 워크스페이스: 로빙팀 (T0925SXPS4D), 리스트: F09J1HPPQJG - 채널: C09HR9BMT51, 토큰: ROBEING_SLACK_BOT_TOKEN ### 검증 결과 - files_upload_v2(file, title) 성공 (channel 파라미터 없이 업로드) - slackLists.items.create 성공, attachment: [file_id] 전달 확인 - 테스트 파일: skill-slack/tests/test_lists_with_file.py, test_lists_all_fields.py ### 테스트 리스트 컬럼 (F09J1HPPQJG) - Col00: checkbox, Col01: user, Col02: date - Col09HQTDUM0T: rich_text(name) - Col09JATRA4GZ: email, Col09HGCGB45D: attachment, Col09JRU1U1FA: checkbox ### 운영 환경 확인 필요 - Company X 리스트 (F09L4S2C6BG) 컬럼 ID는 다를 수 있음 - Slack App 재설치 후 lists:read/write 권한 확인 필요 --- ## 교훈 ### channel 파라미터 필수 여부 미확인 - files_upload_v2는 channel 없이도 업로드 가능 - 문서(test_slack_lists.py:192)에 명시되어 있었으나 미확인 - 교훈: 테스트 코드 주석과 구현 예시 우선 확인 ### 테스트/운영 환경 리스트 구조 차이 - F09J1HPPQJG(테스트)와 F09L4S2C6BG(운영)는 별도 리스트 - 컬럼 ID가 다를 가능성 있음 - 교훈: 운영 배포 전 실제 리스트 구조 확인 필수 ### Slack App scope 재설치 프로세스 - scope 추가 시 각 워크스페이스별 재설치 필요 - 앱 소유자만 api.slack.com/apps 접근 가능 - 교훈: 멀티 워크스페이스 앱은 OAuth URL 생성하여 관리자에게 전달