From af0e2fca8a678b2b1d0c7e3a240b80dc047d263c Mon Sep 17 00:00:00 2001 From: sm4640 Date: Tue, 24 Mar 2026 16:27:03 +0900 Subject: [PATCH] =?UTF-8?q?Feat:=20[2.0.5]=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=20=EC=8B=9C=20Discord=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=20=EC=A0=84=EC=86=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 요약 처리 중 에러 발생 시 Discord에 에러 상세 내용 전송 - 에러 타입, 메시지, 영상 정보를 포함한 embed 형식 Co-Authored-By: Claude Opus 4.6 --- app/discord.py | 26 ++++++++++++++++++++++++++ app/main.py | 17 +++++++++++------ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/app/discord.py b/app/discord.py index ac0533f..f21482d 100644 --- a/app/discord.py +++ b/app/discord.py @@ -107,3 +107,29 @@ async def send_to_discord(title: str, video_url: str, summary: str) -> None: async with httpx.AsyncClient() as client: resp = await client.post(settings.discord_webhook_url, json=payload) resp.raise_for_status() + + +async def send_error_to_discord( + title: str, video_url: str, error: Exception +) -> None: + """에러 발생 시 Discord 웹훅으로 에러 내용 전송.""" + error_type = type(error).__name__ + error_msg = str(error)[:1024] + + embed = { + "title": "❌ 뉴스 요약 실패", + "color": 0xED4245, + "fields": [ + {"name": "영상 제목", "value": title or "(제목 없음)", "inline": False}, + {"name": "영상 URL", "value": video_url, "inline": False}, + {"name": "에러 타입", "value": f"`{error_type}`", "inline": True}, + {"name": "에러 내용", "value": f"```\n{error_msg}\n```", "inline": False}, + ], + "footer": {"text": "YouTube 뉴스 요약 봇 - 에러 알림"}, + "timestamp": datetime.now(timezone.utc).isoformat(), + } + + payload = {"embeds": [embed]} + + async with httpx.AsyncClient() as client: + await client.post(settings.discord_webhook_url, json=payload) diff --git a/app/main.py b/app/main.py index 815cc46..135b121 100644 --- a/app/main.py +++ b/app/main.py @@ -2,7 +2,7 @@ from fastapi import FastAPI, Header, HTTPException from pydantic import BaseModel from app.config import settings -from app.discord import send_to_discord +from app.discord import send_error_to_discord, send_to_discord from app.summarizer import summarize from app.transcript import extract_video_id, fetch_transcript @@ -22,11 +22,16 @@ async def summarize_video( if settings.api_secret and x_api_secret != settings.api_secret: raise HTTPException(status_code=401, detail="Unauthorized") - video_id = extract_video_id(req.video_url) - transcript = fetch_transcript(video_id) - title = req.title or video_id - summary = summarize(transcript, title) - await send_to_discord(title, req.video_url, summary) + title = req.title or "제목 없음" + + try: + video_id = extract_video_id(req.video_url) + transcript = fetch_transcript(video_id) + summary = summarize(transcript, title) + await send_to_discord(title, req.video_url, summary) + except Exception as e: + await send_error_to_discord(title, req.video_url, e) + raise HTTPException(status_code=500, detail=str(e)) return {"status": "ok", "title": title, "summary_length": len(summary)}