From 2e2a51db1d5dc9c5fbb7a1aaa0e98b0d1bcf97cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Mart=C3=ADn?= Date: Tue, 3 Jun 2025 15:41:43 +0200 Subject: [PATCH 1/2] Improve error web push treatments --- push_notifications/models.py | 9 +++-- push_notifications/webpush.py | 62 ++++++++++++++++++++++++++++------- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/push_notifications/models.py b/push_notifications/models.py index 8c95cff5..27ae42b5 100644 --- a/push_notifications/models.py +++ b/push_notifications/models.py @@ -242,12 +242,11 @@ def get_queryset(self): class WebPushDeviceQuerySet(models.query.QuerySet): def send_message(self, message, **kwargs): + from .webpush import webpush_send_bulk_message devices = self.filter(active=True).order_by("application_id").distinct() - res = [] - for device in devices: - res.append(device.send_message(message)) - - return res + ret = [] + ret.append(webpush_send_bulk_message(devices, message, **kwargs)) + return ret class WebPushDevice(Device): diff --git a/push_notifications/webpush.py b/push_notifications/webpush.py index de379431..837f2860 100644 --- a/push_notifications/webpush.py +++ b/push_notifications/webpush.py @@ -5,6 +5,8 @@ from .conf import get_manager from .exceptions import WebPushError +from .models import WebPushDevice + def get_subscription_info(application_id, uri, browser, auth, p256dh): if uri.startswith("https://"): @@ -26,12 +28,43 @@ def get_subscription_info(application_id, uri, browser, auth, p256dh): } -def webpush_send_message(device, message, **kwargs): +def webpush_send_bulk_message(devices, message, **kwargs): + results = { + "success": 0, + "failure": 0, + "results": []} + exception_message = '' + for device in devices: + try: + webpush_send_message(device, message, results=results, **kwargs) + except WebPushError as e: + if exception_message != '': + exception_message += '\n\n' + exception_message += f'{e} device pk: {device.pk}' + + ids_to_disable = [] + for result in results["results"]: + if "error" in result: + ids_to_disable.append(result["original_registration_id"]) + WebPushDevice.objects.filter(registration_id__in=ids_to_disable).update(active=False) + + if exception_message: + raise WebPushError(exception_message) + + return results + + +def webpush_send_message(device, message, results=None, **kwargs): + bulk = results is not None + if not bulk: + results = { + "success": 0, + "failure": 0, + "results": []} subscription_info = get_subscription_info( device.application_id, device.registration_id, device.browser, device.auth, device.p256dh) try: - results = {"results": [{"original_registration_id": device.registration_id}]} response = webpush( subscription_info=subscription_info, data=message, @@ -40,16 +73,23 @@ def webpush_send_message(device, message, **kwargs): **kwargs ) if response.ok: - results["success"] = 1 + results["success"] += 1 + results["results"].append({'original_registration_id': device.registration_id}) else: - results["failure"] = 1 - results["results"][0]["error"] = response.content + results["failure"] += 1 + results["results"].append({'error': response.content, + 'original_registration_id': device.registration_id}) return results except WebPushException as e: - if e.response is not None and e.response.status_code in [404, 410]: - results["failure"] = 1 - results["results"][0]["error"] = e.message - device.active = False - device.save() + exception_message = str(e) + if e.response is not None and e.response.status_code in [400, 404, 410]: + results["failure"] += 1 + results["results"].append( + {'error': exception_message, + 'original_registration_id': device.registration_id}) + if not bulk: + device.active = False + device.save(update_fields=('active',)) return results - raise WebPushError(e.message) + raise WebPushError(exception_message) + From f04c2defec51bf36e5f0790f68b70c2960015350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Mart=C3=ADn?= Date: Tue, 3 Jun 2025 15:53:20 +0200 Subject: [PATCH 2/2] Fix end-of-file-fixer --- push_notifications/webpush.py | 1 - 1 file changed, 1 deletion(-) diff --git a/push_notifications/webpush.py b/push_notifications/webpush.py index 837f2860..23b214df 100644 --- a/push_notifications/webpush.py +++ b/push_notifications/webpush.py @@ -92,4 +92,3 @@ def webpush_send_message(device, message, results=None, **kwargs): device.save(update_fields=('active',)) return results raise WebPushError(exception_message) -