avoid loops
This commit is contained in:
parent
397a2f7d98
commit
7f9ac1c9e6
|
|
@ -468,7 +468,8 @@ def create_ooo_reply(original_parsed, recipient: str, ooo_msg: str, content_type
|
||||||
msg['Message-ID'] = make_msgid(domain=recipient.split('@')[1])
|
msg['Message-ID'] = make_msgid(domain=recipient.split('@')[1])
|
||||||
msg['In-Reply-To'] = original_parsed.get('Message-ID', '')
|
msg['In-Reply-To'] = original_parsed.get('Message-ID', '')
|
||||||
msg['References'] = original_parsed.get('Message-ID', '')
|
msg['References'] = original_parsed.get('Message-ID', '')
|
||||||
msg['Auto-Submitted'] = 'auto-replied' # Verhindert Loops
|
msg['Auto-Submitted'] = 'auto-replied' # Standard header für Auto-Replies
|
||||||
|
msg['X-SES-Worker-Processed'] = 'ooo-reply' # Unser Loop-Prevention Header
|
||||||
|
|
||||||
# Body-Teil erstellen
|
# Body-Teil erstellen
|
||||||
body_part = MIMEMultipart('alternative')
|
body_part = MIMEMultipart('alternative')
|
||||||
|
|
@ -515,6 +516,7 @@ def create_forward_message(original_parsed, recipient: str, forward_to: str, ori
|
||||||
msg['Date'] = formatdate(localtime=True)
|
msg['Date'] = formatdate(localtime=True)
|
||||||
msg['Message-ID'] = make_msgid(domain=recipient.split('@')[1])
|
msg['Message-ID'] = make_msgid(domain=recipient.split('@')[1])
|
||||||
msg['Reply-To'] = original_from
|
msg['Reply-To'] = original_from
|
||||||
|
msg['X-SES-Worker-Processed'] = 'forwarded' # Unser Loop-Prevention Header
|
||||||
|
|
||||||
# Forward-Header als Text
|
# Forward-Header als Text
|
||||||
text_body, html_body = extract_body_parts(original_parsed)
|
text_body, html_body = extract_body_parts(original_parsed)
|
||||||
|
|
@ -885,6 +887,25 @@ def process_message(domain: str, message: dict, receive_count: int) -> bool:
|
||||||
try:
|
try:
|
||||||
response = s3.get_object(Bucket=bucket, Key=key)
|
response = s3.get_object(Bucket=bucket, Key=key)
|
||||||
raw_bytes = response['Body'].read()
|
raw_bytes = response['Body'].read()
|
||||||
|
|
||||||
|
# LOOP DETECTION: Check if this message was already processed by our worker
|
||||||
|
# We use a unique header that only our worker sets
|
||||||
|
temp_parsed = BytesParser(policy=SMTPPolicy).parsebytes(raw_bytes)
|
||||||
|
|
||||||
|
# Check for OUR unique loop prevention header
|
||||||
|
x_worker_processed = temp_parsed.get('X-SES-Worker-Processed', '')
|
||||||
|
auto_submitted = temp_parsed.get('Auto-Submitted', '')
|
||||||
|
|
||||||
|
# Only skip if OUR header is present (not generic headers that others might set)
|
||||||
|
is_processed_by_us = bool(x_worker_processed)
|
||||||
|
is_our_auto_reply = auto_submitted == 'auto-replied' and x_worker_processed
|
||||||
|
|
||||||
|
if is_processed_by_us:
|
||||||
|
log(f"🔄 Loop prevention: Already processed by worker", 'INFO', worker_name)
|
||||||
|
skip_rules = True
|
||||||
|
else:
|
||||||
|
skip_rules = False
|
||||||
|
|
||||||
except s3.exceptions.NoSuchKey:
|
except s3.exceptions.NoSuchKey:
|
||||||
if receive_count < 5:
|
if receive_count < 5:
|
||||||
log(f"⏳ S3 Object not found yet (Attempt {receive_count}). Retrying...", 'WARNING', worker_name)
|
log(f"⏳ S3 Object not found yet (Attempt {receive_count}). Retrying...", 'WARNING', worker_name)
|
||||||
|
|
@ -929,9 +950,10 @@ def process_message(domain: str, message: dict, receive_count: int) -> bool:
|
||||||
log(f"⚠ Parsing/Logic Error: {e}. Sending original.", 'WARNING', worker_name)
|
log(f"⚠ Parsing/Logic Error: {e}. Sending original.", 'WARNING', worker_name)
|
||||||
from_addr_final = from_addr
|
from_addr_final = from_addr
|
||||||
is_bounce = False
|
is_bounce = False
|
||||||
|
skip_rules = False # Default if parsing failed
|
||||||
|
|
||||||
# 5. OOO & FORWARD LOGIC (vor SMTP-Versand, nicht für Bounces)
|
# 5. OOO & FORWARD LOGIC (vor SMTP-Versand, nicht für Bounces oder bereits weitergeleitete)
|
||||||
if not is_bounce:
|
if not is_bounce and not skip_rules:
|
||||||
for recipient in recipients:
|
for recipient in recipients:
|
||||||
process_rules_for_recipient(recipient, parsed, domain, worker_name)
|
process_rules_for_recipient(recipient, parsed, domain, worker_name)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue