Post Moderation

Messages which are held for approval can be accepted, rejected, discarded, or deferred by the list moderators.

Viewing the list of held messages

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

Disposing of held messages

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