The task. A bounce or complaint arrives several days after sending. Figuring out which client, campaign and recipient it concerns means either parsing a report whose format differs for every receiver, or reading the address it arrived at.
What it is made of:
The parts have different scopes. The processors are node-level, and their lists are matched against the address the message arrived at; changing the bounce processor’s list requires a restart. Both require the node to accept this mail: for complaints, to be the MX of the complaint domain.
How they interact. The manual recommends a unique address per message directly — something like customer1-campaign563-uniqueID498294@bounce.yourdomain.com — and the idea generalizes: such an address names the campaign and the recipient by itself, and identification becomes a lookup rather than an interpretation. VERP generates such addresses itself, so the two halves of the scheme are one solution from different ends: at submission and at receipt. The scheme does not eliminate the variety of formats: identification is reliable, parsing is not, so unidentified reports are worth keeping.
What each part gives:
| Part | Where it is set | What appears |
|---|---|---|
| bounce address list | <bounce-processor> | rb records |
| VERP | message submission | a unique return address per recipient |
| complaint address list | <feedback-loop-processor> | f records |
| job | the x-job header and process-x-job | the jobId field |
<bounce-processor> <address-list> address /^b-[a-z0-9-]+@bounce\.example\.com$/ </address-list> </bounce-processor> <feedback-loop-processor> <address-list> address /^fbl@fbl\.example\.com$/ </address-list> </feedback-loop-processor>
grep -c '^rb,' /var/log/pmta/acct-*.csv