Notification emails #80
@ -1,5 +1,4 @@
|
||||
"""Send user notifications as emails, at most once delivery."""
|
||||
from collections import defaultdict
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
@ -15,37 +14,33 @@ logger.setLevel(logging.INFO)
|
||||
|
||||
class Command(BaseCommand):
|
||||
def handle(self, *args, **options): # noqa: D102
|
||||
logger.info('start, checking for outstanding notifications')
|
||||
notifications = Notification.objects.filter(processed_by_mailer_at=None)
|
||||
batched_by_recipient = defaultdict(list)
|
||||
for n in notifications:
|
||||
batched_by_recipient[n.recipient].append(n)
|
||||
|
||||
for recipient, batch in batched_by_recipient.items():
|
||||
to_send = []
|
||||
for n in batch:
|
||||
unprocessed_notifications = Notification.objects.filter(processed_by_mailer_at=None)
|
||||
for n in unprocessed_notifications:
|
||||
logger.info(f'processing Notification pk={n.pk}')
|
||||
n.processed_by_mailer_at = timezone.now()
|
||||
recipient = n.recipient
|
||||
if not recipient.is_subscribed_to_notification_emails:
|
||||
logger.info(f'{recipient} is not subscribed, skipping')
|
||||
n.save()
|
||||
continue
|
||||
# check that email is confirmed to avoid spamming unsuspecting email owners
|
||||
if recipient.confirmed_email_at is None:
|
||||
logger.info(f'{recipient} has unconfirmed email, skipping')
|
||||
n.save()
|
||||
continue
|
||||
n.sent = True
|
||||
to_send.append(n)
|
||||
# first mark as processed, then send: avoid spamming in case of a crash-loop
|
||||
Notification.objects.bulk_update(batch, ['processed_by_mailer_at', 'sent'])
|
||||
if len(to_send) > 0:
|
||||
logger.info(f'sending an email to {recipient} about {len(to_send)} notifications')
|
||||
send_batch_notification_email(recipient, to_send)
|
||||
logger.info('finish')
|
||||
n.save()
|
||||
logger.info(f'sending an email to {recipient}: {n.action}')
|
||||
send_notification_email(n)
|
||||
|
||||
|
||||
def send_batch_notification_email(recipient, notifications):
|
||||
def send_notification_email(notification):
|
||||
subject = 'New activity'
|
||||
message = '\n\n'.join([n.format_email_txt() for n in notifications])
|
||||
message = notification.format_email_txt()
|
||||
send_mail(
|
||||
subject,
|
||||
message,
|
||||
settings.DEFAULT_FROM_EMAIL,
|
||||
[recipient.email],
|
||||
[notification.recipient.email],
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user