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 backend.models.models import MessageTemplateDoc
|
||||||
from common.log.module_logger import ModuleLogger
|
from common.log.module_logger import ModuleLogger
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@ -355,9 +356,60 @@ class TemplateMessageHandler:
|
|||||||
)
|
)
|
||||||
raise
|
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:
|
async def render_template(self, template: MessageTemplateDoc, properties: dict) -> dict:
|
||||||
"""render template"""
|
"""render template"""
|
||||||
try:
|
try:
|
||||||
|
required_params = await self.validate_template_parameters(template, properties)
|
||||||
|
|
||||||
subject = template.subject.format(**properties)
|
subject = template.subject.format(**properties)
|
||||||
body = template.body.format(**properties)
|
body = template.body.format(**properties)
|
||||||
|
|
||||||
@ -367,11 +419,30 @@ class TemplateMessageHandler:
|
|||||||
"template_id": template.template_id,
|
"template_id": template.template_id,
|
||||||
"tenant_id": template.tenant_id,
|
"tenant_id": template.tenant_id,
|
||||||
"region": template.region,
|
"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:
|
except KeyError as e:
|
||||||
await self.module_logger.log_error(
|
await self.module_logger.log_error(
|
||||||
error="Missing template parameter",
|
error="Missing template parameter",
|
||||||
@ -382,7 +453,7 @@ class TemplateMessageHandler:
|
|||||||
"missing_parameter": str(e)
|
"missing_parameter": str(e)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
raise ValueError(f"Missing template parameter: {e}")
|
raise ValueError(f"Missing template parameter: {str(e)}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await self.module_logger.log_error(
|
await self.module_logger.log_error(
|
||||||
error="Template rendering error",
|
error="Template rendering error",
|
||||||
|
|||||||
@ -3,7 +3,7 @@ from datetime import datetime
|
|||||||
from typing import Optional, List
|
from typing import Optional, List
|
||||||
|
|
||||||
from common.constants.region import UserRegion
|
from common.constants.region import UserRegion
|
||||||
from common.constants.email import EmailSenderStatus, BounceType
|
from common.constants.email import EmailSendStatus, BounceType
|
||||||
|
|
||||||
class MessageTemplateDoc(Document):
|
class MessageTemplateDoc(Document):
|
||||||
template_id: str
|
template_id: str
|
||||||
@ -32,7 +32,7 @@ class EmailSenderDoc(Document):
|
|||||||
name = "email_sender_doc"
|
name = "email_sender_doc"
|
||||||
indexes = ["tenant_id"]
|
indexes = ["tenant_id"]
|
||||||
|
|
||||||
class EmailSenderStatusDoc(Document):
|
class EmailSendStatusDoc(Document):
|
||||||
email_id: str
|
email_id: str
|
||||||
tenant_id: str
|
tenant_id: str
|
||||||
email_senders: List[str]
|
email_senders: List[str]
|
||||||
@ -40,7 +40,7 @@ class EmailSenderStatusDoc(Document):
|
|||||||
template_id: Optional[str] = None
|
template_id: Optional[str] = None
|
||||||
subject: str
|
subject: str
|
||||||
body: str
|
body: str
|
||||||
status: EmailSenderStatus = EmailSenderStatus.PENDING
|
status: EmailSendStatus = EmailSendStatus.PENDING
|
||||||
sent_at: Optional[datetime] = None
|
sent_at: Optional[datetime] = None
|
||||||
failed_at: Optional[datetime] = None
|
failed_at: Optional[datetime] = None
|
||||||
error_message: Optional[str] = None
|
error_message: Optional[str] = None
|
||||||
@ -88,6 +88,7 @@ class EmailTrackingDoc(Document):
|
|||||||
class EmailBounceDoc(Document):
|
class EmailBounceDoc(Document):
|
||||||
email: str
|
email: str
|
||||||
tenant_id: str
|
tenant_id: str
|
||||||
|
email_id: Optional[str] = None
|
||||||
template_id: Optional[str] = None
|
template_id: Optional[str] = None
|
||||||
bounce_type: BounceType
|
bounce_type: BounceType
|
||||||
reason: str
|
reason: str
|
||||||
|
|||||||
@ -40,11 +40,6 @@ class TemplateMessageService:
|
|||||||
async def create_global_template(self, template: MessageTemplateDoc):
|
async def create_global_template(self, template: MessageTemplateDoc):
|
||||||
"""create global template"""
|
"""create global template"""
|
||||||
try:
|
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)
|
result = await self.template_message_handler.create_global_template(template)
|
||||||
await self.module_logger.log_info(
|
await self.module_logger.log_info(
|
||||||
info="Global template created",
|
info="Global template created",
|
||||||
@ -54,9 +49,6 @@ class TemplateMessageService:
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
return result
|
return result
|
||||||
except ValueError as e:
|
|
||||||
# Re-raise ValueError for duplicate template
|
|
||||||
raise
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await self.module_logger.log_error(
|
await self.module_logger.log_error(
|
||||||
error="Failed to create global template",
|
error="Failed to create global template",
|
||||||
@ -104,8 +96,7 @@ class TemplateMessageService:
|
|||||||
await self.module_logger.log_info(
|
await self.module_logger.log_info(
|
||||||
info="Global template deleted",
|
info="Global template deleted",
|
||||||
properties={
|
properties={
|
||||||
"template_id": template_id,
|
"template_id": template_id
|
||||||
"deleted_count": result.get("deleted_count", 0) if result else 0
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return result
|
return result
|
||||||
@ -243,12 +234,6 @@ class TemplateMessageService:
|
|||||||
"""create tenant template"""
|
"""create tenant template"""
|
||||||
try:
|
try:
|
||||||
template.tenant_id = tenant_id
|
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)
|
result = await self.template_message_handler.create_tenant_template(tenant_id, template)
|
||||||
await self.module_logger.log_info(
|
await self.module_logger.log_info(
|
||||||
info="Tenant template created",
|
info="Tenant template created",
|
||||||
@ -259,9 +244,6 @@ class TemplateMessageService:
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
return result
|
return result
|
||||||
except ValueError as e:
|
|
||||||
# Re-raise ValueError for duplicate template
|
|
||||||
raise
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await self.module_logger.log_error(
|
await self.module_logger.log_error(
|
||||||
error="Failed to create tenant template",
|
error="Failed to create tenant template",
|
||||||
@ -361,3 +343,32 @@ class TemplateMessageService:
|
|||||||
)
|
)
|
||||||
raise
|
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 fastapi.responses import JSONResponse
|
||||||
from backend.models.models import MessageTemplateDoc
|
from backend.models.models import MessageTemplateDoc
|
||||||
from backend.application.template_message_hub import TemplateMessageHub
|
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",
|
description="Delete an existing template for the current tenant",
|
||||||
response_description="Success/failure response in deleting the tenant template"
|
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:
|
try:
|
||||||
tenant_id = payload.get("tenant_id")
|
tenant_id = payload.get("tenant_id")
|
||||||
await verify_tenant_access(template_id, tenant_id, template_message_hub, allow_global_template=False, region=region)
|
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)],
|
dependencies=[Depends(tenant_only)],
|
||||||
operation_id="render_template",
|
operation_id="render_template",
|
||||||
summary="Render a template (Tenant Only)",
|
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"
|
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:
|
try:
|
||||||
tenant_id = payload.get("tenant_id")
|
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=False, region=region)
|
||||||
await verify_tenant_access(template_id, tenant_id, template_message_hub, allow_global_template=True, region=region)
|
|
||||||
|
|
||||||
result = await template_message_hub.render_template(tenant_id, template_id, request.properties, region)
|
result = await template_message_hub.render_template(tenant_id, template_id, request.properties, region)
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user