from typing import List, Union from django.core.mail import send_mail, EmailMessage from django.contrib.auth import get_user_model from django.template.loader import render_to_string from django.conf import settings # To access EMAIL_HOST_USER, etc. from recruitment.models import Message UserModel = get_user_model() User = UserModel # Type alias for clarity class EmailService: """ A service class for sending single or bulk emails. """ def _send_email_internal( self, subject: str, body: str, recipient_list: List[str], context:dict, from_email: str = settings.DEFAULT_FROM_EMAIL, html_content: Union[str, None] = None, ) -> int: """ Internal method to handle the actual sending using Django's email backend. """ try: # Using EmailMessage for more control (e.g., HTML content) for recipient in recipient_list: email = EmailMessage( subject=subject, body=body, from_email=from_email, to=[recipient], ) if html_content: email.content_subtype = "html" # Main content is HTML email.body = html_content # Overwrite body with HTML # Returns the number of successfully sent emails (usually 1 or the count of recipients) result=email.send(fail_silently=False) recipient_user=User.objects.filter(email=recipient).first() if result and recipient_user and not context["message_created"]: Message.objects.create(sender=context['sender_user'],recipient=recipient_user,job=context['job'],subject=subject,content=context['email_message'],message_type='DIRECT',is_read=False) return len(recipient_list) except Exception as e: # Log the error (in a real app, use Django's logger) print(f"Error sending email to {recipient_list}: {e}") return 0 # def send_single_email( # self, # user: User, # subject: str, # template_name: str, # context: dict, # from_email: str = settings.DEFAULT_FROM_EMAIL # ) -> int: # """ # Sends a single, template-based email to one user. # """ # recipient_list = [user.email] # # 1. Render content from template # html_content = render_to_string(template_name, context) # # You can optionally render a plain text version as well: # # text_content = strip_tags(html_content) # # 2. Call internal sender # return self._send_email_internal( # subject=subject, # body="", # Can be empty if html_content is provided # recipient_list=recipient_list, # from_email=from_email, # html_content=html_content # ) def send_email_service( self, recipient_emails: List[str], subject: str, template_name: str, context: dict, from_email: str = settings.DEFAULT_FROM_EMAIL ) -> int: """ Sends the same template-based email to a list of email addresses. Note: Django's EmailMessage can handle multiple recipients in one transaction, which is often more efficient than sending them one-by-one. """ # 1. Render content from template (once) html_content = render_to_string(template_name, context) # 2. Call internal sender with all recipients # The result here is usually 1 if successful, as it uses a single # EmailMessage call for all recipients. sent_count = self._send_email_internal( subject=subject, body="", recipient_list=recipient_emails, context=context, from_email=from_email, html_content=html_content, ) # Return the count of recipients if successful, or 0 if failure return len(recipient_emails) if sent_count > 0 else 0