Internal
Public Access
Fix daily email timing to work across all timezones
Critical fix: Task now runs every hour instead of once at 6 AM UTC. This ensures users in all timezones receive their email at 6 AM local time. Changes: - Run task every hour instead of once daily - Check if it's 6-7 AM in user's timezone (1 hour window) - Track sent emails in Notification model to prevent duplicates - Add 'daily_email' notification type Without this fix, users in timezones where 6 AM UTC is not morning would never receive their daily email. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.5
parent
03cfdea42d
commit
aca8abca56
+1
-1
@@ -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',
|
||||
|
||||
@@ -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)
|
||||
|
||||
+23
-2
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user