worker with ooo & forward logic

This commit is contained in:
2025-12-17 12:25:56 -06:00
parent 19b4bb1471
commit 93f2c0c3bd
3 changed files with 167 additions and 407 deletions

View File

@@ -35,12 +35,15 @@ SMTP_PASS = os.environ.get('SMTP_PASS')
shutdown_requested = False
# DynamoDB Ressource für Bounce-Lookup
# DynamoDB Ressource für Bounce-Lookup und Rules
try:
dynamo = boto3.resource('dynamodb', region_name=AWS_REGION)
msg_table = dynamo.Table('ses-outbound-messages')
rules_table = dynamo.Table('email-rules') # Neu: Für OOO/Forwards
except Exception as e:
log(f"Warning: Could not connect to DynamoDB: {e}", 'WARNING')
msg_table = None
rules_table = None
def get_bucket_name(domain):
"""Konvention: domain.tld -> domain-tld-emails"""
@@ -511,7 +514,66 @@ def process_message(message_body: dict, receive_count: int) -> bool:
log(f"⚠ Parsing/Logic Error: {e}. Sending original.", 'WARNING')
from_addr_final = from_addr
# 5. SMTP VERSAND (Loop über Recipients)
# 5. OOO & FORWARD LOGIC (neu, vor SMTP-Versand)
if rules_table and not is_ses_bounce_or_autoreply(parsed): # Vermeide Loops bei Bounces/Auto-Replies
for recipient in recipients:
try:
rule = rules_table.get_item(Key={'email_address': recipient}).get('Item', {})
# OOO handling
if rule.get('ooo_active', False):
ooo_msg = rule.get('ooo_message', 'Default OOO message.')
content_type = rule.get('ooo_content_type', 'text') # Default: text
sender = parsed.get('From') # Original-Sender
reply_subject = f"Out of Office: {subject}"
original_body = str(parsed.get_payload(decode=True)) # Original für Quote
if content_type == 'html':
reply_body = {'Html': {'Data': f"<p>{ooo_msg}</p><br><blockquote>Original Message:<br>Subject: {parsed.get('Subject')}<br>From: {sender}<br><br>{original_body}</blockquote>"}}
else:
reply_body = {'Text': {'Data': f"{ooo_msg}\n\nOriginal Message:\nSubject: {parsed.get('Subject')}\nFrom: {sender}\n\n{original_body}"}}
ses.send_email(
Source=recipient, # Verifizierte eigene Adresse
Destination={'ToAddresses': [sender]},
Message={
'Subject': {'Data': reply_subject},
'Body': reply_body # Dynamisch Text oder Html
},
ReplyToAddresses=[recipient] # Optional: Für Replies
)
log(f"✓ Sent OOO reply to {sender} from {recipient}")
# Forward handling
forwards = rule.get('forwards', [])
if forwards:
original_from = parsed.get('From') # Für Headers
fwd_subject = f"FWD: {subject}"
fwd_body_text = f"Forwarded from: {original_from}\n\n{original_body}"
fwd_body = {'Text': {'Data': fwd_body_text}} # Erweiterbar auf HTML
for forward_to in forwards:
ses.send_email(
Source=recipient, # Verifizierte eigene Adresse
Destination={'ToAddresses': [forward_to]},
Message={
'Subject': {'Data': fwd_subject},
'Body': fwd_body
},
ReplyToAddresses=[original_from] # Original-Sender für Replies
)
log(f"✓ Forwarded to {forward_to} from {recipient} (original: {original_from})")
except boto3.exceptions.ClientError as e:
if 'MessageRejected' in str(e):
log(f"⚠ SES rejected: {e}. Check verification.", 'ERROR')
else:
log(f"⚠ Rules error for {recipient}: {e}", 'WARNING')
except Exception as e:
log(f"⚠ General error: {e}", 'WARNING')
# 6. SMTP VERSAND (Loop über Recipients)
log(f"📤 Sending to {len(recipients)} recipient(s)...")
successful = []