Coverage for src/expo_notifications/tasks/check_receipts_task.py: 100%
30 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-10 02:00 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-10 02:00 +0000
1from celery import shared_task
2from django.utils import timezone
3from exponent_server_sdk import (
4 DeviceNotRegisteredError,
5 PushClient,
6 PushReceipt,
7 PushServerError,
8 PushTicketError,
9)
10from requests.exceptions import ConnectionError, HTTPError
12from expo_notifications.conf import settings
13from expo_notifications.models import Receipt, Ticket
14from expo_notifications.tasks.session import session
17@shared_task(
18 bind=True,
19 ignore_result=True,
20 max_retries=settings.checking_task_max_retries,
21 default_retry_delay=settings.checking_task_retry_delay.total_seconds(),
22)
23def check_receipts(self, ticket_pks: list[str]) -> None:
24 tickets = Ticket.objects.filter(pk__in=ticket_pks).exclude(external_id="")
26 push_tickets = [ticket.to_push_ticket() for ticket in tickets]
28 push_client = PushClient(session=session)
30 try:
31 push_receipts: list[PushReceipt] = push_client.check_receipts_multiple(
32 push_tickets
33 )
34 except PushServerError:
35 raise self.retry()
36 except (ConnectionError, HTTPError):
37 raise self.retry()
39 receipts: list[Receipt] = []
41 for push_receipt in push_receipts:
42 ticket = tickets.get(external_id=push_receipt.id)
44 try:
45 push_receipt.validate_response()
46 except DeviceNotRegisteredError:
47 ticket.message.device.is_active = False
48 ticket.message.device.save()
49 except PushTicketError:
50 pass
52 receipts.append(
53 Receipt(
54 ticket=ticket,
55 is_success=push_receipt.is_success(),
56 error_message=push_receipt.message,
57 date_checked=timezone.now(),
58 )
59 )
61 Receipt.objects.bulk_create(receipts)