feat(ntfy): add ntfy platform adapter with atomic reconnect, identity fix, and 81 tests

This commit is contained in:
sprmn24 2026-05-23 00:54:18 +03:00 committed by Teknium
parent 874c2b1fe6
commit b10f17bf1e
10 changed files with 1318 additions and 3 deletions

View file

@ -777,6 +777,8 @@ async def _send_to_platform(platform, pconfig, chat_id, message, thread_id=None,
result = await _send_bluebubbles(pconfig.extra, chat_id, chunk)
elif platform == Platform.QQBOT:
result = await _send_qqbot(pconfig, chat_id, chunk)
elif platform == Platform.NTFY:
result = await _send_ntfy(pconfig, chat_id, chunk)
elif platform == Platform.YUANBAO:
result = await _send_yuanbao(chat_id, chunk)
else:
@ -1770,6 +1772,28 @@ async def _send_qqbot(pconfig, chat_id, message):
return _error(f"QQBot send failed: {e}")
async def _send_ntfy(pconfig, chat_id, message):
"""Send a message via ntfy HTTP POST."""
try:
extra = pconfig.extra or {}
server = extra.get("server") or os.getenv("NTFY_SERVER_URL", "https://ntfy.sh").rstrip("/")
topic = chat_id or extra.get("topic") or os.getenv("NTFY_TOPIC", "")
token = extra.get("token") or os.getenv("NTFY_TOKEN", "")
if not topic:
return _error("ntfy topic not configured.")
import httpx
headers = {"Content-Type": "text/plain; charset=utf-8"}
if token:
headers["Authorization"] = f"Bearer {token}"
url = f"{server}/{topic}"
async with httpx.AsyncClient(timeout=15.0) as client:
resp = await client.post(url, content=message.encode("utf-8"), headers=headers)
resp.raise_for_status()
return {"success": True, "platform": "ntfy", "chat_id": topic}
except Exception as e:
return _error(f"ntfy send failed: {e}")
async def _send_yuanbao(chat_id, message, media_files=None):
"""Send via Yuanbao using the running gateway adapter's WebSocket connection.