moved
This commit is contained in:
91
email-worker/email_processing/bounce_handler.py
Normal file
91
email-worker/email_processing/bounce_handler.py
Normal file
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Bounce detection and header rewriting
|
||||
"""
|
||||
|
||||
from typing import Tuple, Any
|
||||
|
||||
from logger import log
|
||||
from aws.dynamodb_handler import DynamoDBHandler
|
||||
|
||||
|
||||
class BounceHandler:
|
||||
"""Handles bounce detection and header rewriting"""
|
||||
|
||||
def __init__(self, dynamodb: DynamoDBHandler):
|
||||
self.dynamodb = dynamodb
|
||||
|
||||
@staticmethod
|
||||
def is_ses_bounce_notification(parsed_email) -> bool:
|
||||
"""Check if email is from SES MAILER-DAEMON"""
|
||||
from_header = (parsed_email.get('From') or '').lower()
|
||||
return 'mailer-daemon@' in from_header and 'amazonses.com' in from_header
|
||||
|
||||
def apply_bounce_logic(
|
||||
self,
|
||||
parsed,
|
||||
subject: str,
|
||||
worker_name: str = 'unified'
|
||||
) -> Tuple[Any, bool]:
|
||||
"""
|
||||
Check for SES Bounce, lookup in DynamoDB and rewrite headers
|
||||
|
||||
Args:
|
||||
parsed: Parsed email message object
|
||||
subject: Email subject
|
||||
worker_name: Worker name for logging
|
||||
|
||||
Returns:
|
||||
Tuple of (parsed_email_object, was_modified_bool)
|
||||
"""
|
||||
if not self.is_ses_bounce_notification(parsed):
|
||||
return parsed, False
|
||||
|
||||
log("🔍 Detected SES MAILER-DAEMON bounce notification", 'INFO', worker_name)
|
||||
|
||||
# Extract Message-ID from header
|
||||
message_id = (parsed.get('Message-ID') or '').strip('<>').split('@')[0]
|
||||
|
||||
if not message_id:
|
||||
log("⚠ Could not extract Message-ID from bounce notification", 'WARNING', worker_name)
|
||||
return parsed, False
|
||||
|
||||
log(f" Looking up Message-ID: {message_id}", 'INFO', worker_name)
|
||||
|
||||
# Lookup in DynamoDB
|
||||
bounce_info = self.dynamodb.get_bounce_info(message_id, worker_name)
|
||||
|
||||
if not bounce_info:
|
||||
return parsed, False
|
||||
|
||||
# Bounce Info ausgeben
|
||||
original_source = bounce_info['original_source']
|
||||
bounced_recipients = bounce_info['bouncedRecipients']
|
||||
bounce_type = bounce_info['bounceType']
|
||||
bounce_subtype = bounce_info['bounceSubType']
|
||||
|
||||
log(f"✓ Found bounce info:", 'INFO', worker_name)
|
||||
log(f" Original sender: {original_source}", 'INFO', worker_name)
|
||||
log(f" Bounce type: {bounce_type}/{bounce_subtype}", 'INFO', worker_name)
|
||||
log(f" Bounced recipients: {bounced_recipients}", 'INFO', worker_name)
|
||||
|
||||
if bounced_recipients:
|
||||
new_from = bounced_recipients[0]
|
||||
|
||||
# Rewrite Headers
|
||||
parsed['X-Original-SES-From'] = parsed.get('From', '')
|
||||
parsed['X-Bounce-Type'] = f"{bounce_type}/{bounce_subtype}"
|
||||
parsed.replace_header('From', new_from)
|
||||
|
||||
if not parsed.get('Reply-To'):
|
||||
parsed['Reply-To'] = new_from
|
||||
|
||||
# Subject anpassen
|
||||
if 'delivery status notification' in subject.lower() or 'thanks for your submission' in subject.lower():
|
||||
parsed.replace_header('Subject', f"Delivery Status: {new_from}")
|
||||
|
||||
log(f"✓ Rewritten FROM: {new_from}", 'SUCCESS', worker_name)
|
||||
return parsed, True
|
||||
|
||||
log("⚠ No bounced recipients found in bounce info", 'WARNING', worker_name)
|
||||
return parsed, False
|
||||
Reference in New Issue
Block a user