forked from erp-dev/erp
feat: notifier beta
This commit is contained in:
99
notifier/services.py
Normal file
99
notifier/services.py
Normal file
@@ -0,0 +1,99 @@
|
||||
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
|
||||
Reference in New Issue
Block a user