This commit is contained in:
Andreas Knuth 2025-12-10 15:21:26 -06:00
parent a5fe94df66
commit cfdd840527
2 changed files with 135 additions and 92 deletions

17
extract_email_headers.py Normal file
View File

@ -0,0 +1,17 @@
import sys
import email
if len(sys.argv) < 2:
print("Usage: python3 extract_email_headers.py <email_file>")
sys.exit(1)
file_path = sys.argv[1]
with open(file_path, 'rb') as f:
msg = email.message_from_bytes(f.read())
from_addr = msg.get('From', '')
to_addrs = msg.get_all('To', []) + msg.get_all('Cc', [])
recipients = ','.join([str(addr) for addr in to_addrs]) if to_addrs else ''
print(f'FROM:{from_addr}')
print(f'RECIPIENTS:{recipients}')

View File

@ -2,7 +2,9 @@
# requeue-email.sh - Sendet eine E-Mail aus S3 manuell in die SQS Queue # requeue-email.sh - Sendet eine E-Mail aus S3 manuell in die SQS Queue
# Simuliert das SNS-ähnliche Format, das der Worker erwartet (aus Lambda). # Simuliert das SNS-ähnliche Format, das der Worker erwartet (aus Lambda).
# Extrahiert FROM und RECIPIENTS aus der E-Mail, falls nicht angegeben. # Extrahiert FROM und RECIPIENTS aus der E-Mail, falls nicht angegeben.
set -e set -e
# Parameter prüfen # Parameter prüfen
if [ $# -lt 2 ]; then if [ $# -lt 2 ]; then
echo "Usage: $0 <BUCKET> <S3_KEY> [FROM] [RECIPIENTS]" echo "Usage: $0 <BUCKET> <S3_KEY> [FROM] [RECIPIENTS]"
@ -15,88 +17,108 @@ echo " oder mit manuellen Werten: $0 bayarea-cc-emails rgskc3d59dqdm6lq1scenpuv
echo "" echo ""
exit 1 exit 1
fi fi
BUCKET=$1 BUCKET=$1
S3_KEY=$2 S3_KEY=$2
FROM=${3:-} FROM=${3:-}
RECIPIENTS=${4:-} RECIPIENTS=${4:-}
# Konfiguration # Konfiguration
AWS_REGION="us-east-2" AWS_REGION="us-east-2"
# Temporäre Datei für E-Mail # Temporäre Datei für E-Mail
TEMP_FILE="/tmp/email-${S3_KEY}.eml" TEMP_FILE="/tmp/email-${S3_KEY}.eml"
echo "===================================" echo "==================================="
echo "Requeue E-Mail zu SQS Queue" echo "Requeue E-Mail zu SQS Queue"
echo "===================================" echo "==================================="
echo "Bucket: $BUCKET" echo "Bucket: $BUCKET"
echo "S3 Key: $S3_KEY" echo "S3 Key: $S3_KEY"
# Prüfen ob S3 Object existiert # Prüfen ob S3 Object existiert
echo "Prüfe S3 Object..." echo "Prüfe S3 Object..."
if ! aws s3api head-object if ! aws s3api head-object \
--bucket "$BUCKET" --bucket "$BUCKET" \
--key "$S3_KEY" --key "$S3_KEY" \
--region "$AWS_REGION" &>/dev/null; then --region "$AWS_REGION" &>/dev/null; then
echo "ERROR: S3 Object nicht gefunden: s3://$BUCKET/$S3_KEY" echo "ERROR: S3 Object nicht gefunden: s3://$BUCKET/$S3_KEY"
exit 1 exit 1
fi fi
echo "✓ S3 Object existiert" echo "✓ S3 Object existiert"
# Wenn FROM oder RECIPIENTS nicht angegeben, extrahiere aus E-Mail # Wenn FROM oder RECIPIENTS nicht angegeben, extrahiere aus E-Mail
if [ -z "$FROM" ] || [ -z "$RECIPIENTS" ]; then if [ -z "$FROM" ] || [ -z "$RECIPIENTS" ]; then
echo "Extrahiere Headers aus E-Mail..." echo "Extrahiere Headers aus E-Mail..."
aws s3 cp "s3://$BUCKET/$S3_KEY" "$TEMP_FILE" --region "$AWS_REGION" --quiet aws s3 cp "s3://$BUCKET/$S3_KEY" "$TEMP_FILE" --region "$AWS_REGION" --quiet
#Embedded Python zum Parsen (robust für folded headers etc.)
PARSE_OUTPUT=$(python3 -c " # Aufruf der separaten Python-Datei
import sys if ! command -v python3 &> /dev/null; then
import email echo "ERROR: python3 ist nicht installiert."
with open(sys.argv[1], 'rb') as f: rm -f "$TEMP_FILE"
msg = email.message_from_bytes(f.read()) exit 1
from_addr = msg.get('From', '') fi
to_addrs = msg.get_all('To', []) + msg.get_all('Cc', []) if [ ! -f "extract_email_headers.py" ]; then
recipients = ','.join([str(addr) for addr in to_addrs]) if to_addrs else '' echo "ERROR: extract_email_headers.py nicht gefunden (muss im selben Verzeichnis liegen)."
print(f'FROM:{from_addr}') rm -f "$TEMP_FILE"
print(f'RECIPIENTS:{recipients}') exit 1
" "$TEMP_FILE") fi
PARSE_OUTPUT=$(python3 extract_email_headers.py "$TEMP_FILE")
# Output parsen # Output parsen
EXTRACTED_FROM=$(echo "$PARSE_OUTPUT" | grep '^FROM:' | cut -d':' -f2-) EXTRACTED_FROM=$(echo "$PARSE_OUTPUT" | grep '^FROM:' | cut -d':' -f2-)
EXTRACTED_RECIPIENTS=$(echo "$PARSE_OUTPUT" | grep '^RECIPIENTS:' | cut -d':' -f2-) EXTRACTED_RECIPIENTS=$(echo "$PARSE_OUTPUT" | grep '^RECIPIENTS:' | cut -d':' -f2-)
# Verwende extrahierte Werte, falls nicht angegeben # Verwende extrahierte Werte, falls nicht angegeben
FROM=${FROM:-$EXTRACTED_FROM} FROM=${FROM:-$EXTRACTED_FROM}
RECIPIENTS=${RECIPIENTS:-$EXTRACTED_RECIPIENTS} RECIPIENTS=${RECIPIENTS:-$EXTRACTED_RECIPIENTS}
# Aufräumen # Aufräumen
rm -f "$TEMP_FILE" rm -f "$TEMP_FILE"
fi fi
# Wenn immer noch leer, Error # Wenn immer noch leer, Error
if [ -z "$FROM" ] || [ -z "$RECIPIENTS" ]; then if [ -z "$FROM" ] || [ -z "$RECIPIENTS" ]; then
echo "ERROR: Konnte FROM oder RECIPIENTS nicht extrahieren oder angeben." echo "ERROR: Konnte FROM oder RECIPIENTS nicht extrahieren oder angeben."
exit 1 exit 1
fi fi
# Domain aus erstem Recipient extrahieren # Domain aus erstem Recipient extrahieren
FIRST_RECIPIENT=$(echo "$RECIPIENTS" | cut -d',' -f1) FIRST_RECIPIENT=$(echo "$RECIPIENTS" | cut -d',' -f1)
DOMAIN=$(echo "$FIRST_RECIPIENT" | cut -d'@' -f2) DOMAIN=$(echo "$FIRST_RECIPIENT" | cut -d'@' -f2)
# Queue-Name aus Domain ableiten # Queue-Name aus Domain ableiten
QUEUE_NAME="${DOMAIN//./-}-queue" QUEUE_NAME="${DOMAIN//./-}-queue"
echo "From: $FROM" echo "From: $FROM"
echo "Recipients: $RECIPIENTS" echo "Recipients: $RECIPIENTS"
echo "Domain: $DOMAIN" echo "Domain: $DOMAIN"
echo "Queue: $QUEUE_NAME" echo "Queue: $QUEUE_NAME"
echo "" echo ""
# Queue URL ermitteln # Queue URL ermitteln
echo "Ermittle Queue URL..." echo "Ermittle Queue URL..."
QUEUE_URL=$(aws sqs get-queue-url QUEUE_URL=$(aws sqs get-queue-url \
--queue-name "$QUEUE_NAME" --queue-name "$QUEUE_NAME" \
--region "$AWS_REGION" --region "$AWS_REGION" \
--query 'QueueUrl' --query 'QueueUrl' \
--output text 2>/dev/null) --output text 2>/dev/null)
if [ -z "$QUEUE_URL" ]; then if [ -z "$QUEUE_URL" ]; then
echo "ERROR: Queue nicht gefunden: $QUEUE_NAME" echo "ERROR: Queue nicht gefunden: $QUEUE_NAME"
exit 1 exit 1
fi fi
echo "✓ Queue URL: $QUEUE_URL" echo "✓ Queue URL: $QUEUE_URL"
# Recipients als Array für JSON # Recipients als Array für JSON
RECIPIENTS_ARRAY=$(echo "$RECIPIENTS" | tr ',' '\n' | jq -R . | jq -s .) RECIPIENTS_ARRAY=$(echo "$RECIPIENTS" | tr ',' '\n' | jq -R . | jq -s .)
# Fake SES-Event erstellen # Fake SES-Event erstellen
SES_DATA=$(jq -n SES_DATA=$(jq -n \
--arg from "$FROM" --arg from "$FROM" \
--arg msgid "$S3_KEY" --arg msgid "$S3_KEY" \
--argjson recipients "$RECIPIENTS_ARRAY" --argjson recipients "$RECIPIENTS_ARRAY" \
'{ '{
mail: { mail: {
source: $from, source: $from,
@ -107,11 +129,12 @@ receipt: {
recipients: $recipients recipients: $recipients
} }
}') }')
# Fake SNS-Payload (Wrapper) # Fake SNS-Payload (Wrapper)
FAKE_SNS_PAYLOAD=$(jq -n FAKE_SNS_PAYLOAD=$(jq -n \
--argjson message "$SES_DATA" --argjson message "$SES_DATA" \
--arg msgid "$(uuidgen)" --arg msgid "$(uuidgen)" \
--arg timestamp "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" --arg timestamp "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
'{ '{
Type: "Notification", Type: "Notification",
MessageId: $msgid, MessageId: $msgid,
@ -120,13 +143,16 @@ Subject: "Amazon SES Email Receipt Notification",
Message: ($message | tostring), Message: ($message | tostring),
Timestamp: $timestamp Timestamp: $timestamp
}') }')
# Message in Queue senden # Message in Queue senden
echo "Sende Message in Queue..." echo "Sende Message in Queue..."
RESPONSE=$(aws sqs send-message RESPONSE=$(aws sqs send-message \
--queue-url "$QUEUE_URL" --queue-url "$QUEUE_URL" \
--region "$AWS_REGION" --region "$AWS_REGION" \
--message-body "$FAKE_SNS_PAYLOAD") --message-body "$FAKE_SNS_PAYLOAD")
MESSAGE_ID=$(echo "$RESPONSE" | jq -r '.MessageId') MESSAGE_ID=$(echo "$RESPONSE" | jq -r '.MessageId')
echo "" echo ""
echo "===================================" echo "==================================="
echo "✅ E-Mail erfolgreich in Queue" echo "✅ E-Mail erfolgreich in Queue"