shiftregister/shiftregister/app/tasks.py

87 lines
2.6 KiB
Python

from celery import shared_task
from .models import Message, ShiftRegistration
from django.conf import settings
from django.db import transaction
from django.utils import timezone
from dynamic_preferences.registries import global_preferences_registry
from .sipgate.sms import send as send_sms
import sentry_sdk
global_preferences = global_preferences_registry.manager()
def send(msg):
if not (
settings.SIPGATE_SMS_EXTENSION
and settings.SIPGATE_TOKEN
and settings.SIPGATE_TOKEN_ID
):
print(f"would send message to {msg.to.phone}\n---\n{msg.text}")
return
send_sms(str(msg.to.phone), msg.text)
# cron task to send normal messages(reminders,changes) in batches
@shared_task
def send_messages():
if not global_preferences["helper__send_sms"]:
print("sms disabled, not sending")
return
msgs = Message.objects.select_for_update().filter(sent_at__isnull=True)[
: global_preferences["helper__sms_rate"] * 2
]
with transaction.atomic():
for msg in msgs:
if msg.sent_at:
continue
try:
send(msg)
msg.sent_at = timezone.now()
msg.save()
except Exception as e:
sentry_sdk.capture_exception(e)
# singlemessage so registration links arrive faster.
# will silently fail when messages are disabled.
# those messages will be picked up by the cron send later
# once we have decided to continue sending messages
@shared_task
def send_message(msgid, is_retry=False):
if not global_preferences["helper__send_sms"]:
return
try:
with transaction.atomic():
msg = Message.objects.select_for_update().get(pk=msgid)
if msg.sent_at:
return
send(msg)
msg.sent_at = timezone.now()
msg.save()
except Message.DoesNotExist:
if not is_retry:
print("message not found, retrying")
send_message.apply_async((msgid, True), countdown=0.2)
else:
print(f"message {msgid} not found in retry, giving up")
@shared_task
def send_reminders():
regs = ShiftRegistration.objects.select_for_update().filter(
reminder_sent=False,
shift__start_at__lte=timezone.now()
+ global_preferences["helper__reminder_time"],
)
with transaction.atomic():
for reg in regs:
if reg.reminder_sent:
continue
try:
reg.send_reminder()
except Exception as e:
sentry_sdk.capture_exception(e)