feat(service): Add email status update handling for bounce cases

This commit is contained in:
YuehuCao 2025-08-11 15:33:43 +08:00
parent 1d6f41c3b5
commit 0a01b1c6c6

View File

@ -11,13 +11,13 @@ class EmailBounceService:
async def process_bounce_event(self, email: str, tenant_id: str, bounce_type: BounceType, async def process_bounce_event(self, email: str, tenant_id: str, bounce_type: BounceType,
reason: str, message_id: str = None) -> Dict: reason: str, message_id: str = None) -> Dict:
"""处理退信事件建立email_id关联""" """handle bounce event, create email_id association"""
try: try:
# 1. 查找对应的邮件记录 # 1. find corresponding email record
email_status_doc = await EmailSendStatusDoc.find_one( email_status_doc = await EmailSendStatusDoc.find_one(
EmailSendStatusDoc.recipient_email == email, EmailSendStatusDoc.recipient_email == email,
EmailSendStatusDoc.tenant_id == tenant_id EmailSendStatusDoc.tenant_id == tenant_id
).sort(-EmailSendStatusDoc.created_at) # 获取最新的邮件记录 ).sort(-EmailSendStatusDoc.created_at)
email_id = None email_id = None
template_id = None template_id = None
@ -25,6 +25,12 @@ class EmailBounceService:
if email_status_doc: if email_status_doc:
email_id = email_status_doc.email_id email_id = email_status_doc.email_id
template_id = email_status_doc.template_id template_id = email_status_doc.template_id
# 2. update email status to bounced
email_status_doc.status = EmailSendStatus.BOUNCED
email_status_doc.updated_at = datetime.utcnow()
await email_status_doc.save()
await self.module_logger.log_info( await self.module_logger.log_info(
"Found email record for bounce", "Found email record for bounce",
properties={ properties={
@ -42,11 +48,11 @@ class EmailBounceService:
} }
) )
# 2. 创建退信记录 # 3. create bounce record
bounce_doc = EmailBounceDoc( bounce_doc = EmailBounceDoc(
email=email, email=email,
tenant_id=tenant_id, tenant_id=tenant_id,
email_id=email_id, # 建立关联 email_id=email_id,
template_id=template_id, template_id=template_id,
bounce_type=bounce_type, bounce_type=bounce_type,
reason=reason, reason=reason,
@ -89,7 +95,7 @@ class EmailBounceService:
raise raise
async def get_bounce_info(self, email: str, tenant_id: str) -> Optional[Dict]: async def get_bounce_info(self, email: str, tenant_id: str) -> Optional[Dict]:
"""获取退信信息""" """get bounce info"""
try: try:
bounce_doc = await EmailBounceDoc.find_one( bounce_doc = await EmailBounceDoc.find_one(
EmailBounceDoc.email == email, EmailBounceDoc.email == email,
@ -125,7 +131,7 @@ class EmailBounceService:
raise raise
async def mark_bounce_processed(self, email: str, tenant_id: str) -> bool: async def mark_bounce_processed(self, email: str, tenant_id: str) -> bool:
"""标记退信为已处理""" """mark bounce as processed"""
try: try:
bounce_doc = await EmailBounceDoc.find_one( bounce_doc = await EmailBounceDoc.find_one(
EmailBounceDoc.email == email, EmailBounceDoc.email == email,
@ -159,14 +165,13 @@ class EmailBounceService:
) )
raise raise
async def is_blacklisted(self, email: str, tenant_id: str) -> bool: async def is_blacklisted(self, email: str, tenant_id: str):
"""检查邮箱是否在黑名单中""" """check if email is blacklisted"""
try: try:
# 查找该邮箱的退信记录
bounce_doc = await EmailBounceDoc.find_one( bounce_doc = await EmailBounceDoc.find_one(
EmailBounceDoc.email == email, EmailBounceDoc.email == email,
EmailBounceDoc.tenant_id == tenant_id, EmailBounceDoc.tenant_id == tenant_id,
EmailBounceDoc.bounce_type == BounceType.HARD_BOUNCE # 只检查硬退信 EmailBounceDoc.bounce_type == BounceType.HARD_BOUNCE
) )
is_blacklisted = bounce_doc is not None is_blacklisted = bounce_doc is not None