119 lines
4.1 KiB
Python
119 lines
4.1 KiB
Python
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)
|
|
from time import sleep
|
|
for recipient in recipient_list:
|
|
sleep(2)
|
|
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,
|
|
|
|
)
|
|
print(f"Bulk email sent to {sent_count} recipients.")
|
|
|
|
# Return the count of recipients if successful, or 0 if failure
|
|
return len(recipient_emails) if sent_count > 0 else 0
|