Files
gpu-services/nanoclaude/services/synology_sender.py
Hyungi Ahn 40c5d3cf21 fix: Synology 응답에서 마크다운 제거 — **bold**, # header, - list → 순수 텍스트
상태 메시지(이모지)는 raw=True로 유지

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:57:50 +09:00

49 lines
1.6 KiB
Python

"""Synology Chat — incoming webhook으로 응답 전송."""
from __future__ import annotations
import json
import logging
import re
import httpx
from config import settings
logger = logging.getLogger(__name__)
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:
async with httpx.AsyncClient(verify=False, timeout=10.0) as client:
resp = await client.post(
settings.synology_incoming_url,
data={"payload": payload},
)
if resp.status_code == 200:
return True
logger.error("Synology send failed: %d %s", resp.status_code, resp.text)
return False
except Exception:
logger.exception("Failed to send to Synology Chat")
return False