Docs: [3.0.0] 전체 문서 업데이트 — YouTube Data API + n8n Discord 전송 구조 반영
All checks were successful
news-summary-bot-cicd / build_push_deploy (push) Successful in 25m15s

- README: 아키텍처, 환경변수, API 응답 형식 업데이트
- n8n-setup: RSS → YouTube Data API playlistItems 전환, 노드별 상세 설정
- development: discord.py 제거 반영, API 응답 형식 추가
- operations: CI/CD 자동 배포 설명, DISCORD_WEBHOOK_URL 제거
- testing: DISCORD_WEBHOOK_URL 더미값 제거
- .env.example: DISCORD_WEBHOOK_URL 제거
- tests/test_discord.py 삭제 (모듈 삭제됨)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
sm4640
2026-03-25 15:18:39 +09:00
parent 302f892c5d
commit a2a82084ba
7 changed files with 260 additions and 273 deletions

View File

@@ -1,11 +1,11 @@
# News Summary Bot
YouTube 뉴스/경제 채널의 새 영상을 감지하면 자막을 추출하고, Claude API로 요약한 뒤 Discord로 전송하는 봇입니다.
YouTube 뉴스/경제 채널의 새 영상을 감지하면 자막을 추출하고, Claude API로 요약하는 봇입니다.
## 아키텍처
```
n8n (RSS 감지) → POST /api/news/summarize → 자막 추출 → Claude 요약 → Discord 웹훅
n8n (YouTube Data API로 새 영상 감지) → POST /api/news/summarize → 자막 추출 → Claude 요약 → JSON 응답 → n8n이 Discord 웹훅 전송
```
| 모듈 | 역할 |
@@ -13,7 +13,6 @@ n8n (RSS 감지) → POST /api/news/summarize → 자막 추출 → Claude 요
| `app/main.py` | FastAPI 엔드포인트 |
| `app/transcript.py` | YouTube 자막 추출 (yt-dlp + 쿠키 인증) |
| `app/summarizer.py` | Claude Sonnet 4.6으로 요약 생성 |
| `app/discord.py` | Discord 웹훅 전송 |
| `app/config.py` | 환경변수 설정 (pydantic-settings) |
## 빠른 시작
@@ -28,7 +27,6 @@ cp .env.example .env
| 변수 | 필수 | 설명 |
|------|------|------|
| `ANTHROPIC_API_KEY` | O | Claude API 키 |
| `DISCORD_WEBHOOK_URL` | O | Discord 웹훅 URL |
| `API_SECRET` | X | n8n → FastAPI 인증용 시크릿 |
### 로컬 개발
@@ -53,13 +51,13 @@ OCI 등 클라우드 서버에서는 YouTube가 데이터센터 IP를 봇으로
2. 서버에 `cookies.txt` 업로드
3. `compose.apps.yml`에서 볼륨 마운트: `./news-summary-bot/cookies.txt:/app/cookies.txt:ro`
> 쿠키는 6개월~1년 후 만료됩니다. 자막 추출 500 에러 발생 시 쿠키 재export가 필요합니다.
> 쿠키는 6개월~1년 후 만료됩니다. 자막 추출 에러 발생 시 쿠키 재export가 필요합니다.
## API
### `POST /api/news/summarize` (외부) / `POST /summarize` (내부)
영상 URL을 받아 자막 추출 → 요약 Discord 전송을 수행합니다.
영상 URL을 받아 자막 추출 → 요약을 수행하고 JSON으로 결과를 반환합니다. Discord 전송은 n8n에서 처리합니다.
**Request:**
@@ -75,11 +73,14 @@ OCI 등 클라우드 서버에서는 YouTube가 데이터센터 IP를 봇으로
**Response:**
```json
{
"status": "ok",
"title": "영상 제목",
"summary_length": 1234
}
// 성공
{"status": "ok", "title": "영상 제목", "summary": "요약 텍스트"}
// 스킵 (라이브/쇼츠)
{"status": "skipped", "title": "영상 제목", "reason": "라이브/예정 영상은 요약 대상이 아닙니다"}
// 에러
{"status": "error", "title": "영상 제목", "error_type": "ValueError", "error_message": "..."}
```
### `GET /api/news/health` (외부) / `GET /health` (내부)
@@ -90,14 +91,10 @@ OCI 등 클라우드 서버에서는 YouTube가 데이터센터 IP를 봇으로
## n8n 워크플로우
```
RSS Feed Trigger (채널A) ──┐
├→ Merge → HTTP Request (POST /api/news/summarize)
RSS Feed Trigger (채널B) ──┘
```
n8n에서 YouTube Data API v3의 `playlistItems.list`로 채널별 새 영상을 감지하고, 각 영상마다 이 봇의 API를 호출합니다. 응답의 `status` 필드로 분기하여 Discord 웹훅으로 요약 또는 에러 알림을 전송합니다.
n8n에서 RSS Feed Trigger로 채널별 새 영상을 감지하고, 각 영상마다 이 봇의 API를 호출합니다. 자세한 설정은 [docs/n8n-setup.md](docs/n8n-setup.md)를 참고하세요.
자세한 설정은 [docs/n8n-setup.md](docs/n8n-setup.md)를 참고하세요.
## 배포
Docker Hub에 이미지를 푸시하고 서버에서 `docker compose pull && docker compose up -d`로 배포합니다. 자세한 내용은 [docs/operations.md](docs/operations.md)를 참고하세요.
CI/CD가 설정되어 있어 main 브랜치에 push하면 자동으로 Docker 이미지 빌드 → Docker Hub push → OCI 서버 배포가 진행됩니다. 자세한 내용은 [docs/operations.md](docs/operations.md)를 참고하세요.