From 69628b1d2d93d4d87c3a1ec4db3e2e0ff0acfade Mon Sep 17 00:00:00 2001 From: KlemenSpruk Date: Mon, 20 Nov 2023 14:56:10 +0100 Subject: [PATCH] send delayed notification --- .../celery/background_tasks/beat_task.py | 6 +-- .../notifications/base/notification.py | 48 +++++++++++-------- ...jangoprojectbasenotification_extra_data.py | 17 +++++++ django_project_base/notifications/models.py | 1 + .../notifications/rest/notification.py | 1 + 5 files changed, 49 insertions(+), 24 deletions(-) create mode 100644 django_project_base/notifications/migrations/0011_djangoprojectbasenotification_extra_data.py diff --git a/django_project_base/celery/background_tasks/beat_task.py b/django_project_base/celery/background_tasks/beat_task.py index e3a34524..ba90f12c 100644 --- a/django_project_base/celery/background_tasks/beat_task.py +++ b/django_project_base/celery/background_tasks/beat_task.py @@ -5,6 +5,7 @@ from django_project_base.celery.background_tasks.base_task import BaseTask from django_project_base.celery.celery import app from django_project_base.constants import NOTIFICATION_QUEUE_NAME +from django_project_base.notifications.base.send_notification_service import SendNotificationService from django_project_base.notifications.models import DjangoProjectBaseNotification @@ -25,7 +26,6 @@ def run(self): cache.set(self.run_ck, True, timeout=None) now_ts = datetime.datetime.now().timestamp() + 300 - # SET CONNECTION AND DELETE IT IN EXTRA DATA for notification in DjangoProjectBaseNotification.objects.using(NOTIFICATION_QUEUE_NAME).filter( send_at__isnull=False, sent_at__isnull=True, send_at__lte=now_ts ): @@ -33,9 +33,7 @@ def run(self): notification.user = notification.extra_data["user"] notification.recipients_list = notification.extra_data["recipients-list"] notification.sender = notification.extra_data["sender"] - print(notification) - - # SendNotificationService().make_send(notification, notification.extra_data or {}, resend=False) + SendNotificationService(settings=self.settings).make_send(notification, {}, resend=False) self._clear_in_progress_status() def on_failure(self, exc, task_id, args, kwargs, einfo): diff --git a/django_project_base/notifications/base/notification.py b/django_project_base/notifications/base/notification.py index 0cb281fb..8d8e8394 100644 --- a/django_project_base/notifications/base/notification.py +++ b/django_project_base/notifications/base/notification.py @@ -94,7 +94,7 @@ def __init__( @staticmethod def resend(notification: DjangoProjectBaseNotification, user_pk: Optional[str] = None): - notification.user = user_pk + notification.user = user_pk or (notification.extra_data or {}).get("user") from django_project_base.notifications.rest.notification import MessageToListField recipients: List[str] = MessageToListField.parse(json.loads(notification.recipients_original_payload)) @@ -175,6 +175,7 @@ def send(self) -> DjangoProjectBaseNotification: send_notification_sms=self.send_notification_sms, send_notification_sms_text=None, send_at=self.send_at, + extra_data=self._extra_data, ) notification = self._ensure_channels(channels=required_channels, notification=notification, settings=settings) @@ -209,6 +210,8 @@ def send(self) -> DjangoProjectBaseNotification: ) notification.recipients_list = rec_list ext_data = self._extra_data.get("a_extra_data") or self._extra_data + notification.extra_data = ext_data + notification.save(update_fields=["extra_data"]) self.enqueue_notification(notification, extra_data=ext_data) return notification @@ -216,25 +219,30 @@ def send(self) -> DjangoProjectBaseNotification: SendNotificationService(settings=settings, use_default_db_connection=True).make_send( notification, self._extra_data, resend=False ) - # else: - # if not self.persist: - # raise Exception("Delayed notification must be persisted") - # mail_fallback: bool = ( - # swapper.load_model("django_project_base", "ProjectSettings") - # .objects.get(name=USE_EMAIL_IF_RECIPIENT_HAS_NO_PHONE_NUMBER, project__slug=notification.project_slug) - # .python_value - # if notification.project_slug - # else False - # ) - # rec_list = [] - # for usr in self._recipients: - # rec_list.append( - # { - # k: v - # for k, v in get_user_model().objects.get(pk=usr).userprofile.__dict__.items() - # if not k.startswith("_") and isinstance(v, (str, list, tuple, int, float)) - # } - # ) + else: + if not self.persist: + raise Exception("Delayed notification must be persisted") + mail_fallback: bool = ( + swapper.load_model("django_project_base", "ProjectSettings") + .objects.get(name=USE_EMAIL_IF_RECIPIENT_HAS_NO_PHONE_NUMBER, project__slug=notification.project_slug) + .python_value + if notification.project_slug + else False + ) + rec_list = [] + for usr in self._recipients: + rec_list.append( + { + k: v + for k, v in get_user_model().objects.get(pk=usr).userprofile.__dict__.items() + if not k.startswith("_") and isinstance(v, (str, list, tuple, int, float)) + } + ) + notification.extra_data["recipients-list"] = rec_list + notification.extra_data["sender"] = notification.sender + notification.extra_data["mail-fallback"] = mail_fallback + notification.save(update_fields=["extra_data"]) + return notification def _ensure_channels( diff --git a/django_project_base/notifications/migrations/0011_djangoprojectbasenotification_extra_data.py b/django_project_base/notifications/migrations/0011_djangoprojectbasenotification_extra_data.py new file mode 100644 index 00000000..4452c2c3 --- /dev/null +++ b/django_project_base/notifications/migrations/0011_djangoprojectbasenotification_extra_data.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.4 on 2023-11-20 13:51 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("notifications", "0010_djangoprojectbasenotification_send_at"), + ] + + operations = [ + migrations.AddField( + model_name="djangoprojectbasenotification", + name="extra_data", + field=models.JSONField(null=True), + ), + ] diff --git a/django_project_base/notifications/models.py b/django_project_base/notifications/models.py index 9b2b60c9..eec42914 100644 --- a/django_project_base/notifications/models.py +++ b/django_project_base/notifications/models.py @@ -80,6 +80,7 @@ class AbstractDjangoProjectBaseNotification(models.Model): send_notification_sms = models.BooleanField(null=False, blank=False, default=False) send_notification_sms_text = models.TextField(blank=False, null=True) send_at = models.BigIntegerField(blank=False, null=True) + extra_data = models.JSONField(null=True, blank=False) class Meta: abstract = True diff --git a/django_project_base/notifications/rest/notification.py b/django_project_base/notifications/rest/notification.py index 8b7ad930..b340d7a8 100644 --- a/django_project_base/notifications/rest/notification.py +++ b/django_project_base/notifications/rest/notification.py @@ -253,6 +253,7 @@ class Meta: "delayed_to", "recipients_original_payload_search", "exceptions", + "extra_data", ) layout = Layout( Row(Column("message_to")),