update
This commit is contained in:
@@ -5,16 +5,54 @@ Handles automatic notifications when tickets are updated
|
||||
|
||||
from django.db.models.signals import post_save, pre_save
|
||||
from django.dispatch import receiver
|
||||
from django.core.mail import EmailMultiAlternatives
|
||||
from django.core.mail import EmailMultiAlternatives, get_connection
|
||||
from django.template.loader import render_to_string
|
||||
from django.conf import settings
|
||||
import logging
|
||||
import time
|
||||
|
||||
from .models import SupportTicket, TicketMessage, TicketActivity
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _send_email_with_retry(email_message, max_retries: int = 3, delay: float = 1.0) -> bool:
|
||||
"""
|
||||
Send email with retry logic for production reliability.
|
||||
Uses Django settings from .env file.
|
||||
|
||||
Args:
|
||||
email_message: EmailMultiAlternatives instance
|
||||
max_retries: Maximum number of retry attempts
|
||||
delay: Delay between retries in seconds
|
||||
|
||||
Returns:
|
||||
bool: True if email was sent successfully, False otherwise
|
||||
"""
|
||||
for attempt in range(max_retries + 1):
|
||||
try:
|
||||
# Test connection before sending (uses EMAIL_BACKEND from settings)
|
||||
connection = get_connection()
|
||||
connection.open()
|
||||
connection.close()
|
||||
|
||||
# Send the email (uses EMAIL_BACKEND and credentials from settings)
|
||||
email_message.send()
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"Email send attempt {attempt + 1} failed: {str(e)}")
|
||||
|
||||
if attempt < max_retries:
|
||||
time.sleep(delay * (2 ** attempt)) # Exponential backoff
|
||||
continue
|
||||
else:
|
||||
logger.error(f"Failed to send email after {max_retries + 1} attempts: {str(e)}")
|
||||
return False
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class TicketUpdateNotifier:
|
||||
"""Service for sending ticket update notifications"""
|
||||
|
||||
@@ -34,6 +72,8 @@ class TicketUpdateNotifier:
|
||||
'status_color': ticket.status.color if ticket.status else '#3b82f6',
|
||||
'updated_at': ticket.updated_at.strftime('%B %d, %Y at %I:%M %p'),
|
||||
'support_url': f'{settings.SITE_URL}/support-center',
|
||||
'logo_url': f'{settings.SITE_URL}/images/logo.png',
|
||||
'site_url': settings.SITE_URL,
|
||||
}
|
||||
|
||||
# Render HTML email
|
||||
@@ -48,19 +88,24 @@ class TicketUpdateNotifier:
|
||||
context
|
||||
)
|
||||
|
||||
# Create email
|
||||
# Create email (uses DEFAULT_FROM_EMAIL from settings)
|
||||
email = EmailMultiAlternatives(
|
||||
subject=subject,
|
||||
body=text_message,
|
||||
from_email=settings.DEFAULT_FROM_EMAIL,
|
||||
from_email=settings.DEFAULT_FROM_EMAIL, # From .env file
|
||||
to=[ticket.user_email],
|
||||
)
|
||||
|
||||
email.attach_alternative(html_message, "text/html")
|
||||
email.send(fail_silently=False)
|
||||
|
||||
logger.info(f'Status change notification sent for ticket {ticket.ticket_number}')
|
||||
return True
|
||||
# Send email with retry logic (uses EMAIL_BACKEND and credentials from settings)
|
||||
success = _send_email_with_retry(email)
|
||||
|
||||
if success:
|
||||
logger.info(f'Status change notification sent for ticket {ticket.ticket_number}')
|
||||
else:
|
||||
logger.error(f'Failed to send status change notification for ticket {ticket.ticket_number} after retries')
|
||||
return success
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f'Failed to send status change notification: {str(e)}')
|
||||
@@ -85,6 +130,8 @@ class TicketUpdateNotifier:
|
||||
'message_author': message.author_name or 'Support Team',
|
||||
'created_at': message.created_at.strftime('%B %d, %Y at %I:%M %p'),
|
||||
'support_url': f'{settings.SITE_URL}/support-center',
|
||||
'logo_url': f'{settings.SITE_URL}/images/logo.png',
|
||||
'site_url': settings.SITE_URL,
|
||||
}
|
||||
|
||||
# Render HTML email
|
||||
@@ -99,19 +146,24 @@ class TicketUpdateNotifier:
|
||||
context
|
||||
)
|
||||
|
||||
# Create email
|
||||
# Create email (uses DEFAULT_FROM_EMAIL from settings)
|
||||
email = EmailMultiAlternatives(
|
||||
subject=subject,
|
||||
body=text_message,
|
||||
from_email=settings.DEFAULT_FROM_EMAIL,
|
||||
from_email=settings.DEFAULT_FROM_EMAIL, # From .env file
|
||||
to=[ticket.user_email],
|
||||
)
|
||||
|
||||
email.attach_alternative(html_message, "text/html")
|
||||
email.send(fail_silently=False)
|
||||
|
||||
logger.info(f'Message notification sent for ticket {ticket.ticket_number}')
|
||||
return True
|
||||
# Send email with retry logic (uses EMAIL_BACKEND and credentials from settings)
|
||||
success = _send_email_with_retry(email)
|
||||
|
||||
if success:
|
||||
logger.info(f'Message notification sent for ticket {ticket.ticket_number}')
|
||||
else:
|
||||
logger.error(f'Failed to send message notification for ticket {ticket.ticket_number} after retries')
|
||||
return success
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f'Failed to send message notification: {str(e)}')
|
||||
@@ -131,6 +183,8 @@ class TicketUpdateNotifier:
|
||||
'assigned_to': assigned_to.get_full_name() or assigned_to.username,
|
||||
'updated_at': ticket.updated_at.strftime('%B %d, %Y at %I:%M %p'),
|
||||
'support_url': f'{settings.SITE_URL}/support-center',
|
||||
'logo_url': f'{settings.SITE_URL}/images/logo.png',
|
||||
'site_url': settings.SITE_URL,
|
||||
}
|
||||
|
||||
# Render HTML email
|
||||
@@ -145,19 +199,24 @@ class TicketUpdateNotifier:
|
||||
context
|
||||
)
|
||||
|
||||
# Create email
|
||||
# Create email (uses DEFAULT_FROM_EMAIL from settings)
|
||||
email = EmailMultiAlternatives(
|
||||
subject=subject,
|
||||
body=text_message,
|
||||
from_email=settings.DEFAULT_FROM_EMAIL,
|
||||
from_email=settings.DEFAULT_FROM_EMAIL, # From .env file
|
||||
to=[ticket.user_email],
|
||||
)
|
||||
|
||||
email.attach_alternative(html_message, "text/html")
|
||||
email.send(fail_silently=False)
|
||||
|
||||
logger.info(f'Assignment notification sent for ticket {ticket.ticket_number}')
|
||||
return True
|
||||
# Send email with retry logic (uses EMAIL_BACKEND and credentials from settings)
|
||||
success = _send_email_with_retry(email)
|
||||
|
||||
if success:
|
||||
logger.info(f'Assignment notification sent for ticket {ticket.ticket_number}')
|
||||
else:
|
||||
logger.error(f'Failed to send assignment notification for ticket {ticket.ticket_number} after retries')
|
||||
return success
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f'Failed to send assignment notification: {str(e)}')
|
||||
|
||||
Reference in New Issue
Block a user