diff --git a/admin_api/urls.py b/admin_api/urls.py index 8e89a7e..4fb1c0d 100644 --- a/admin_api/urls.py +++ b/admin_api/urls.py @@ -88,6 +88,7 @@ urlpatterns = [ path('notifications/schedules//recipients/', views.NotificationRecipientView.as_view(), name='notification-recipient-create'), path('notifications/schedules//recipients//', views.NotificationRecipientDetailView.as_view(), name='notification-recipient-detail'), path('notifications/schedules//send-now/', views.NotificationScheduleSendNowView.as_view(), name='notification-schedule-send-now'), + path('notifications/schedules//test-send/', views.NotificationScheduleTestSendView.as_view(), name='notification-schedule-test-send'), # Ad Control path('ad-control/', include('ad_control.urls')), diff --git a/admin_api/views.py b/admin_api/views.py index 471afa1..443d68e 100644 --- a/admin_api/views.py +++ b/admin_api/views.py @@ -2783,3 +2783,51 @@ class NotificationScheduleSendNowView(APIView): 'recipientCount': recipient_count, 'schedule': _serialize_schedule(schedule), }) + + +class NotificationScheduleTestSendView(APIView): + """Send a preview of this schedule's email to a single address. + + Does NOT update last_run_at / last_status — purely for previewing content. + """ + permission_classes = [IsAuthenticated] + + def post(self, request, pk): + from notifications.models import NotificationSchedule + from notifications.emails import BUILDERS + from django.conf import settings + from django.core.mail import EmailMessage + from django.shortcuts import get_object_or_404 + + schedule = get_object_or_404(NotificationSchedule, pk=pk) + + email = (request.data.get('email') or '').strip().lower() + if not email: + return Response({'error': 'email is required'}, status=400) + + builder = BUILDERS.get(schedule.notification_type) + if builder is None: + return Response( + {'error': f'No builder for type: {schedule.notification_type}'}, + status=400, + ) + + try: + subject, html = builder(schedule) + subject = f'[TEST] {subject}' + msg = EmailMessage( + subject=subject, + body=html, + from_email=settings.DEFAULT_FROM_EMAIL, + to=[email], + ) + msg.content_subtype = 'html' + msg.send(fail_silently=False) + except Exception as exc: # noqa: BLE001 + log('error', f'Test-send failed for schedule #{pk}: {exc}', + request=request, user=request.user) + return Response({'error': str(exc)}, status=500) + + log('info', f'Test email sent for schedule #{pk} → {email}', + request=request, user=request.user) + return Response({'ok': True, 'sentTo': email})