diff --git a/doc/api/webhooks.rst b/doc/api/webhooks.rst index bd88f13e09..c4937985e9 100644 --- a/doc/api/webhooks.rst +++ b/doc/api/webhooks.rst @@ -70,6 +70,9 @@ and ``checkin_list``. only include the minimum amount of data necessary for you to fetch the changed objects from our :ref:`rest-api` in an authenticated way. +.. warning:: In very rare cases, you could receive the same webhook notification twice. We try to avoid it, but we + prefer it over missing a notification. + If you want to further prevent others from accessing your webhook URL, you can also use `Basic authentication`_ and supply the URL to us in the format of ``https://username:password@domain.com/path/``. We recommend that you use HTTPS for your webhook URL and might require it in the future. If HTTPS is used, we require diff --git a/src/pretix/api/webhooks.py b/src/pretix/api/webhooks.py index bb7d622de6..631429ba8a 100644 --- a/src/pretix/api/webhooks.py +++ b/src/pretix/api/webhooks.py @@ -168,7 +168,7 @@ def register_default_webhook_events(sender, **kwargs): ) -@app.task(base=TransactionAwareTask) +@app.task(base=TransactionAwareTask, acks_late=True) def notify_webhooks(logentry_id: int): logentry = LogEntry.all.select_related('event', 'event__organizer').get(id=logentry_id) @@ -205,7 +205,7 @@ def notify_webhooks(logentry_id: int): send_webhook.apply_async(args=(logentry_id, notification_type.action_type, wh.pk)) -@app.task(base=ProfiledTask, bind=True, max_retries=9) +@app.task(base=ProfiledTask, bind=True, max_retries=9, acks_late=True) def send_webhook(self, logentry_id: int, action_type: str, webhook_id: int): # 9 retries with 2**(2*x) timing is roughly 72 hours with scopes_disabled(): diff --git a/src/pretix/base/services/cancelevent.py b/src/pretix/base/services/cancelevent.py index a3e50c9760..f7f5c7f565 100644 --- a/src/pretix/base/services/cancelevent.py +++ b/src/pretix/base/services/cancelevent.py @@ -81,7 +81,8 @@ def _send_mail(order: Order, subject: LazyI18nString, message: LazyI18nString, s logger.exception('Order canceled email could not be sent to attendee') -@app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(OrderError,)) +@app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(OrderError,), + acks_late=True) def cancel_event(self, event: Event, subevent: int, auto_refund: bool, keep_fee_fixed: str, keep_fee_percentage: str, keep_fees: list=None, manual_refund: bool=False, send: bool=False, send_subject: dict=None, send_message: dict=None, diff --git a/src/pretix/base/services/mail.py b/src/pretix/base/services/mail.py index d4944bb1fa..6e9ab62dcd 100644 --- a/src/pretix/base/services/mail.py +++ b/src/pretix/base/services/mail.py @@ -250,7 +250,7 @@ class CustomEmail(EmailMultiAlternatives): return super()._create_mime_attachment(content, mimetype) -@app.task(base=TransactionAwareTask, bind=True) +@app.task(base=TransactionAwareTask, bind=True, acks_late=True) def mail_send_task(self, *args, to: List[str], subject: str, body: str, html: str, sender: str, event: int=None, position: int=None, headers: dict=None, bcc: List[str]=None, invoices: List[int]=None, order: int=None, attach_tickets=False, user=None, diff --git a/src/pretix/base/services/notifications.py b/src/pretix/base/services/notifications.py index 9ce6973088..ae3f5c1413 100644 --- a/src/pretix/base/services/notifications.py +++ b/src/pretix/base/services/notifications.py @@ -13,7 +13,7 @@ from pretix.celery_app import app from pretix.helpers.urls import build_absolute_uri -@app.task(base=TransactionAwareTask) +@app.task(base=TransactionAwareTask, acks_late=True) @scopes_disabled() def notify(logentry_id: int): logentry = LogEntry.all.select_related('event', 'event__organizer').get(id=logentry_id) @@ -66,7 +66,7 @@ def notify(logentry_id: int): send_notification.apply_async(args=(logentry_id, notification_type.action_type, user.pk, method)) -@app.task(base=ProfiledTask) +@app.task(base=ProfiledTask, acks_late=True) def send_notification(logentry_id: int, action_type: str, user_id: int, method: str): logentry = LogEntry.all.get(id=logentry_id) if logentry.event: diff --git a/src/pretix/base/services/tickets.py b/src/pretix/base/services/tickets.py index 70033c21a4..1d1f70de54 100644 --- a/src/pretix/base/services/tickets.py +++ b/src/pretix/base/services/tickets.py @@ -175,7 +175,7 @@ def get_tickets_for_order(order, base_position=None): return tickets -@app.task(base=EventTask) +@app.task(base=EventTask, acks_late=True) def invalidate_cache(event: Event, item: int=None, provider: str=None, order: int=None, **kwargs): qs = CachedTicket.objects.filter(order_position__order__event=event) qsc = CachedCombinedTicket.objects.filter(order__event=event) diff --git a/src/pretix/base/services/vouchers.py b/src/pretix/base/services/vouchers.py index 68fa711394..d39bdc9cb1 100644 --- a/src/pretix/base/services/vouchers.py +++ b/src/pretix/base/services/vouchers.py @@ -9,7 +9,7 @@ from pretix.base.services.tasks import TransactionAwareProfiledEventTask from pretix.celery_app import app -@app.task(base=TransactionAwareProfiledEventTask) +@app.task(base=TransactionAwareProfiledEventTask, acks_late=True) def vouchers_send(event: Event, vouchers: list, subject: str, message: str, recipients: list, user: int) -> None: vouchers = list(Voucher.objects.filter(id__in=vouchers).order_by('id')) user = User.objects.get(pk=user)