Fix bounce watcher: pass campaign_uuid to Listmonk webhook
Bounces showed 0 in campaigns because the webhook didn't include campaign_uuid. Now fetches UUID of running campaign via API and includes it in bounce reports. Refreshes every 100 messages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
72f692007e
commit
763100f664
1 changed files with 31 additions and 4 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue