115 lines
3.9 KiB
Python
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 |