diff --git a/basic_setup/awsses.sh b/basic_setup/awsses.sh index 8114e64..0ee86a1 100755 --- a/basic_setup/awsses.sh +++ b/basic_setup/awsses.sh @@ -1,7 +1,16 @@ #!/bin/bash -# awsses_lambda_global.sh - SES Setup mit S3 + Global Lambda Shim -> SQS +# awsses.sh - SES Setup mit S3 + Global Lambda Shim -> SQS # Dieses Skript ist idempotent: Es kann sicher mehrfach ausgeführt werden. # Globale Lambda für alle Domains. +# +# MAIL FROM Subdomain: +# Standard: mail.${DOMAIN_NAME} +# Override: export MAIL_FROM_SUBDOMAIN="mailfrom" (nur der Prefix, ohne Domain) +# +# Beispiel: +# export DOMAIN_NAME="buddelectric.net" +# export MAIL_FROM_SUBDOMAIN="mailfrom" # → mailfrom.buddelectric.net +# ./awsses.sh set -e @@ -21,6 +30,10 @@ AWS_REGION=${AWS_REGION:-"us-east-2"} EMAIL_PREFIX=${EMAIL_PREFIX:-""} CONFIGURATION_SET_NAME="relay-outbound" +# MAIL FROM Subdomain (konfigurierbar) +MAIL_FROM_SUBDOMAIN=${MAIL_FROM_SUBDOMAIN:-"mail"} +MAIL_FROM_DOMAIN="${MAIL_FROM_SUBDOMAIN}.${DOMAIN_NAME}" + # Bucket Name generieren falls leer if [ -z "$S3_BUCKET_NAME" ]; then S3_BUCKET_NAME=$(echo "$DOMAIN_NAME" | tr '.' '-' | awk '{print $0 "-emails"}') @@ -35,6 +48,7 @@ LAMBDA_ROLE_NAME="SesShimGlobalRole" echo "==========================================================" echo " SES Setup (S3 -> Global Lambda Shim -> SQS) für $DOMAIN_NAME" +echo " MAIL FROM: $MAIL_FROM_DOMAIN" echo "==========================================================" # --------------------------------------------------------- @@ -46,9 +60,11 @@ if ! aws sesv2 get-email-identity --email-identity ${DOMAIN_NAME} --region ${AWS fi # Update Attributes (Idempotent) aws sesv2 put-email-identity-dkim-attributes --email-identity ${DOMAIN_NAME} --signing-enabled --region ${AWS_REGION} -aws sesv2 put-email-identity-mail-from-attributes --email-identity ${DOMAIN_NAME} --mail-from-domain "mail.${DOMAIN_NAME}" --behavior-on-mx-failure USE_DEFAULT_VALUE --region ${AWS_REGION} +aws sesv2 put-email-identity-mail-from-attributes --email-identity ${DOMAIN_NAME} --mail-from-domain "${MAIL_FROM_DOMAIN}" --behavior-on-mx-failure USE_DEFAULT_VALUE --region ${AWS_REGION} aws sesv2 put-email-identity-configuration-set-attributes --email-identity ${DOMAIN_NAME} --configuration-set-name "$CONFIGURATION_SET_NAME" --region ${AWS_REGION} +echo " -> MAIL FROM Domain: ${MAIL_FROM_DOMAIN}" + # --------------------------------------------------------- # 2. SQS Queue holen (nur zur Validierung, Lambda holt dynamisch) # --------------------------------------------------------- @@ -149,7 +165,7 @@ RULE_JSON=$(jq -n \ --arg larn "$LAMBDA_ARN" \ --arg rule "$RULE_NAME" \ --arg domain "$DOMAIN_NAME" \ - --arg subdomain "mail.$DOMAIN_NAME" \ + --arg subdomain "${MAIL_FROM_DOMAIN}" \ '{ Name: $rule, Enabled: true, @@ -181,7 +197,12 @@ else fi # Aktivieren aws ses set-active-receipt-rule-set --rule-set-name "bizmatch-ruleset" --region ${AWS_REGION} + echo "========================================================" -echo "✅ Setup erfolgreich. Globale Lambda ($LAMBDA_NAME) für alle Domains." -echo " S3 -> Lambda -> Domain-spezifische SQS" +echo "✅ Setup erfolgreich." +echo " Domain: $DOMAIN_NAME" +echo " MAIL FROM: $MAIL_FROM_DOMAIN" +echo " S3 Bucket: $S3_BUCKET_NAME" +echo " SQS Queue: $QUEUE_NAME" +echo " Lambda: $LAMBDA_NAME (global)" echo "========================================================" \ No newline at end of file diff --git a/basic_setup/cloudflareMigrationDns.sh b/basic_setup/cloudflareMigrationDns.sh new file mode 100644 index 0000000..ddc7dc1 --- /dev/null +++ b/basic_setup/cloudflareMigrationDns.sh @@ -0,0 +1,358 @@ +#!/bin/bash +# cloudflareMigrationDns.sh - DNS Setup für sanfte E-Mail-Migration +# +# Dieses Script ist speziell für die Migration von einem alten Provider +# zu Bay Area Email (Amazon SES + DMS). Es: +# - Erkennt automatisch die MAIL FROM Subdomain aus SES +# - Prüft auf CNAME-Konflikte bevor Records gesetzt werden +# - Enthält den alten Provider SPF während der Migration +# - Setzt KEINE Autodiscover/SRV Records (das kommt erst in Phase 3) +# +# Voraussetzungen: +# - awsses.sh wurde bereits ausgeführt (SES Identity existiert) +# - Domain ist bereits in Cloudflare +# +# Verwendung: +# export DOMAIN_NAME="buddelectric.net" +# export CF_API_TOKEN="xxx" +# export OLD_PROVIDER_SPF="include:_spf.hostedemail.com" # SPF des alten Providers +# ./cloudflareMigrationDns.sh +# +# Optionale Parameter: +# export OLD_PROVIDER_SPF="" # Kein alter SPF nötig +# export DRY_RUN="true" # Nur anzeigen, nichts ändern +# export SKIP_MX="true" # MX nicht setzen (für Tests) + +set -e + +# ========================================== +# KONFIGURATION & CHECKS +# ========================================== + +AWS_REGION=${AWS_REGION:-"us-east-2"} +DRY_RUN=${DRY_RUN:-"false"} +SKIP_MX=${SKIP_MX:-"false"} + +if [ -z "$DOMAIN_NAME" ]; then + echo "❌ Fehler: DOMAIN_NAME ist nicht gesetzt." + echo " export DOMAIN_NAME='buddelectric.net'" + exit 1 +fi +if [ -z "$CF_API_TOKEN" ]; then + echo "❌ Fehler: CF_API_TOKEN fehlt." + exit 1 +fi +if ! command -v jq &> /dev/null; then + echo "❌ Fehler: 'jq' fehlt." + exit 1 +fi +if ! command -v aws &> /dev/null; then + echo "❌ Fehler: 'aws' CLI fehlt." + exit 1 +fi + +echo "============================================================" +echo " 📧 Migration DNS Setup für: $DOMAIN_NAME" +echo "============================================================" +if [ "$DRY_RUN" = "true" ]; then + echo " ⚠️ DRY RUN - Es werden KEINE Änderungen vorgenommen!" +fi +echo "" + +# ========================================== +# 1. MAIL FROM Subdomain aus SES ermitteln +# ========================================== + +echo "--- [1/7] MAIL FROM Subdomain aus SES ermitteln ---" + +SES_IDENTITY=$(aws sesv2 get-email-identity \ + --email-identity "${DOMAIN_NAME}" \ + --region "${AWS_REGION}" \ + --output json 2>/dev/null) + +if [ $? -ne 0 ] || [ -z "$SES_IDENTITY" ]; then + echo "❌ SES Identity für ${DOMAIN_NAME} nicht gefunden!" + echo " Bitte zuerst ./awsses.sh ausführen." + exit 1 +fi + +MAIL_FROM_DOMAIN=$(echo "$SES_IDENTITY" | jq -r '.MailFromAttributes.MailFromDomain // empty') + +if [ -z "$MAIL_FROM_DOMAIN" ]; then + echo "⚠️ Keine MAIL FROM Domain in SES konfiguriert. Verwende mail.${DOMAIN_NAME}" + MAIL_FROM_DOMAIN="mail.${DOMAIN_NAME}" +fi + +# Extrahiere den Subdomain-Prefix (z.B. "mailfrom" aus "mailfrom.buddelectric.net") +MAIL_FROM_PREFIX=$(echo "$MAIL_FROM_DOMAIN" | sed "s/\.${DOMAIN_NAME}$//") + +echo " ✓ MAIL FROM Domain: ${MAIL_FROM_DOMAIN} (Prefix: ${MAIL_FROM_PREFIX})" + +# ========================================== +# 2. Cloudflare Zone ID ermitteln +# ========================================== + +echo "" +echo "--- [2/7] Cloudflare Zone ID ermitteln ---" + +ZONE_RESPONSE=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$DOMAIN_NAME" \ + -H "Authorization: Bearer $CF_API_TOKEN" \ + -H "Content-Type: application/json") + +if [ "$(echo $ZONE_RESPONSE | jq -r '.success')" != "true" ]; then + echo "❌ Fehler beim Abrufen der Zone ID:" + echo $ZONE_RESPONSE | jq . + exit 1 +fi + +CF_ZONE_ID=$(echo $ZONE_RESPONSE | jq -r '.result[0].id') +if [ "$CF_ZONE_ID" = "null" ] || [ -z "$CF_ZONE_ID" ]; then + echo "❌ Zone für $DOMAIN_NAME nicht in Cloudflare gefunden!" + exit 1 +fi +echo " ✓ Zone ID: $CF_ZONE_ID" + +# ========================================== +# 3. Bestehende Records prüfen (Konflikte erkennen) +# ========================================== + +echo "" +echo "--- [3/7] Bestehende DNS Records prüfen ---" + +# Alle Records der Zone abrufen +EXISTING_RECORDS=$(curl -s -X GET \ + "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records?per_page=100" \ + -H "Authorization: Bearer $CF_API_TOKEN" \ + -H "Content-Type: application/json") + +# Prüfe auf CNAME-Konflikt mit MAIL FROM Subdomain +MAIL_FROM_CNAME=$(echo "$EXISTING_RECORDS" | jq -r \ + --arg name "${MAIL_FROM_DOMAIN}" \ + '.result[] | select(.type == "CNAME" and .name == $name) | .content') + +if [ -n "$MAIL_FROM_CNAME" ]; then + echo "" + echo " ⚠️ KONFLIKT ERKANNT!" + echo " ${MAIL_FROM_DOMAIN} hat einen CNAME → ${MAIL_FROM_CNAME}" + echo " Ein CNAME erlaubt keine weiteren Records (MX, TXT)." + echo "" + echo " Optionen:" + echo " 1) CNAME löschen lassen (falls kein Client diesen Hostnamen nutzt)" + echo " 2) awsses.sh mit MAIL_FROM_SUBDOMAIN='mailfrom' nochmal ausführen" + echo "" + + # Prüfe ob es ein alternativer MAIL FROM wäre + if [ "$MAIL_FROM_PREFIX" = "mail" ]; then + echo " 💡 Empfehlung: Führe folgendes aus und starte dann dieses Script neu:" + echo "" + echo " export MAIL_FROM_SUBDOMAIN=\"mailfrom\"" + echo " export DOMAIN_NAME=\"${DOMAIN_NAME}\"" + echo " ./awsses.sh" + echo "" + echo " Dann dieses Script erneut starten." + exit 1 + fi +fi + +# Prüfe auf bestehenden MX Record +EXISTING_MX=$(echo "$EXISTING_RECORDS" | jq -r \ + --arg name "${DOMAIN_NAME}" \ + '.result[] | select(.type == "MX" and .name == $name) | "\(.priority) \(.content)"') + +if [ -n "$EXISTING_MX" ]; then + echo " ℹ️ Bestehende MX Records:" + echo "$EXISTING_MX" | while read line; do echo " $line"; done + echo " → Diese müssen manuell gelöscht werden bevor der neue MX gesetzt wird!" + echo " (Script erstellt nur neue Records, löscht keine alten)" +fi + +# Prüfe auf bestehenden SPF +EXISTING_SPF=$(echo "$EXISTING_RECORDS" | jq -r \ + --arg name "${DOMAIN_NAME}" \ + '.result[] | select(.type == "TXT" and .name == $name and (.content | contains("v=spf1"))) | .content') + +if [ -n "$EXISTING_SPF" ]; then + echo " ℹ️ Bestehender SPF: $EXISTING_SPF" + echo " → Muss manuell gelöscht/ersetzt werden!" +fi + +echo "" + +# ========================================== +# HILFSFUNKTIONEN +# ========================================== + +create_dns_record() { + local TYPE=$1 + local NAME=$2 + local CONTENT=$3 + local PROXIED=${4:-"false"} + local TTL=${5:-3600} + local PRIORITY=$6 + + if [ "$DRY_RUN" = "true" ]; then + echo " [DRY RUN] Würde erstellen: $TYPE $NAME → $CONTENT" + [ -n "$PRIORITY" ] && echo " Priorität: $PRIORITY" + return + fi + + local JSON_DATA="" + + if [ "$TYPE" = "MX" ]; then + if [ -z "$PRIORITY" ]; then PRIORITY=10; fi + JSON_DATA="{ + \"type\": \"$TYPE\", \"name\": \"$NAME\", \"content\": \"$CONTENT\", + \"ttl\": $TTL, \"priority\": $PRIORITY, \"proxied\": $PROXIED + }" + elif [ "$TYPE" = "TXT" ]; then + CONTENT=$(echo "$CONTENT" | sed 's/"//g') + JSON_DATA="{ + \"type\": \"$TYPE\", \"name\": \"$NAME\", \"content\": \"\\\"$CONTENT\\\"\", + \"ttl\": $TTL, \"proxied\": $PROXIED + }" + else + JSON_DATA="{ + \"type\": \"$TYPE\", \"name\": \"$NAME\", \"content\": \"$CONTENT\", + \"ttl\": $TTL, \"proxied\": $PROXIED + }" + fi + + RESULT=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records" \ + -H "Authorization: Bearer $CF_API_TOKEN" \ + -H "Content-Type: application/json" \ + --data "$JSON_DATA") + + SUCCESS=$(echo "$RESULT" | jq -r '.success') + if [ "$SUCCESS" = "true" ]; then + echo " ✓ $TYPE $NAME → $CONTENT" + else + ERROR_MSG=$(echo "$RESULT" | jq -r '.errors[0].message // "Unbekannt"') + ERROR_CODE=$(echo "$RESULT" | jq -r '.errors[0].code // 0') + if [ "$ERROR_CODE" = "81057" ]; then + echo " ⏭ $TYPE $NAME existiert bereits (übersprungen)" + else + echo " ✗ $TYPE $NAME FEHLER: $ERROR_MSG" + fi + fi +} + +# ========================================== +# 4. DKIM Records (aus SES API) +# ========================================== + +echo "--- [4/7] SES DKIM Records ---" + +DKIM_TOKENS=$(aws ses get-identity-dkim-attributes \ + --identities ${DOMAIN_NAME} --region ${AWS_REGION} \ + --query "DkimAttributes.\"${DOMAIN_NAME}\".DkimTokens" --output text 2>/dev/null) + +if [ -n "$DKIM_TOKENS" ] && [ "$DKIM_TOKENS" != "None" ]; then + for TOKEN in ${DKIM_TOKENS}; do + create_dns_record "CNAME" "${TOKEN}._domainkey.${DOMAIN_NAME}" "${TOKEN}.dkim.amazonses.com" "false" + done +else + echo " ⚠️ Keine DKIM Tokens gefunden. SES Identity evtl. noch nicht verifiziert?" +fi + +# SES Verification Token +VERIFICATION_TOKEN=$(aws ses get-identity-verification-attributes \ + --identities ${DOMAIN_NAME} --region ${AWS_REGION} \ + --query "VerificationAttributes.\"${DOMAIN_NAME}\".VerificationToken" --output text 2>/dev/null) + +if [ -n "$VERIFICATION_TOKEN" ] && [ "$VERIFICATION_TOKEN" != "None" ]; then + create_dns_record "TXT" "_amazonses.${DOMAIN_NAME}" "${VERIFICATION_TOKEN}" "false" +fi + +# ========================================== +# 5. MX Record (SES Inbound) +# ========================================== + +echo "" +echo "--- [5/7] MX Record ---" + +if [ "$SKIP_MX" = "true" ]; then + echo " ⏭ MX übersprungen (SKIP_MX=true)" + echo " → Setze MX manuell wenn du bereit bist:" + echo " ${DOMAIN_NAME} MX 10 inbound-smtp.${AWS_REGION}.amazonaws.com" +else + echo " ⚠️ ACHTUNG: Alte MX Records müssen VORHER manuell gelöscht werden!" + echo " Alter MX vorhanden? Siehe Prüfung oben." + echo "" + create_dns_record "MX" "${DOMAIN_NAME}" "inbound-smtp.${AWS_REGION}.amazonaws.com" "false" 3600 10 +fi + +# ========================================== +# 6. MAIL FROM Subdomain (MX + SPF) +# ========================================== + +echo "" +echo "--- [6/7] MAIL FROM Subdomain: ${MAIL_FROM_DOMAIN} ---" + +create_dns_record "MX" "${MAIL_FROM_DOMAIN}" "feedback-smtp.${AWS_REGION}.amazonses.com" "false" 3600 10 +create_dns_record "TXT" "${MAIL_FROM_DOMAIN}" "v=spf1 include:amazonses.com ~all" "false" + +# ========================================== +# 7. SPF & DMARC (mit altem Provider!) +# ========================================== + +echo "" +echo "--- [7/7] SPF & DMARC ---" + +# SPF mit beiden Providern (Migration!) +if [ -n "$OLD_PROVIDER_SPF" ]; then + SPF_RECORD="v=spf1 include:amazonses.com ${OLD_PROVIDER_SPF} ~all" + echo " ℹ️ Migrations-SPF (enthält alten Provider):" +else + SPF_RECORD="v=spf1 include:amazonses.com ~all" + echo " ℹ️ Standard-SPF (kein alter Provider angegeben):" +fi +echo " ${SPF_RECORD}" + +create_dns_record "TXT" "${DOMAIN_NAME}" "${SPF_RECORD}" "false" + +# DMARC +create_dns_record "TXT" "_dmarc.${DOMAIN_NAME}" "v=DMARC1; p=none; pct=100; rua=mailto:postmaster@${DOMAIN_NAME}" "false" + +# ========================================== +# ZUSAMMENFASSUNG +# ========================================== + +echo "" +echo "============================================================" +if [ "$DRY_RUN" = "true" ]; then + echo " ⚠️ DRY RUN abgeschlossen - keine Änderungen gemacht" +else + echo " ✅ Migration DNS Setup abgeschlossen" +fi +echo "============================================================" +echo "" +echo " Domain: $DOMAIN_NAME" +echo " MAIL FROM: $MAIL_FROM_DOMAIN" +echo " SPF: $SPF_RECORD" +if [ "$SKIP_MX" = "true" ]; then + echo " MX: ⏭ ÜBERSPRUNGEN (manuelle Aktivierung nötig)" +else + echo " MX: inbound-smtp.${AWS_REGION}.amazonaws.com" +fi +echo "" +echo " 📋 MANUELLE SCHRITTE (falls noch nicht erledigt):" +echo " ─────────────────────────────────────────────────" +echo " 1. Alte MX Records für ${DOMAIN_NAME} löschen" +echo " 2. Alten SPF Record für ${DOMAIN_NAME} löschen" +echo " 3. Alten DKIM Record löschen (falls vorhanden)" + +if [ -n "$MAIL_FROM_CNAME" ]; then + echo " 4. CNAME ${MAIL_FROM_DOMAIN} → ${MAIL_FROM_CNAME} löschen" +fi + +echo "" +echo " ⚠️ NICHT LÖSCHEN während Migration:" +echo " ─────────────────────────────────────" +echo " - imap.${DOMAIN_NAME} (Clients holen noch dort ab)" +echo " - pop.${DOMAIN_NAME} (Clients holen noch dort ab)" +echo " - smtp.${DOMAIN_NAME} (Clients senden noch dort)" +echo " - webmail.${DOMAIN_NAME} (falls vorhanden)" +echo "" +echo " Diese Records werden erst in Phase 3 (nach vollständiger" +echo " Client-Umstellung) gelöscht mit cloudflareDns.sh" +echo "============================================================" \ No newline at end of file diff --git a/basic_setup/test_migration_email.sh b/basic_setup/test_migration_email.sh new file mode 100644 index 0000000..d00ee42 --- /dev/null +++ b/basic_setup/test_migration_email.sh @@ -0,0 +1,169 @@ +#!/bin/bash +# test_migration_email.sh - Stellt eine Test-EMail in S3 + SQS ein +# +# Simuliert den kompletten SES-Eingang: Mail landet in S3, Metadaten in SQS. +# Der Worker holt sie dann ab und verarbeitet sie (Delivery oder Forward). +# +# Verwendung: +# ./test_migration_email.sh cielectrical.com carlosr@cielectrical.com +# ./test_migration_email.sh buddelectric.net service@buddelectric.net +# +# Optionale Absenderadresse: +# ./test_migration_email.sh cielectrical.com carlosr@cielectrical.com test@example.com + +set -e + +# --- Parameter --- +DOMAIN="$1" +RECIPIENT="$2" +FROM_ADDR="${3:-migration-test@andreasknuth.de}" +AWS_REGION=${AWS_REGION:-"us-east-2"} + +if [ -z "$DOMAIN" ] || [ -z "$RECIPIENT" ]; then + echo "Verwendung: $0 [from-address]" + echo "Beispiel: $0 cielectrical.com carlosr@cielectrical.com" + exit 1 +fi + +# --- Abgeleitete Variablen --- +BUCKET_NAME=$(echo "$DOMAIN" | tr '.' '-')"-emails" +QUEUE_NAME=$(echo "$DOMAIN" | tr '.' '-')"-queue" +MESSAGE_ID="test-migration-$(date +%s)-$$" +TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") +DATE_RFC2822=$(date -R) + +echo "============================================================" +echo " 📧 Test-Mail für Migration" +echo "============================================================" +echo " Domain: $DOMAIN" +echo " Empfänger: $RECIPIENT" +echo " Absender: $FROM_ADDR" +echo " Bucket: $BUCKET_NAME" +echo " Queue: $QUEUE_NAME" +echo " Key: $MESSAGE_ID" +echo "" + +# --- Schritt 1: E-Mail als RFC822 erstellen --- +echo "[1/3] Erstelle Test-Email..." + +MAIL_CONTENT="From: Migration Test <${FROM_ADDR}> +To: ${RECIPIENT} +Subject: Migration Test $(date '+%Y-%m-%d %H:%M:%S') +Date: ${DATE_RFC2822} +Message-ID: <${MESSAGE_ID}@test.email-srvr.com> +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 + +Hallo! + +Dies ist eine Test-EMail zur Validierung der E-Mail-Migration. + +Gesendet: $(date) +Domain: ${DOMAIN} +Empfaenger: ${RECIPIENT} +Message-ID: ${MESSAGE_ID} + +Wenn du diese Mail in deiner Inbox siehst, funktioniert der +komplette Pfad: S3 -> SQS -> Worker -> Forward/Delivery. + +-- +Bay Area Affiliates Migration Test" + +TMP_FILE=$(mktemp /tmp/test-mail-XXXXXX.eml) +echo "$MAIL_CONTENT" > "$TMP_FILE" + +echo " ✓ Mail erstellt ($(wc -c < "$TMP_FILE") Bytes)" + +# --- Schritt 2: In S3 Bucket ablegen --- +echo "[2/3] Lade Mail in S3 hoch: s3://${BUCKET_NAME}/${MESSAGE_ID} ..." + +aws s3 cp "$TMP_FILE" "s3://${BUCKET_NAME}/${MESSAGE_ID}" \ + --region "$AWS_REGION" \ + --quiet + +echo " ✓ S3 Upload erfolgreich" + +# --- Schritt 3: SQS Message im Fake-SNS-Format einstellen --- +echo "[3/3] Stelle Message in SQS Queue..." + +QUEUE_URL=$(aws sqs get-queue-url \ + --queue-name "$QUEUE_NAME" \ + --region "$AWS_REGION" \ + --output text \ + --query 'QueueUrl') + +if [ -z "$QUEUE_URL" ]; then + echo " ❌ Queue $QUEUE_NAME nicht gefunden!" + rm -f "$TMP_FILE" + exit 1 +fi + +# SES Event Payload (das was die Lambda normalerweise erzeugt) +SES_DATA=$(jq -n \ + --arg msgId "$MESSAGE_ID" \ + --arg source "$FROM_ADDR" \ + --arg recipient "$RECIPIENT" \ + --arg ts "$TIMESTAMP" \ + '{ + mail: { + messageId: $msgId, + source: $source, + timestamp: $ts, + destination: [$recipient] + }, + receipt: { + recipients: [$recipient], + timestamp: $ts, + action: { + type: "S3", + bucketName: "test", + objectKey: $msgId + } + } + }') + +# Fake SNS Wrapper (so wie deine Lambda es erzeugt) +SQS_BODY=$(jq -n \ + --arg sesData "$SES_DATA" \ + --arg ts "$TIMESTAMP" \ + '{ + Type: "Notification", + MessageId: "test-\(now | tostring)", + TopicArn: "arn:aws:sns:ses-shim:global-topic", + Subject: "Amazon SES Email Receipt Notification", + Message: $sesData, + Timestamp: $ts + }') + +aws sqs send-message \ + --queue-url "$QUEUE_URL" \ + --region "$AWS_REGION" \ + --message-body "$SQS_BODY" \ + --output text \ + --query 'MessageId' + +echo " ✓ SQS Message eingestellt" + +# --- Aufräumen --- +rm -f "$TMP_FILE" + +echo "" +echo "============================================================" +echo " ✅ Test-Mail eingestellt!" +echo "============================================================" +echo "" +echo " Jetzt Worker-Logs beobachten:" +echo " docker logs -f email-worker --tail 50" +echo "" +echo " Der Worker sollte folgendes zeigen:" +echo " 📧 Processing: ${MESSAGE_ID:0:20}... -> ${RECIPIENT}" +echo " ✓ Forwarded via legacy SMTP ... (falls Forward-Rule existiert)" +echo " ODER" +echo " ✓ Delivered to ${RECIPIENT} (falls DMS-Mailbox existiert)" +echo "" +echo " S3 Objekt prüfen:" +echo " aws s3 ls s3://${BUCKET_NAME}/${MESSAGE_ID} --region ${AWS_REGION}" +echo "" +echo " Falls etwas schief geht - SQS Message manuell prüfen:" +echo " aws sqs receive-message --queue-url ${QUEUE_URL} --region ${AWS_REGION}" +echo "============================================================" \ No newline at end of file