Messages which are held for approval can be accepted, rejected, discarded, or deferred by the list moderators.
Held messages can be moderated through the REST API. A mailing list starts with no held messages.
>>> ant = create_list('ant@example.com')
>>> transaction.commit()
>>> dump_json('http://localhost:9001/3.0/lists/ant@example.com/held')
http_etag: "..."
start: 0
total_size: 0
When a message gets held for moderator approval, it shows up in this list.
>>> msg = message_from_string("""\
... From: anne@example.com
... To: ant@example.com
... Subject: Something
... Message-ID: <alpha>
...
... Something else.
... """)
>>> from mailman.app.moderator import hold_message
>>> request_id = hold_message(ant, msg, {'extra': 7}, 'Because')
>>> transaction.commit()
>>> dump_json('http://localhost:9001/3.0/lists/ant@example.com/held')
entry 0:
extra: 7
hold_date: 2005-08-01T07:49:23
http_etag: "..."
message_id: <alpha>
msg: From: anne@example.com
To: ant@example.com
Subject: Something
Message-ID: <alpha>
X-Message-ID-Hash: GCSMSG43GYWWVUMO6F7FBUSSPNXQCJ6M
Something else.
reason: Because
request_id: 1
sender: anne@example.com
subject: Something
http_etag: "..."
start: 0
total_size: 1
You can get an individual held message by providing the request id for that message. This will include the text of the message.
>>> def url(request_id):
... return ('http://localhost:9001/3.0/lists/'
... 'ant@example.com/held/{0}'.format(request_id))
>>> dump_json(url(request_id))
extra: 7
hold_date: 2005-08-01T07:49:23
http_etag: "..."
message_id: <alpha>
msg: From: anne@example.com
To: ant@example.com
Subject: Something
Message-ID: <alpha>
X-Message-ID-Hash: GCSMSG43GYWWVUMO6F7FBUSSPNXQCJ6M
Something else.
reason: Because
request_id: 1
sender: anne@example.com
subject: Something
Individual messages can be moderated through the API by POSTing back to the held message’s resource. The POST data requires an action of one of the following:
- discard - throw the message away.
- reject - bounces the message back to the original author.
- defer - defer any action on the message (continue to hold it)
- accept - accept the message for posting.
Let’s see what happens when the above message is deferred.
>>> dump_json(url(request_id), {
... 'action': 'defer',
... })
content-length: 0
date: ...
server: ...
status: 204
The message is still in the moderation queue.
>>> dump_json(url(request_id))
extra: 7
hold_date: 2005-08-01T07:49:23
http_etag: "..."
message_id: <alpha>
msg: From: anne@example.com
To: ant@example.com
Subject: Something
Message-ID: <alpha>
X-Message-ID-Hash: GCSMSG43GYWWVUMO6F7FBUSSPNXQCJ6M
Something else.
reason: Because
request_id: 1
sender: anne@example.com
subject: Something
The held message can be discarded.
>>> dump_json(url(request_id), {
... 'action': 'discard',
... })
content-length: 0
date: ...
server: ...
status: 204
Messages can also be accepted via the REST API. Let’s hold a new message for moderation.
>>> del msg['message-id']
>>> msg['Message-ID'] = '<bravo>'
>>> request_id = hold_message(ant, msg)
>>> transaction.commit()
>>> results = call_http(url(request_id))
>>> print(results['message_id'])
<bravo>
>>> dump_json(url(request_id), {
... 'action': 'accept',
... })
content-length: 0
date: ...
server: ...
status: 204
>>> from mailman.testing.helpers import get_queue_messages
>>> messages = get_queue_messages('pipeline')
>>> len(messages)
1
>>> print(messages[0].msg['message-id'])
<bravo>
Messages can be rejected via the REST API too. These bounce the message back to the original author.
>>> del msg['message-id']
>>> msg['Message-ID'] = '<charlie>'
>>> request_id = hold_message(ant, msg)
>>> transaction.commit()
>>> results = call_http(url(request_id))
>>> print(results['message_id'])
<charlie>
>>> dump_json(url(request_id), {
... 'action': 'reject',
... })
content-length: 0
date: ...
server: ...
status: 204
>>> from mailman.testing.helpers import get_queue_messages
>>> messages = get_queue_messages('virgin')
>>> len(messages)
1
>>> print(messages[0].msg['subject'])
Request to mailing list "Ant" rejected