1 ==========================
2 Mailing list configuration
3 ==========================
5 Mailing lists can be configured via the REST API.
7 >>> mlist = create_list('ant@example.com')
8 >>> transaction.commit()
11 Reading a configuration
12 =======================
14 All readable attributes for a list are available on a sub-resource.
16 >>> dump_json('http://localhost:9001/3.0/lists/ant@example.com/config')
17 acceptable_aliases: []
18 admin_immed_notify: True
19 admin_notify_mchanges: False
22 allow_list_posts: True
24 archive_policy: public
25 autorespond_owner: none
26 autorespond_postings: none
27 autorespond_requests: none
28 autoresponse_grace_period: 90d
29 autoresponse_owner_text:
30 autoresponse_postings_text:
31 autoresponse_request_text:
32 bounces_address: ant-bounces@example.com
33 collapse_alternatives: True
34 convert_html_to_plaintext: False
36 default_member_action: defer
37 default_nonmember_action: hold
41 digest_last_sent_at: None
42 digest_send_periodic: True
43 digest_size_threshold: 30.0
44 digest_volume_frequency: monthly
47 dmarc_mitigate_action: no_mitigation
48 dmarc_mitigate_unconditionally: False
49 dmarc_moderation_notice:
50 dmarc_wrapped_message_text:
52 first_strip_reply_to: False
54 fqdn_listname: ant@example.com
58 include_rfc2369_headers: True
60 join_address: ant-join@example.com
62 leave_address: ant-leave@example.com
64 mail_host: example.com
66 max_num_recipients: 10
67 member_roster_visibility: moderators
68 moderator_password: None
70 no_reply_address: noreply@example.com
71 owner_address: ant-owner@example.com
73 posting_address: ant@example.com
74 posting_pipeline: default-posting-pipeline
75 reply_goes_to_list: no_munging
77 request_address: ant-request@example.com
78 require_explicit_destination: True
79 respond_to_post_requests: True
80 send_welcome_message: True
82 subscription_policy: confirm
87 Changing the full configuration
88 ===============================
90 Not all of the readable attributes can be set through the web interface. The
91 ones that can, can either be set via ``PUT`` or ``PATCH``. ``PUT`` changes
92 all the writable attributes in one request.
94 When using ``PUT``, all writable attributes must be included.
96 >>> dump_json('http://localhost:9001/3.0/lists/'
97 ... 'ant@example.com/config',
99 ... acceptable_aliases=['one@example.com', 'two@example.com'],
100 ... admin_immed_notify=False,
101 ... admin_notify_mchanges=True,
102 ... administrivia=False,
103 ... advertised=False,
104 ... anonymous_list=True,
105 ... archive_policy='never',
106 ... autorespond_owner='respond_and_discard',
107 ... autorespond_postings='respond_and_continue',
108 ... autorespond_requests='respond_and_discard',
109 ... autoresponse_grace_period='45d',
110 ... autoresponse_owner_text='the owner',
111 ... autoresponse_postings_text='the mailing list',
112 ... autoresponse_request_text='the robot',
113 ... display_name='Fnords',
114 ... description='This is my mailing list',
115 ... include_rfc2369_headers=False,
116 ... info='This is the mailing list information',
117 ... allow_list_posts=False,
118 ... digest_send_periodic=False,
119 ... digest_size_threshold=10.5,
120 ... digest_volume_frequency='yearly',
121 ... digests_enabled=False,
122 ... dmarc_mitigate_action='munge_from',
123 ... dmarc_mitigate_unconditionally=False,
124 ... dmarc_moderation_notice='Some moderation notice',
125 ... dmarc_wrapped_message_text='some message text',
126 ... posting_pipeline='virgin',
127 ... filter_content=True,
128 ... first_strip_reply_to=True,
129 ... convert_html_to_plaintext=True,
130 ... collapse_alternatives=False,
131 ... reply_goes_to_list='point_to_list',
132 ... reply_to_address='bee@example.com',
133 ... require_explicit_destination=False,
134 ... member_roster_visibility='members',
135 ... send_welcome_message=False,
136 ... subject_prefix='[ant]',
137 ... subscription_policy='moderate',
138 ... default_member_action='hold',
139 ... default_nonmember_action='discard',
140 ... moderator_password='password',
141 ... max_message_size='500',
142 ... respond_to_post_requests=True,
143 ... max_num_recipients='20',
148 server: WSGIServer/...
151 These values are changed permanently.
153 >>> dump_json('http://localhost:9001/3.0/lists/'
154 ... 'ant@example.com/config')
155 acceptable_aliases: ['one@example.com', 'two@example.com']
156 admin_immed_notify: False
157 admin_notify_mchanges: True
160 allow_list_posts: False
162 archive_policy: never
163 autorespond_owner: respond_and_discard
164 autorespond_postings: respond_and_continue
165 autorespond_requests: respond_and_discard
166 autoresponse_grace_period: 45d
167 autoresponse_owner_text: the owner
168 autoresponse_postings_text: the mailing list
169 autoresponse_request_text: the robot
171 collapse_alternatives: False
172 convert_html_to_plaintext: True
174 default_member_action: hold
175 default_nonmember_action: discard
176 description: This is my mailing list
178 digest_send_periodic: False
179 digest_size_threshold: 10.5
180 digest_volume_frequency: yearly
181 digests_enabled: False
183 dmarc_mitigate_action: munge_from
184 dmarc_mitigate_unconditionally: False
185 dmarc_moderation_notice: Some moderation notice
186 dmarc_wrapped_message_text: some message text
188 first_strip_reply_to: True
190 fqdn_listname: ant@example.com
192 include_rfc2369_headers: False
194 member_roster_visibility: members
195 moderator_password: {plaintext}password
197 posting_pipeline: virgin
198 reply_goes_to_list: point_to_list
199 reply_to_address: bee@example.com
201 require_explicit_destination: False
202 respond_to_post_requests: True
203 send_welcome_message: False
204 subject_prefix: [ant]
205 subscription_policy: moderate
209 Changing a partial configuration
210 ================================
212 Using ``PATCH``, you can change just one attribute.
214 >>> dump_json('http://localhost:9001/3.0/lists/'
215 ... 'ant@example.com/config',
216 ... dict(display_name='My List'),
223 These values are changed permanently.
225 >>> print(mlist.display_name)
232 Mailing list configuration variables are actually available as sub-resources
233 on the mailing list. Their values can be retrieved and set through the
240 You can view the current value of the sub-resource.
242 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
243 ... '/config/display_name')
244 display_name: My List
247 The resource can be changed by PUTting to it. Note that the value still
248 requires a dictionary, and that dictionary must have a single key matching the
249 name of the resource.
252 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
253 ... '/config/display_name',
254 ... dict(display_name='Your List'),
261 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
262 ... '/config/display_name')
263 display_name: Your List
266 PATCH works the same way, with the same effect, so you can choose to use
269 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
270 ... '/config/display_name',
271 ... dict(display_name='Their List'),
278 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
279 ... '/config/display_name')
280 display_name: Their List
287 These are recipient aliases that can be used in the ``To:`` and ``CC:``
288 headers instead of the posting address. They are often used in forwarded
289 emails. By default, a mailing list has no acceptable aliases.
291 >>> from mailman.interfaces.mailinglist import IAcceptableAliasSet
292 >>> IAcceptableAliasSet(mlist).clear()
293 >>> transaction.commit()
294 >>> dump_json('http://localhost:9001/3.0/lists/'
295 ... 'ant@example.com/config/acceptable_aliases')
296 acceptable_aliases: []
299 We can add a few by ``PUT``-ing them on the sub-resource. The keys in the
300 dictionary are ignored.
302 >>> dump_json('http://localhost:9001/3.0/lists/'
303 ... 'ant@example.com/config/acceptable_aliases',
304 ... dict(acceptable_aliases=['foo@example.com',
305 ... 'bar@example.net']),
309 server: WSGIServer/...
312 You can get all the mailing list's acceptable aliases through the REST API.
314 >>> response = call_http(
315 ... 'http://localhost:9001/3.0/lists/'
316 ... 'ant@example.com/config/acceptable_aliases')
317 >>> for alias in response['acceptable_aliases']:
322 The mailing list has its aliases set.
324 >>> from mailman.interfaces.mailinglist import IAcceptableAliasSet
325 >>> aliases = IAcceptableAliasSet(mlist)
326 >>> for alias in sorted(aliases.aliases):
331 The aliases can be removed by using ``DELETE``.
333 >>> response = call_http(
334 ... 'http://localhost:9001/3.0/lists/'
335 ... 'ant@example.com/config/acceptable_aliases',
339 server: WSGIServer/...
342 Now the mailing list has no aliases.
344 >>> aliases = IAcceptableAliasSet(mlist)
345 >>> print(len(list(aliases.aliases)))
352 Mailman can do pattern based header matching during its normal rule
353 processing. Each mailing list can also be configured with a set of header
354 matching regular expression rules. These can be used to impose list-specific
355 header filtering with the same semantics as the global ``[antispam]`` section,
356 or to have a different action.
358 The list of header matches for a mailing list are returned on the
359 ``header-matches`` child of this list.
361 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
362 ... '/header-matches')
367 New header matches can be created by POSTing to the resource.
370 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
371 ... '/header-matches', {
372 ... 'header': 'X-Spam-Flag',
373 ... 'pattern': '^Yes',
377 location: .../3.0/lists/ant.example.com/header-matches/0
381 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
382 ... '/header-matches/0')
387 self_link: http://localhost:9001/3.0/lists/ant.example.com/header-matches/0
389 To follow the global antispam action, the header match rule must not specify
390 an ``action`` key, which names the chain to jump to if the rule matches. If
391 the default antispam action is changed in the configuration file and Mailman
392 is restarted, those rules will get the new jump action. If a specific action
393 is desired, the ``action`` key must name a valid chain to jump to.
396 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
397 ... '/header-matches', {
398 ... 'header': 'X-Spam-Status',
399 ... 'pattern': '^Yes',
400 ... 'action': 'discard',
404 location: .../3.0/lists/ant.example.com/header-matches/1
408 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
409 ... '/header-matches/1')
411 header: x-spam-status
415 self_link: http://localhost:9001/3.0/lists/ant.example.com/header-matches/1
417 The resource can be changed by PATCHing it. The ``position`` key can be used
418 to change the priority of the header match in the list. If it is not supplied,
419 the priority is not changed.
422 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
423 ... '/header-matches/1',
424 ... dict(pattern='^No', action='accept'),
430 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
431 ... '/header-matches/1')
433 header: x-spam-status
437 self_link: http://localhost:9001/3.0/lists/ant.example.com/header-matches/1
439 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
440 ... '/header-matches/1',
441 ... dict(position=0),
447 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
448 ... '/header-matches')
451 header: x-spam-status
455 self_link: .../lists/ant.example.com/header-matches/0
461 self_link: .../lists/ant.example.com/header-matches/1
466 The PUT method can replace an entire header match. The ``position`` key is
467 optional; if it is omitted, the order will not be changed.
470 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
471 ... '/header-matches/1',
472 ... dict(header='X-Spam-Status',
481 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
482 ... '/header-matches/1')
484 header: x-spam-status
488 self_link: http://localhost:9001/3.0/lists/ant.example.com/header-matches/1
490 A header match can be removed using the DELETE method.
493 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
494 ... '/header-matches/1',
500 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
501 ... '/header-matches')
504 header: x-spam-status
508 self_link: .../lists/ant.example.com/header-matches/0
513 The mailing list's header matches can be cleared by issuing a DELETE request on
517 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
518 ... '/header-matches',
524 >>> dump_json('http://localhost:9001/3.0/lists/ant.example.com'
525 ... '/header-matches')