fix(email): make these changes to Fixed the duplicate email sending bug

This commit is contained in:
YuehuCao 2025-08-13 22:22:12 +08:00
parent 58c77ce002
commit 6d7c6af8a1
3 changed files with 45 additions and 18 deletions

View File

@ -64,8 +64,8 @@ class TenantNotificationManager:
# 4. spam detection with region
email_content = {
"subject": rendered_template.get("subject_properties", {}).get("subject", ""),
"body": rendered_template.get("body_properties", {}).get("html_content", "")
"subject": rendered_template.get("subject", ""),
"body": rendered_template.get("body", "")
}
spam_result = await self.email_spam_protection_service.detect_spam(email_content, region)
if spam_result["is_spam"]:
@ -82,8 +82,8 @@ class TenantNotificationManager:
"region": region,
"priority": priority,
"tracking_enabled": tracking_enabled,
"content_text": rendered_template.get("body_properties", {}).get("html_content", ""),
"content_subject": rendered_template.get("subject_properties", {}).get("subject", ""),
"content_text": rendered_template.get("body", ""),
"content_subject": rendered_template.get("subject", ""),
"receiver_type": "email",
"validation_info": {
"invalid_recipients": invalid_recipients,
@ -96,13 +96,36 @@ class TenantNotificationManager:
# 6. create message for each recipient
for recipient_email in valid_recipients:
# create individual properties for each recipient
individual_properties = {
"tenant_id": tenant_id,
"template_id": template_id,
"destination_emails": [recipient_email],
"sender_emails": valid_senders,
"subject_properties": rendered_template.get("subject_properties", {}),
"body_properties": rendered_template.get("body_properties", {}),
"region": region,
"priority": priority,
"tracking_enabled": tracking_enabled,
"content_text": rendered_template.get("body", ""),
"content_subject": rendered_template.get("subject", ""),
"receiver_type": "email",
"validation_info": {
"invalid_recipients": invalid_recipients,
"invalid_senders": invalid_senders,
"blacklisted_recipients": blacklisted_recipients,
"rate_limit_info": rate_limit_result,
"spam_detection_info": spam_result
}
}
# create NotificationMessage
message = NotificationMessage(
sender_id=tenant_id,
receiver_id=recipient_email,
subject=template_id,
event="tenant_email",
properties=properties
properties=individual_properties
)
await self.email_publisher.publish(message=message.model_dump_json())

View File

@ -6,7 +6,9 @@ import aio_pika
class AsyncMQClient:
exchange_name_format = "freeleaps.notification.exchange.{}"
# TODO: change to freeleaps.notification.exchange.{}
# in local test, we use freeleaps.notification.exchange.local.{} to avoid repeating sending emails
exchange_name_format = "freeleaps.notification.exchange.local.{}"
exchange_type = "direct"
def __init__(self, channel_name: str) -> None:
@ -38,7 +40,7 @@ class AsyncMQClient:
# Declare and bind queue if it's not set by a specific client
self.queue = await self.channel.declare_queue(
name=None, exclusive=True, auto_delete=True, durable=False
name=f"freeleaps.notification.queue.{self.channel_name}", exclusive=False, auto_delete=False, durable=True
)
await self.queue.bind(
exchange=self.exchange, routing_key=self.routing_key

View File

@ -12,13 +12,13 @@ class EmailMQConsumer:
module_logger = ModuleLogger(sender_id="EmailMQConsumer")
# examin whether it is a multi-tenant email message
if "tenant_id" in message and "template_id" in message:
if "tenant_id" in message and "template_id" in message.get("properties", {}):
await module_logger.log_info(
"Processing tenant email message",
properties={
"template_id": message.get("template_id"),
"template_id": message.get("properties", {}).get("template_id"),
"tenant_id": message.get("tenant_id"),
"destination_count": len(message.get("destination_emails", []))
"destination_count": len(message.get("properties", {}).get("destination_emails", []))
}
)
@ -56,12 +56,14 @@ class EmailMQConsumer:
async def tenant_mail_handler(register_key: str, message: dict, args: dict):
"""Handle tenant email messages"""
try:
tenant_id = message.get("tenant_id")
template_id = message.get("template_id")
destination_emails = message.get("destination_emails", [])
sender_emails = message.get("sender_emails", [])
subject_properties = message.get("subject_properties", {})
body_properties = message.get("body_properties", {})
# Get fields from message structure
tenant_id = message.get("tenant_id") or message.get("properties", {}).get("tenant_id")
template_id = message.get("properties", {}).get("template_id")
destination_emails = message.get("properties", {}).get("destination_emails", [])
sender_emails = message.get("properties", {}).get("sender_emails", [])
# Use rendered content instead of template properties
subject = message.get("properties", {}).get("content_subject", "No Subject")
html_content = message.get("properties", {}).get("content_text", "")
email_handler = EmailHandler()
email_ids = []
@ -73,8 +75,8 @@ class EmailMQConsumer:
template_id=template_id,
recipient_email=recipient_email,
sender_emails=sender_emails,
subject_properties=subject_properties,
body_properties=body_properties
subject_properties={"subject": subject},
body_properties={"html_content": html_content}
)
email_ids.append(email_id)