trace/services/notify-gateway/notifiers/factory.py
Lee 19afaffbb7
All checks were successful
Java Maven 3.9.9 & JDK 26 CI/CD Pipeline / build-and-deploy (push) Successful in 3m22s
feat: add shared notification gateway
2026-09-07 17:50:25 +08:00

52 lines
1.9 KiB
Python

from .base import ImageAttachment, Notifier
from .qq import QQNotifier
from .telegram import TelegramNotifier
from .wecom_webhook import WecomWebhookNotifier
def build_notifier(name: str, cfg: dict | None = None) -> Notifier:
cfg = cfg or {}
if name == "telegram":
return TelegramNotifier(
token=cfg.get("token", ""),
chat_ids=cfg.get("chat_ids"),
token_env=cfg.get("token_env", "TELEGRAM_BOT_TOKEN"),
chat_ids_env=cfg.get("chat_ids_env", "TELEGRAM_NOTIFY_CHAT_ID"),
)
if name == "wecom_webhook":
return WecomWebhookNotifier(urls=cfg.get("urls"))
if name == "qq":
return QQNotifier(
onebot_http=cfg.get("onebot_http", ""),
access_token=cfg.get("access_token", ""),
targets=cfg.get("targets", []))
raise ValueError(f"Unknown notification channel: {name}")
def build_notifiers(names: list[str], channels_cfg: dict | None = None) -> "MultiNotifier":
channels_cfg = channels_cfg or {}
return MultiNotifier([build_notifier(n, channels_cfg.get(n, {})) for n in names])
class MultiNotifier(Notifier):
"""Fan-out to N channels; raises only if ALL fail."""
name = "multi"
def __init__(self, notifiers: list[Notifier]):
self.notifiers = notifiers
async def send(self, title: str, text: str,
images: list[ImageAttachment] | None = None) -> None:
errors: dict[str, str] = {}
for n in self.notifiers:
try:
await n.send(title, text, images)
except Exception as exc:
errors[n.name] = repr(exc)
if errors and len(errors) == len(self.notifiers):
raise RuntimeError(f"All notifiers failed: {errors}")
if errors:
import logging
logging.getLogger("notify-gateway").warning("partial notify failure: %s", errors)