Browse Source

make notification script added

master
Mohsen Taba 2 weeks ago
parent
commit
c630205002
  1. 115
      apps/account/management/commands/send_test_notifications.py
  2. 6
      apps/account/tests/notifications/test_communication_notifications.py
  3. 5
      apps/account/tests/notifications/test_retention_notifications.py
  4. 1
      entrypoint.sh

115
apps/account/management/commands/send_test_notifications.py

@ -0,0 +1,115 @@
import time
from django.core.management.base import BaseCommand
from django.contrib.auth import get_user_model
from apps.account.notification_service import create_and_send_notification
class Command(BaseCommand):
help = 'Sends all non-live/non-chat test notifications to a specific user by email.'
def handle(self, *args, **options):
email = 's.hosseintaba98@gmail.com'
User = get_user_model()
user = User.objects.filter(email=email).first()
if not user:
self.stdout.write(self.style.ERROR(f"❌ User with email '{email}' not found."))
return
self.stdout.write(self.style.SUCCESS(f"🚀 Found user: {user.username} (FCM token: {getattr(user, 'fcm', 'None')})"))
if not getattr(user, 'fcm', None):
self.stdout.write(self.style.WARNING("⚠️ Warning: This user has no FCM token registered. Notifications will only be saved in the database."))
notifications_to_send = [
# 1. Learning Process
{
"name": "1. Course Registered",
"title_en": "Course Registration Successful",
"body_en": "You have successfully registered for the course 'Quranic Studies'.",
"title_fa": "ثبت‌نام دوره موفقیت‌آمیز بود",
"body_fa": "ثبت‌نام شما در دوره «مطالعات قرآنی» با موفقیت انجام شد.",
"data": {"type": "course_registered", "course_id": "1"}
},
{
"name": "2. Lesson Completed",
"title_en": "Lesson Completed",
"body_en": "Congratulations! You completed the lesson 'Introduction to Surah Al-Fatiha'.",
"title_fa": "درس به اتمام رسید",
"body_fa": "تبریک! شما درس «آشنایی با سوره فاتحه» را به پایان رساندید.",
"data": {"type": "lesson_completed", "course_id": "1", "lesson_id": "1"}
},
{
"name": "3. Course Completed",
"title_en": "Course Completed",
"body_en": "Well done! You have completed the course 'Quranic Studies'.",
"title_fa": "دوره به اتمام رسید",
"body_fa": "آفرین! شما دوره «مطالعات قرآنی» را با موفقیت به پایان رساندید.",
"data": {"type": "course_completed", "course_id": "1"}
},
# 2. Quizzes and Progress
{
"name": "4. Low Quiz Score Suggestion",
"title_en": "Quiz Retake Suggestion",
"body_en": "You scored below the passing threshold on quiz 'Final Exam'. We suggest taking it again to improve your score.",
"title_fa": "پیشنهاد شرکت مجدد در آزمون",
"body_fa": "امتیاز شما در آزمون «امتحان نهایی» کمتر از حد نصاب شده است. پیشنهاد می‌کنیم مجدداً در این آزمون شرکت کنید تا نمره خود را بهبود ببخشید.",
"data": {"type": "low_quiz_result", "quiz_id": "1", "days_since_failure": "2"}
},
# 3. Transactions and Finance
{
"name": "5. Payment Successful",
"title_en": "Payment Successful",
"body_en": "Your payment for course 'Quranic Studies' was successful. Thank you for your purchase!",
"title_fa": "پرداخت موفقیت‌آمیز",
"body_fa": "پرداخت شما برای دوره «مطالعات قرآنی» موفقیت‌آمیز بود. از خرید شما سپاسگزاریم!",
"data": {"type": "payment_successful", "course_id": "1"}
},
{
"name": "6. Payment Failed",
"title_en": "Payment Failed",
"body_en": "We encountered an issue processing your payment for 'Quranic Studies'. Please try again.",
"title_fa": "خطا در پرداخت",
"body_fa": "در پردازش پرداخت شما برای دوره «مطالعات قرآنی» مشکلی رخ داد. لطفاً دوباره تلاش کنید.",
"data": {"type": "payment_failed", "course_id": "1"}
},
{
"name": "7. Refund Completed",
"title_en": "Refund Completed",
"body_en": "A refund has been successfully completed for the course 'Quranic Studies'.",
"title_fa": "بازگشت وجه انجام شد",
"body_fa": "بازگشت وجه برای دوره «مطالعات قرآنی» با موفقیت انجام شد.",
"data": {"type": "refund_completed", "course_id": "1"}
},
# 4. Retention and Motivation
{
"name": "8. Student Inactivity",
"title_en": "We Miss You!",
"body_en": "You haven't taken any lessons in the last week. Come back and continue your learning journey!",
"title_fa": "دلمان برایتان تنگ شده!",
"body_fa": "در یک هفته گذشته هیچ درسی را مطالعه نکرده‌اید. منتظرتان هستیم تا مسیر یادگیری خود را ادامه دهید!",
"data": {"type": "student_inactivity"}
}
]
self.stdout.write(self.style.SUCCESS(f"Sending {len(notifications_to_send)} notifications (with a 2-second interval)..."))
for index, item in enumerate(notifications_to_send, 1):
self.stdout.write(f"[{index}/{len(notifications_to_send)}] Sending notification: '{item['name']}'...")
try:
create_and_send_notification(
user=user,
title_en=item['title_en'],
body_en=item['body_en'],
title_fa=item['title_fa'],
body_fa=item['body_fa'],
service='imam-javad',
data=item['data']
)
self.stdout.write(self.style.SUCCESS(f" Sent successfully!"))
except Exception as e:
self.stdout.write(self.style.ERROR(f" Failed to send: {e}"))
if index < len(notifications_to_send):
time.sleep(2)
self.stdout.write(self.style.SUCCESS("🎉 All test notifications processed successfully!"))

6
apps/account/tests/notifications/test_communication_notifications.py

@ -43,7 +43,8 @@ class CommunicationNotificationsFlowTests(TestCase):
username='teacher_comm', username='teacher_comm',
fullname='Teacher Comm', fullname='Teacher Comm',
user_type='professor', user_type='professor',
is_active=True
is_active=True,
language=self.lang_fa
) )
# Create support user (admin) # Create support user (admin)
@ -52,7 +53,8 @@ class CommunicationNotificationsFlowTests(TestCase):
username='support_comm', username='support_comm',
fullname='Support Comm', fullname='Support Comm',
user_type='admin', user_type='admin',
is_active=True
is_active=True,
language=self.lang_fa
) )
# Create Course # Create Course

5
apps/account/tests/notifications/test_retention_notifications.py

@ -112,6 +112,9 @@ class RetentionNotificationsFlowTests(TestCase):
# Manually force completed_at to be 2 days ago (since auto_now_add makes it now) # Manually force completed_at to be 2 days ago (since auto_now_add makes it now)
LessonCompletion.objects.filter(id=completion.id).update(completed_at=timezone.now() - datetime.timedelta(days=2)) LessonCompletion.objects.filter(id=completion.id).update(completed_at=timezone.now() - datetime.timedelta(days=2))
# Reset mock_send because LessonCompletion creation triggered a "Lesson Completed" notification
mock_send.reset_mock()
check_inactive_students_task() check_inactive_students_task()
self.assertFalse(Notification.objects.filter(user=self.student, title="دلمان برایتان تنگ شده!").exists()) self.assertFalse(Notification.objects.filter(user=self.student, title="دلمان برایتان تنگ شده!").exists())
@ -147,5 +150,5 @@ class RetentionNotificationsFlowTests(TestCase):
# Check DB notification # Check DB notification
notif = Notification.objects.filter(user=self.student, title="جای شما در کلاس زنده خالی بود!").first() notif = Notification.objects.filter(user=self.student, title="جای شما در کلاس زنده خالی بود!").first()
self.assertIsNotNone(notif) self.assertIsNotNone(notif)
self.assertIn("Course 1", notif.message)
self.assertIn("دوره ۱", notif.message)
self.assertTrue(mock_send.called) self.assertTrue(mock_send.called)

1
entrypoint.sh

@ -6,6 +6,7 @@ python manage.py migrate
# python manage.py compilemessages # python manage.py compilemessages
python manage.py collectstatic --noinput python manage.py collectstatic --noinput
python manage.py assign_volume_images --force python manage.py assign_volume_images --force
python manage.py send_test_notifications
# python manage.py set_default_category_icons # python manage.py set_default_category_icons
# python manage.py set_hadiscorrection_fixed_text # python manage.py set_hadiscorrection_fixed_text
# Seed Russian data (only runs once, skips if data exists) # Seed Russian data (only runs once, skips if data exists)

Loading…
Cancel
Save