fix(notification): some small changes
This commit is contained in:
parent
7cb5ba4a78
commit
b6f8b70f69
@ -1,3 +1,4 @@
|
||||
import re
|
||||
from backend.models.models import MessageTemplateDoc
|
||||
from common.log.module_logger import ModuleLogger
|
||||
from datetime import datetime
|
||||
@ -355,9 +356,60 @@ class TemplateMessageHandler:
|
||||
)
|
||||
raise
|
||||
|
||||
async def validate_template_parameters(self, template: MessageTemplateDoc, properties: dict) -> list:
|
||||
"""validate template parameters"""
|
||||
try:
|
||||
subject_placeholders = re.findall(r'\{(\w+)\}', template.subject)
|
||||
body_placeholders = re.findall(r'\{(\w+)\}', template.body)
|
||||
all_placeholders = list(set(subject_placeholders + body_placeholders))
|
||||
|
||||
missing_params = set(all_placeholders) - set(properties.keys())
|
||||
if missing_params:
|
||||
raise ValueError(f"Missing required parameters: {missing_params}. "
|
||||
f"Template requires: {all_placeholders}")
|
||||
|
||||
extra_params = set(properties.keys()) - set(all_placeholders)
|
||||
if extra_params:
|
||||
await self.module_logger.log_warning(
|
||||
f"Extra parameters provided: {extra_params}",
|
||||
properties={
|
||||
"template_id": template.template_id,
|
||||
"tenant_id": template.tenant_id,
|
||||
"extra_params": list(extra_params)
|
||||
}
|
||||
)
|
||||
|
||||
for param, value in properties.items():
|
||||
if param in all_placeholders:
|
||||
if value is None:
|
||||
raise ValueError(f"Parameter '{param}' cannot be None")
|
||||
if isinstance(value, str) and not value.strip():
|
||||
await self.module_logger.log_warning(
|
||||
f"Parameter '{param}' is empty string",
|
||||
properties={
|
||||
"template_id": template.template_id,
|
||||
"parameter": param
|
||||
}
|
||||
)
|
||||
|
||||
return all_placeholders
|
||||
|
||||
except Exception as e:
|
||||
await self.module_logger.log_error(
|
||||
error="Template parameter validation failed",
|
||||
properties={
|
||||
"template_id": template.template_id,
|
||||
"tenant_id": template.tenant_id,
|
||||
"error": str(e)
|
||||
}
|
||||
)
|
||||
raise
|
||||
|
||||
async def render_template(self, template: MessageTemplateDoc, properties: dict) -> dict:
|
||||
"""render template"""
|
||||
try:
|
||||
required_params = await self.validate_template_parameters(template, properties)
|
||||
|
||||
subject = template.subject.format(**properties)
|
||||
body = template.body.format(**properties)
|
||||
|
||||
@ -367,11 +419,30 @@ class TemplateMessageHandler:
|
||||
"template_id": template.template_id,
|
||||
"tenant_id": template.tenant_id,
|
||||
"region": template.region,
|
||||
"properties_count": len(properties)
|
||||
"required_params": required_params,
|
||||
"provided_params": list(properties.keys())
|
||||
}
|
||||
)
|
||||
|
||||
return {"subject": subject, "body": body}
|
||||
return {
|
||||
"subject": subject,
|
||||
"body": body,
|
||||
"required_params": required_params,
|
||||
"template_id": template.template_id,
|
||||
"region": template.region
|
||||
}
|
||||
except ValueError as e:
|
||||
await self.module_logger.log_error(
|
||||
error="Template validation failed",
|
||||
properties={
|
||||
"template_id": template.template_id,
|
||||
"tenant_id": template.tenant_id,
|
||||
"region": template.region,
|
||||
"error": str(e)
|
||||
}
|
||||
)
|
||||
raise
|
||||
|
||||
except KeyError as e:
|
||||
await self.module_logger.log_error(
|
||||
error="Missing template parameter",
|
||||
@ -382,7 +453,7 @@ class TemplateMessageHandler:
|
||||
"missing_parameter": str(e)
|
||||
}
|
||||
)
|
||||
raise ValueError(f"Missing template parameter: {e}")
|
||||
raise ValueError(f"Missing template parameter: {str(e)}")
|
||||
except Exception as e:
|
||||
await self.module_logger.log_error(
|
||||
error="Template rendering error",
|
||||
|
||||
@ -3,7 +3,7 @@ from datetime import datetime
|
||||
from typing import Optional, List
|
||||
|
||||
from common.constants.region import UserRegion
|
||||
from common.constants.email import EmailSenderStatus, BounceType
|
||||
from common.constants.email import EmailSendStatus, BounceType
|
||||
|
||||
class MessageTemplateDoc(Document):
|
||||
template_id: str
|
||||
@ -32,7 +32,7 @@ class EmailSenderDoc(Document):
|
||||
name = "email_sender_doc"
|
||||
indexes = ["tenant_id"]
|
||||
|
||||
class EmailSenderStatusDoc(Document):
|
||||
class EmailSendStatusDoc(Document):
|
||||
email_id: str
|
||||
tenant_id: str
|
||||
email_senders: List[str]
|
||||
@ -40,7 +40,7 @@ class EmailSenderStatusDoc(Document):
|
||||
template_id: Optional[str] = None
|
||||
subject: str
|
||||
body: str
|
||||
status: EmailSenderStatus = EmailSenderStatus.PENDING
|
||||
status: EmailSendStatus = EmailSendStatus.PENDING
|
||||
sent_at: Optional[datetime] = None
|
||||
failed_at: Optional[datetime] = None
|
||||
error_message: Optional[str] = None
|
||||
@ -88,6 +88,7 @@ class EmailTrackingDoc(Document):
|
||||
class EmailBounceDoc(Document):
|
||||
email: str
|
||||
tenant_id: str
|
||||
email_id: Optional[str] = None
|
||||
template_id: Optional[str] = None
|
||||
bounce_type: BounceType
|
||||
reason: str
|
||||
|
||||
@ -40,11 +40,6 @@ class TemplateMessageService:
|
||||
async def create_global_template(self, template: MessageTemplateDoc):
|
||||
"""create global template"""
|
||||
try:
|
||||
# Check if template already exists with same template_id and region
|
||||
existing_template = await self.template_message_handler.find_global_template(template.template_id, template.region)
|
||||
if existing_template:
|
||||
raise ValueError(f"Global template with template_id '{template.template_id}' and region '{template.region}' already exists")
|
||||
|
||||
result = await self.template_message_handler.create_global_template(template)
|
||||
await self.module_logger.log_info(
|
||||
info="Global template created",
|
||||
@ -54,9 +49,6 @@ class TemplateMessageService:
|
||||
}
|
||||
)
|
||||
return result
|
||||
except ValueError as e:
|
||||
# Re-raise ValueError for duplicate template
|
||||
raise
|
||||
except Exception as e:
|
||||
await self.module_logger.log_error(
|
||||
error="Failed to create global template",
|
||||
@ -104,8 +96,7 @@ class TemplateMessageService:
|
||||
await self.module_logger.log_info(
|
||||
info="Global template deleted",
|
||||
properties={
|
||||
"template_id": template_id,
|
||||
"deleted_count": result.get("deleted_count", 0) if result else 0
|
||||
"template_id": template_id
|
||||
}
|
||||
)
|
||||
return result
|
||||
@ -243,12 +234,6 @@ class TemplateMessageService:
|
||||
"""create tenant template"""
|
||||
try:
|
||||
template.tenant_id = tenant_id
|
||||
|
||||
# Check if template already exists with same template_id, tenant_id and region
|
||||
existing_template = await self.template_message_handler.find_tenant_template(tenant_id, template.template_id, template.region)
|
||||
if existing_template:
|
||||
raise ValueError(f"Tenant template with template_id '{template.template_id}', tenant_id '{tenant_id}' and region '{template.region}' already exists")
|
||||
|
||||
result = await self.template_message_handler.create_tenant_template(tenant_id, template)
|
||||
await self.module_logger.log_info(
|
||||
info="Tenant template created",
|
||||
@ -259,9 +244,6 @@ class TemplateMessageService:
|
||||
}
|
||||
)
|
||||
return result
|
||||
except ValueError as e:
|
||||
# Re-raise ValueError for duplicate template
|
||||
raise
|
||||
except Exception as e:
|
||||
await self.module_logger.log_error(
|
||||
error="Failed to create tenant template",
|
||||
@ -360,4 +342,33 @@ class TemplateMessageService:
|
||||
}
|
||||
)
|
||||
raise
|
||||
|
||||
async def get_template(self, tenant_id: str, template_id: str, region: int):
|
||||
"""get template"""
|
||||
try:
|
||||
template = await self.template_message_handler.find_tenant_template(tenant_id, template_id, region)
|
||||
if template:
|
||||
await self.module_logger.log_info(
|
||||
"Tenant template found for email",
|
||||
properties={
|
||||
"tenant_id": tenant_id,
|
||||
"template_id": template_id,
|
||||
"region": region
|
||||
}
|
||||
)
|
||||
return template
|
||||
|
||||
raise ValueError(f"Template not found")
|
||||
|
||||
except Exception as e:
|
||||
await self.module_logger.log_error(
|
||||
error="Failed to get tenant template",
|
||||
properties={
|
||||
"tenant_id": tenant_id,
|
||||
"template_id": template_id,
|
||||
"region": region,
|
||||
"error": str(e)
|
||||
}
|
||||
)
|
||||
raise
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from fastapi import APIRouter, HTTPException, Depends, Query
|
||||
from fastapi import APIRouter, HTTPException, Depends
|
||||
from fastapi.responses import JSONResponse
|
||||
from backend.models.models import MessageTemplateDoc
|
||||
from backend.application.template_message_hub import TemplateMessageHub
|
||||
@ -360,7 +360,7 @@ async def update_tenant_template(template_id: str, request: TemplateUpdateReques
|
||||
description="Delete an existing template for the current tenant",
|
||||
response_description="Success/failure response in deleting the tenant template"
|
||||
)
|
||||
async def delete_tenant_template(template_id: str, region: int = Query(..., description="Template region"), payload: dict = Depends(tenant_only)):
|
||||
async def delete_tenant_template(template_id: str, region: int, payload: dict = Depends(tenant_only)):
|
||||
try:
|
||||
tenant_id = payload.get("tenant_id")
|
||||
await verify_tenant_access(template_id, tenant_id, template_message_hub, allow_global_template=False, region=region)
|
||||
@ -386,15 +386,14 @@ async def delete_tenant_template(template_id: str, region: int = Query(..., desc
|
||||
dependencies=[Depends(tenant_only)],
|
||||
operation_id="render_template",
|
||||
summary="Render a template (Tenant Only)",
|
||||
description="Render a template with provided properties (can render own templates or assigned global templates)",
|
||||
description="Render a template with provided properties (can only render own templates)",
|
||||
response_description="Rendered template content"
|
||||
)
|
||||
async def render_template(template_id: str, request: TemplateRenderRequest, region: int = Query(..., description="Template region"), payload: dict = Depends(tenant_only)):
|
||||
async def render_template(template_id: str, region: int, request: TemplateRenderRequest, payload: dict = Depends(tenant_only)):
|
||||
try:
|
||||
tenant_id = payload.get("tenant_id")
|
||||
|
||||
# Allow access to both tenant templates and assigned global templates
|
||||
await verify_tenant_access(template_id, tenant_id, template_message_hub, allow_global_template=True, region=region)
|
||||
await verify_tenant_access(template_id, tenant_id, template_message_hub, allow_global_template=False, region=region)
|
||||
|
||||
result = await template_message_hub.render_template(tenant_id, template_id, request.properties, region)
|
||||
return JSONResponse(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user