Files

115 lines
3.9 KiB
Python

from __future__ import annotations
from dataclasses import dataclass, field
from pathlib import Path
from app.mail_notifier import MailNotifier
from app.matrix_notifier import MatrixNotifier
from app.models import NotificationDecision, ProcessorForwardEnvelope
from app.notifications.formatter import NotificationFormatter
@dataclass
class DispatchReport:
attempted: bool = False
matrix_attempted: bool = False
matrix_sent: bool = False
matrix_event_id: str | None = None
matrix_error: str | None = None
matrix_image_attempted: bool = False
matrix_image_sent: bool = False
matrix_image_event_id: str | None = None
matrix_image_mxc_uri: str | None = None
matrix_image_error: str | None = None
mail_attempted: bool = False
mail_sent: bool = False
mail_error: str | None = None
errors: list[str] = field(default_factory=list)
class NotificationDispatcher:
def __init__(
self,
matrix_notifier: MatrixNotifier | None = None,
mail_notifier: MailNotifier | None = None,
) -> None:
self.matrix_notifier = matrix_notifier
self.mail_notifier = mail_notifier
async def dispatch(
self,
envelope: ProcessorForwardEnvelope,
decision: NotificationDecision,
) -> DispatchReport:
report = DispatchReport()
if not decision.notify or decision.suppressed:
return report
report.attempted = True
if "matrix" in decision.channels and self.matrix_notifier is not None:
report.matrix_attempted = True
matrix_body = NotificationFormatter.format_matrix_message(
envelope=envelope,
decision=decision,
)
matrix_result = await self.matrix_notifier.send_message(matrix_body)
report.matrix_sent = matrix_result.ok
report.matrix_event_id = matrix_result.event_id
report.matrix_error = matrix_result.error
if matrix_result.error:
report.errors.append(f"matrix: {matrix_result.error}")
# Если есть отрисованный PNG, отправляем его вторым сообщением
graph_image_path = envelope.event.graph_image_path
if graph_image_path and Path(graph_image_path).exists():
report.matrix_image_attempted = True
image_body = f"{envelope.event.trigger_name or 'Graph'} graph"
image_result = await self.matrix_notifier.send_image(
file_path=graph_image_path,
body=image_body,
)
report.matrix_image_sent = image_result.ok
report.matrix_image_event_id = image_result.event_id
report.matrix_image_mxc_uri = image_result.content_uri
report.matrix_image_error = image_result.error
if image_result.error:
report.errors.append(f"matrix_image: {image_result.error}")
if "mail" in decision.channels and self.mail_notifier is not None:
report.mail_attempted = True
subject = NotificationFormatter.format_mail_subject(
envelope=envelope,
decision=decision,
)
body = NotificationFormatter.format_mail_body(
envelope=envelope,
decision=decision,
)
attachments: list[str] = []
if envelope.event.graph_image_path:
attachments.append(envelope.event.graph_image_path)
mail_result = await self.mail_notifier.send_message(
subject=subject,
body=body,
attachments=attachments,
)
report.mail_sent = mail_result.ok
report.mail_error = mail_result.error
if mail_result.error:
report.errors.append(f"mail: {mail_result.error}")
return report