smtp_direct.py is dead and gone.
[mailman.git] / src / mailman / mta / docs / verp.txt
blobe31419bdbbf8bfefca2884d72c63955d550c9e4c
1 ======================
2 Standard VERP delivery
3 ======================
5 Variable Envelope Return Path (VERP_) delivery is an alternative to bulk_
6 delivery, where an individual message is crafted uniquely for each recipient.
8 .. _VERP: http://en.wikipedia.org/wiki/Variable_envelope_return_path
9 .. _bulk: bulk.txt
11 The cost of enabling VERP is that Mailman must send to the upstream MTA, one
12 message per recipient.  Under bulk delivery, an exact copy of one message can
13 be sent to many recipients, greatly reducing the bandwidth for delivery.
15 In Mailman, enabling VERP delivery for bounce detection brings with it a side
16 benefit: the message which must be crafted uniquely for each recipient, can be
17 further personalized to include all kinds of information unique to that
18 recipient.  In the simplest case, the message can contain footer information,
19 e.g.  pointing the user to their account URL or including a user-specific
20 unsubscription link.  In theory, VERP delivery means we can do sophisticated
21 `mail merge`_ operations.
23 .. _`mail merge`: http://en.wikipedia.org/wiki/Mail_merge
25 Mailman's use of the term VERP really means "message personalization".
27     >>> from mailman.mta.verp import VERPDelivery
28     >>> verp = VERPDelivery()
30 Delivery strategies must implement the proper interface.
32     >>> from mailman.interfaces.mta import IMailTransportAgentDelivery
33     >>> from zope.interface.verify import verifyObject
34     >>> verifyObject(IMailTransportAgentDelivery, verp)
35     True
38 No recipients
39 =============
41 The message metadata specifies the set of recipients to send this message to.
42 If there are no recipients, there's nothing to do.
44     >>> mlist = create_list('test@example.com')
45     >>> msg = message_from_string("""\
46     ... From: aperson@example.org
47     ... To: test@example.com
48     ... Subject: test one
49     ... Message-ID: <aardvark>
50     ...
51     ... This is a test.
52     ... """)
54     >>> verp.deliver(mlist, msg, {})
55     {}
56     >>> len(list(smtpd.messages))
57     0
59     >>> verp.deliver(mlist, msg, dict(recipients=set()))
60     {}
61     >>> len(list(smtpd.messages))
62     0
65 Individual copy
66 ===============
68 Each recipient of the message gets an individual, personalized copy of the
69 message, with their email address encoded into the envelope sender.  This is
70 so the return path will point back to Mailman but allow for decoding of the
71 intended recipient's delivery address.
73     >>> recipients = set([
74     ...     'aperson@example.com',
75     ...     'bperson@example.com',
76     ...     'cperson@example.com',
77     ...     ])
79 VERPing is only actually done if the metadata requests it.
81     >>> msgdata = dict(recipients=recipients, verp=True)
82     >>> verp.deliver(mlist, msg, msgdata)
83     {}
84     >>> messages = list(smtpd.messages)
85     >>> len(messages)
86     3
88     >>> from operator import itemgetter
89     >>> for message in sorted(messages, key=itemgetter('x-rcptto')):
90     ...     print message.as_string()
91     ...     print '----------'
92     From: aperson@example.org
93     To: test@example.com
94     Subject: test one
95     Message-ID: <aardvark>
96     Sender: test-bounces+aperson=example.com@example.com
97     Errors-To: test-bounces+aperson=example.com@example.com
98     X-Peer: ...
99     X-MailFrom: test-bounces+aperson=example.com@example.com
100     X-RcptTo: aperson@example.com
101     <BLANKLINE>
102     This is a test.
103     ----------
104     From: aperson@example.org
105     To: test@example.com
106     Subject: test one
107     Message-ID: <aardvark>
108     Sender: test-bounces+bperson=example.com@example.com
109     Errors-To: test-bounces+bperson=example.com@example.com
110     X-Peer: ...
111     X-MailFrom: test-bounces+bperson=example.com@example.com
112     X-RcptTo: bperson@example.com
113     <BLANKLINE>
114     This is a test.
115     ----------
116     From: aperson@example.org
117     To: test@example.com
118     Subject: test one
119     Message-ID: <aardvark>
120     Sender: test-bounces+cperson=example.com@example.com
121     Errors-To: test-bounces+cperson=example.com@example.com
122     X-Peer: ...
123     X-MailFrom: test-bounces+cperson=example.com@example.com
124     X-RcptTo: cperson@example.com
125     <BLANKLINE>
126     This is a test.
127     ----------
129 The deliverer made a copy of the original message, so it wasn't changed.
131     >>> print msg.as_string()
132     From: aperson@example.org
133     To: test@example.com
134     Subject: test one
135     Message-ID: <aardvark>
136     <BLANKLINE>
137     This is a test.
138     <BLANKLINE>