diff --git a/scripts/bounce-watcher.sh b/scripts/bounce-watcher.sh index a84fa13..160a53f 100644 --- a/scripts/bounce-watcher.sh +++ b/scripts/bounce-watcher.sh @@ -10,9 +10,16 @@ LOG=/var/log/mail.log AUTH="api:6X1rKPea61N4rZ1S65Hx5zvqzbCj30F6nvEe9oVGH_Y" API="http://localhost:9100" +# Get the UUID of the currently running campaign (if any) +get_campaign_uuid() { + curl -s -u "$AUTH" "$API/api/campaigns?status=running&per_page=1" 2>/dev/null \ + | grep -oP '"uuid":"[^"]*"' | head -1 | cut -d'"' -f4 +} + # Track queue IDs from campaign sends (from=noreply@) so we only # report bounces for those, not for system emails. declare -A CAMPAIGN_QIDS +CURRENT_UUID="" tail -F "$LOG" 2>/dev/null | while IFS= read -r line; do @@ -39,11 +46,19 @@ tail -F "$LOG" 2>/dev/null | while IFS= read -r line; do # Only report if this was a campaign email if [ -n "$RCPT" ] && [ -n "${CAMPAIGN_QIDS[$QID]+x}" ]; then + # Refresh campaign UUID periodically + if [ -z "$CURRENT_UUID" ]; then + CURRENT_UUID=$(get_campaign_uuid) + fi + UUID_FIELD="" + if [ -n "$CURRENT_UUID" ]; then + UUID_FIELD=", \"campaign_uuid\": \"$CURRENT_UUID\"" + fi curl -s -u "$AUTH" -X POST "$API/webhooks/bounce" \ -H "Content-Type: application/json" \ - -d "{\"email\": \"$RCPT\", \"source\": \"postfix\", \"type\": \"hard\"}" \ + -d "{\"email\": \"$RCPT\", \"source\": \"postfix\", \"type\": \"hard\"$UUID_FIELD}" \ >/dev/null 2>&1 - logger -t bounce-notify "Hard bounce: $RCPT (qid=$QID)" + logger -t bounce-notify "Hard bounce: $RCPT (qid=$QID, campaign=$CURRENT_UUID)" unset CAMPAIGN_QIDS[$QID] fi fi @@ -54,11 +69,18 @@ tail -F "$LOG" 2>/dev/null | while IFS= read -r line; do RCPT=$(echo "$line" | sed -n 's/.*to=<\([^>]*\)>.*/\1/p') if [ -n "$RCPT" ] && [ -n "${CAMPAIGN_QIDS[$QID]+x}" ]; then + if [ -z "$CURRENT_UUID" ]; then + CURRENT_UUID=$(get_campaign_uuid) + fi + UUID_FIELD="" + if [ -n "$CURRENT_UUID" ]; then + UUID_FIELD=", \"campaign_uuid\": \"$CURRENT_UUID\"" + fi curl -s -u "$AUTH" -X POST "$API/webhooks/bounce" \ -H "Content-Type: application/json" \ - -d "{\"email\": \"$RCPT\", \"source\": \"postfix\", \"type\": \"soft\"}" \ + -d "{\"email\": \"$RCPT\", \"source\": \"postfix\", \"type\": \"soft\"$UUID_FIELD}" \ >/dev/null 2>&1 - logger -t bounce-notify "Soft bounce (5xx): $RCPT (qid=$QID)" + logger -t bounce-notify "Soft bounce (5xx): $RCPT (qid=$QID, campaign=$CURRENT_UUID)" fi fi @@ -66,6 +88,11 @@ tail -F "$LOG" 2>/dev/null | while IFS= read -r line; do if echo "$line" | grep -q "removed$"; then QID=$(echo "$line" | sed -n 's/.*postfix\/[a-z]*\[\([0-9]*\)\]: \([A-Z0-9]*\):.*/\2/p') unset CAMPAIGN_QIDS[$QID] 2>/dev/null + # Refresh campaign UUID every 100 removed messages + REMOVED_COUNT=$((${REMOVED_COUNT:-0} + 1)) + if [ $((REMOVED_COUNT % 100)) -eq 0 ]; then + CURRENT_UUID=$(get_campaign_uuid) + fi fi done