1
0
forked from erp-dev/erp
Files
erpnew/notifier/services.py
2026-04-13 12:30:33 +08:00

100 lines
3.2 KiB
Python

import logging
from django.template.loader import render_to_string
from notifier.models import Notifier
from notifier.registry import get_notifier_backend
logger = logging.getLogger(__name__)
def render_notification_content(*, notifier: Notifier, payload: dict) -> str:
content = render_to_string(notifier.get_template_name(), payload or {}).strip()
if not content:
raise ValueError("通知模板渲染结果不能为空")
return content
def send_notification_with_notifier(*, notifier: Notifier, payload: dict) -> dict:
content = render_notification_content(notifier=notifier, payload=payload)
backend = get_notifier_backend(notifier.channel)
backend_result = backend.notify(notifier=notifier, content=content, context=payload)
result = {
"notifier_id": notifier.id,
"notifier_name": notifier.name,
"event_key": notifier.event_key,
"channel": notifier.channel,
"template_key": notifier.template_key,
"status": "sent",
**backend_result,
}
logger.info("[notifier.services] notification sent: %s", result)
return result
def dispatch_notification_event(*, event_key: str, merchant_id: int, payload: dict | None = None) -> list[dict]:
notifiers = list(
Notifier.objects.filter(
merchant_id=merchant_id,
event_key=event_key,
is_enabled=True,
).order_by("id")
)
if not notifiers:
logger.info(
"[notifier.services] no enabled notifier matched: event_key=%s merchant_id=%s",
event_key,
merchant_id,
)
return []
results = []
for notifier in notifiers:
try:
results.append(send_notification_with_notifier(notifier=notifier, payload=payload or {}))
except Exception as exc:
logger.exception(
"[notifier.services] notification failed: notifier_id=%s event_key=%s merchant_id=%s",
notifier.id,
event_key,
merchant_id,
)
results.append(
{
"notifier_id": notifier.id,
"notifier_name": notifier.name,
"event_key": notifier.event_key,
"channel": notifier.channel,
"template_key": notifier.template_key,
"status": "failed",
"error": str(exc),
}
)
return results
def enqueue_notification_event(*, event_key: str, merchant_id: int, payload: dict | None = None) -> str | None:
from notifier.tasks import dispatch_notification_event_task
try:
async_result = dispatch_notification_event_task.delay(
event_key=event_key,
merchant_id=merchant_id,
payload=payload or {},
)
except Exception:
logger.exception(
"[notifier.services] queue notification task failed: event_key=%s merchant_id=%s",
event_key,
merchant_id,
)
return None
logger.info(
"[notifier.services] queued notification task: event_key=%s merchant_id=%s task_id=%s",
event_key,
merchant_id,
async_result.id,
)
return async_result.id