lizerk 14f1e52425
Some checks failed
Deploy production / deploy (push) Failing after 4s
fix(messages): make HTTP authoritative for chat reads
2026-09-10 11:41:59 +03:00

85 lines
3.1 KiB
Python

"""
WebSocket отправитель для realtime уведомлений
"""
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
from .base import BaseNotificationSender
class WebSocketNotificationSender(BaseNotificationSender):
"""
Отправитель WebSocket уведомлений через Django Channels.
Обеспечивает realtime доставку в браузер.
"""
def can_send(self, notification, user_preferences) -> bool:
"""Проверяет, включены ли веб уведомления"""
if not user_preferences.web_enabled:
self.log_skip(notification, "web_enabled=False")
return False
return True
def send(self, notification, silent: bool = False, **kwargs) -> bool:
"""
Отправляет уведомление через WebSocket.
Args:
notification: Объект Notification
silent: Если True, уведомление без звука/визуальных эффектов
**kwargs: Дополнительные параметры
Returns:
True если отправлено успешно, False иначе
"""
try:
channel_layer = get_channel_layer()
if not channel_layer:
self.log_skip(notification, "channel_layer not configured")
return False
user_id = notification.recipient.id
user_channel = f"user_{user_id}"
# Формируем данные для фронтенда
message_data = {
"type": "notification",
"id": notification.id,
"verb": notification.verb,
"description": notification.description,
"action_url": notification.action_url,
"timestamp": notification.timestamp.isoformat(),
"unread": notification.unread,
"silent": silent,
"data": notification.data,
}
# Добавляем actor если есть
if notification.actor:
message_data["actor"] = {
"type": notification.actor_content_type.model,
"id": notification.actor_object_id,
"str": str(notification.actor),
}
# Добавляем target если есть
if notification.target:
message_data["target"] = {
"type": notification.target_content_type.model,
"id": notification.target_object_id,
"str": str(notification.target),
}
# Отправляем через Channels
async_to_sync(channel_layer.group_send)(
user_channel, {"type": "notification_message", "message": message_data}
)
self.log_success(notification, f"user_{user_id}")
return True
except Exception as e:
self.log_error(notification, e, f"user_{notification.recipient.id}")
return False