157 lines
5.9 KiB
Python
157 lines
5.9 KiB
Python
from common.config.app_settings import app_settings
|
|
from sendgrid import SendGridAPIClient
|
|
from sendgrid.helpers.mail import Mail
|
|
from common.log.module_logger import ModuleLogger
|
|
from typing import List, Dict
|
|
import uuid
|
|
from datetime import datetime
|
|
|
|
from backend.models.models import EmailSendStatusDoc
|
|
from common.constants.email import EmailSendStatus
|
|
|
|
class EmailHandler:
|
|
def __init__(self) -> None:
|
|
pass
|
|
|
|
async def send_email(self, message: dict):
|
|
receiver_id = message["receiver_id"]
|
|
content_text = message["properties"]["content_text"]
|
|
content_subject = message["properties"]["content_subject"]
|
|
receiver_type = message["properties"]["receiver_type"]
|
|
module_logger = ModuleLogger(sender_id="EmailHandler")
|
|
if receiver_type == "email":
|
|
receiver_email = receiver_id
|
|
else:
|
|
receiver_email = None
|
|
module_logger.log_info(
|
|
"unsupported receiver_type: '{}'".format(receiver_type)
|
|
)
|
|
return
|
|
|
|
mail = Mail(
|
|
from_email=app_settings.EMAIL_FROM,
|
|
to_emails=receiver_email,
|
|
subject=content_subject,
|
|
html_content=content_text,
|
|
)
|
|
try:
|
|
sg = SendGridAPIClient(app_settings.SENDGRID_API_KEY)
|
|
response = sg.send(mail)
|
|
await module_logger.log_info(
|
|
info=f"SendGridAPIClient:response:status_code:{response.status_code} | body:{response.body}",
|
|
properties=message["properties"],
|
|
)
|
|
except Exception as e:
|
|
await module_logger.log_exception(e)
|
|
|
|
async def send_tenant_email(
|
|
self,
|
|
tenant_id: str,
|
|
template_id: str,
|
|
recipient_email: str,
|
|
sender_email: str,
|
|
subject_properties: Dict = {},
|
|
body_properties: Dict = {},
|
|
tracking_enabled: bool = True
|
|
):
|
|
"""Send tenant email using specified sender"""
|
|
module_logger = ModuleLogger(sender_id="EmailHandler")
|
|
|
|
try:
|
|
email_id = str(uuid.uuid4())
|
|
|
|
from_email = sender_email if sender_email else app_settings.EMAIL_FROM
|
|
|
|
subject = subject_properties.get("subject", "No Subject")
|
|
html_content = body_properties.get("html_content", "")
|
|
text_content = body_properties.get("text_content", "")
|
|
|
|
email_status_doc = EmailSendStatusDoc(
|
|
email_id=email_id,
|
|
tenant_id=tenant_id,
|
|
email_sender=sender_email,
|
|
recipient_email=recipient_email,
|
|
template_id=template_id,
|
|
subject=subject,
|
|
body=html_content,
|
|
status=EmailSendStatus.SENDING
|
|
)
|
|
await email_status_doc.save()
|
|
|
|
# Create EmailTrackingDoc if tracking is enabled
|
|
tracking_doc = None
|
|
if tracking_enabled:
|
|
from backend.models.models import EmailTrackingDoc
|
|
tracking_doc = EmailTrackingDoc(
|
|
email_id=email_id,
|
|
tenant_id=tenant_id,
|
|
recipient_email=recipient_email,
|
|
template_id=template_id,
|
|
sent_at=datetime.utcnow(),
|
|
tracking_enabled=True
|
|
)
|
|
await tracking_doc.save()
|
|
|
|
mail = Mail(
|
|
from_email=from_email,
|
|
to_emails=recipient_email,
|
|
subject=subject,
|
|
html_content=html_content,
|
|
)
|
|
|
|
# Enable SendGrid tracking if tracking is enabled
|
|
if tracking_enabled:
|
|
from sendgrid.helpers.mail import TrackingSettings, ClickTracking, OpenTracking
|
|
tracking_settings = TrackingSettings()
|
|
click_tracking = ClickTracking(True, True) # Enable click tracking
|
|
open_tracking = OpenTracking(True) # Enable open tracking
|
|
|
|
tracking_settings.click_tracking = click_tracking
|
|
tracking_settings.open_tracking = open_tracking
|
|
mail.tracking_settings = tracking_settings
|
|
|
|
sg = SendGridAPIClient(app_settings.SENDGRID_API_KEY)
|
|
response = sg.send(mail)
|
|
|
|
email_status_doc.status = EmailSendStatus.SENT
|
|
email_status_doc.sent_at = datetime.utcnow()
|
|
email_status_doc.message_id = str(response.headers.get('X-Message-Id', ''))
|
|
await email_status_doc.save()
|
|
|
|
# Update tracking document with message_id
|
|
if tracking_doc:
|
|
tracking_doc.message_id = email_status_doc.message_id
|
|
await tracking_doc.save()
|
|
|
|
await module_logger.log_info(
|
|
f"Tenant email sent successfully",
|
|
properties={
|
|
"tenant_id": tenant_id,
|
|
"template_id": template_id,
|
|
"email_id": email_id,
|
|
"recipient_email": recipient_email,
|
|
"sender_email": from_email,
|
|
"status_code": response.status_code
|
|
}
|
|
)
|
|
|
|
return email_id
|
|
|
|
except Exception as e:
|
|
if 'email_status_doc' in locals():
|
|
email_status_doc.status = EmailSendStatus.FAILED
|
|
email_status_doc.failed_at = datetime.utcnow()
|
|
email_status_doc.error_message = str(e)
|
|
await email_status_doc.save()
|
|
|
|
await module_logger.log_error(
|
|
f"Failed to send tenant email",
|
|
properties={
|
|
"tenant_id": tenant_id,
|
|
"template_id": template_id,
|
|
"recipient_email": recipient_email,
|
|
"error": str(e)
|
|
}
|
|
)
|
|
raise
|