refactor(ntfy): convert built-in adapter to platform plugin
ntfy now ships as a self-contained plugin under plugins/platforms/ntfy/ instead of editing 8 core files (gateway/config.py Platform enum, gateway/run.py factory + auth maps, cron/scheduler.py, toolsets.py, hermes_cli/status.py, agent/prompt_builder.py, gateway/channel_directory.py, tools/send_message_tool.py). All routing goes through gateway/platform_registry via register_platform(): - adapter_factory, check_fn, validate_config, is_connected - env_enablement_fn seeds PlatformConfig.extra from NTFY_* env vars so gateway status reflects env-only setups without instantiating httpx - standalone_sender_fn handles deliver=ntfy cron jobs when cron runs out-of-process from the gateway - allowed_users_env / allow_all_env hook into _is_user_authorized - cron_deliver_env_var=NTFY_HOME_CHANNEL for cron home routing - platform_hint surfaces in the system prompt - pii_safe=True (topic names are the only identifier; no PII to redact) Tests moved to tests/gateway/test_ntfy_plugin.py using _plugin_adapter_loader so the module lives under plugin_adapter_ntfy in sys.modules and cannot collide with sibling plugin-adapter tests on the same xdist worker. The core-file grep tests (Platform.NTFY in source, hermes-ntfy in toolsets, etc.) are replaced with plugin-shape tests covering register() metadata, env_enablement_fn output, and standalone_sender_fn behavior. 68 tests pass under scripts/run_tests.sh.
This commit is contained in:
@@ -777,8 +777,6 @@ 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:
|
||||
@@ -1772,28 +1770,6 @@ 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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user