From 40c5d3cf213fbe00d37490a17fb3da2585f6eb56 Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Mon, 6 Apr 2026 12:57:50 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20Synology=20=EC=9D=91=EB=8B=B5=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=A7=88=ED=81=AC=EB=8B=A4=EC=9A=B4=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20=E2=80=94=20**bold**,=20#=20header,=20-=20list=20?= =?UTF-8?q?=E2=86=92=20=EC=88=9C=EC=88=98=20=ED=85=8D=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 상태 메시지(이모지)는 raw=True로 유지 Co-Authored-By: Claude Opus 4.6 (1M context) --- nanoclaude/routers/synology.py | 2 +- nanoclaude/services/synology_sender.py | 17 +++++++++++++++-- nanoclaude/services/worker.py | 4 ++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/nanoclaude/routers/synology.py b/nanoclaude/routers/synology.py index 2c347f0..7dd8610 100644 --- a/nanoclaude/routers/synology.py +++ b/nanoclaude/routers/synology.py @@ -69,7 +69,7 @@ async def synology_webhook(request: Request): logger.info("Synology job %s from %s: %s", job.id, username, text[:50]) # "처리 중" 메시지 먼저 전송 (typing 느낌) - await send_to_synology("🤔 생각 중...") + await send_to_synology("🤔 생각 중...", raw=True) # 파이프라인 시작 (비동기) await jq_module.job_queue.submit(job) diff --git a/nanoclaude/services/synology_sender.py b/nanoclaude/services/synology_sender.py index 88195a5..d74472b 100644 --- a/nanoclaude/services/synology_sender.py +++ b/nanoclaude/services/synology_sender.py @@ -4,6 +4,7 @@ from __future__ import annotations import json import logging +import re import httpx @@ -12,12 +13,24 @@ from config import settings logger = logging.getLogger(__name__) -async def send_to_synology(text: str) -> bool: - """Incoming webhook URL로 메시지 전송. 성공 시 True.""" +def _strip_markdown(text: str) -> str: + """마크다운 문법 제거 — Synology Chat은 렌더링 안 됨.""" + text = re.sub(r'\*\*(.+?)\*\*', r'\1', text) # **bold** + text = re.sub(r'\*(.+?)\*', r'\1', text) # *italic* + text = re.sub(r'`(.+?)`', r'\1', text) # `code` + text = re.sub(r'^#{1,6}\s+', '', text, flags=re.MULTILINE) # ### headers + text = re.sub(r'^\s*[-*]\s+', '• ', text, flags=re.MULTILINE) # - list → • + return text + + +async def send_to_synology(text: str, *, raw: bool = False) -> bool: + """Incoming webhook URL로 메시지 전송. raw=True면 마크다운 제거 안 함.""" if not settings.synology_incoming_url: logger.warning("Synology incoming URL not configured") return False + if not raw: + text = _strip_markdown(text) payload = json.dumps({"text": text}, ensure_ascii=False) try: diff --git a/nanoclaude/services/worker.py b/nanoclaude/services/worker.py index dbad67f..a764abe 100644 --- a/nanoclaude/services/worker.py +++ b/nanoclaude/services/worker.py @@ -163,7 +163,7 @@ async def run(job: Job) -> None: if job.callback != "synology": await state_stream.push(job.id, "rewrite", {"content": rewritten_message}) else: - await send_to_synology("📝 더 깊이 살펴볼게요...") + await send_to_synology("📝 더 깊이 살펴볼게요...", raw=True) if job.status == JobStatus.cancelled: return @@ -241,7 +241,7 @@ async def run(job: Job) -> None: await state_stream.push(job.id, "error", {"message": "내부 오류가 발생했습니다."}) if job.callback == "synology": try: - await send_to_synology("⚠️ 처리 중 오류가 발생했습니다. 다시 시도해주세요.") + await send_to_synology("⚠️ 처리 중 오류가 발생했습니다. 다시 시도해주세요.", raw=True) except Exception: pass try: