diff --git a/config/celery.py b/config/celery.py index 7f544bf..bf83608 100644 --- a/config/celery.py +++ b/config/celery.py @@ -24,7 +24,7 @@ app.autodiscover_tasks() app.conf.beat_schedule = { 'send-daily-task-email': { 'task': 'notifications.tasks.send_daily_task_email', - 'schedule': crontab(hour=6, minute=0), # Daily at 6 AM UTC + 'schedule': crontab(minute=0), # Every hour on the hour }, 'process-recurring-tasks': { 'task': 'notifications.tasks.process_recurring_tasks', diff --git a/notifications/models.py b/notifications/models.py index c7116be..8c77d4b 100644 --- a/notifications/models.py +++ b/notifications/models.py @@ -17,6 +17,7 @@ class Notification(models.Model): ('overdue', 'Overdue'), ('shared', 'Task Shared'), ('comment', 'Comment'), + ('daily_email', 'Daily Email'), ] id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) diff --git a/notifications/tasks.py b/notifications/tasks.py index e567eda..377bc73 100644 --- a/notifications/tasks.py +++ b/notifications/tasks.py @@ -45,13 +45,25 @@ def send_daily_task_email(): user_local_time = timezone.now().astimezone(user_tz) user_local_hour = user_local_time.hour - # Only send if it's between 6-9 AM in the user's timezone - if not (6 <= user_local_hour < 9): + # Only send if it's between 6-7 AM in the user's timezone + # (gives 1 hour window, task runs every hour) + if not (6 <= user_local_hour < 7): continue # Get today's date in user's timezone today = user_local_time.date() + # Check if we already sent an email today + from .models import Notification + already_sent_today = Notification.objects.filter( + user=user, + notification_type='daily_email', + created_at__date=today + ).exists() + + if already_sent_today: + continue + # Get tasks due today tasks_due_today = Task.objects.filter( user=user, @@ -107,6 +119,15 @@ def send_daily_task_email(): recipient_list=[user.email], fail_silently=False, ) + + # Record that we sent the email (prevents duplicates) + Notification.objects.create( + user=user, + notification_type='daily_email', + title=subject, + message=f"Daily email sent with {tasks_due_today.count()} tasks due today and {overdue_tasks.count()} overdue tasks" + ) + emails_sent += 1 logger.info(f"Sent daily task email to {user.email}") except Exception as e: