Skip to content

Instantly share code, notes, and snippets.

@paulegan
Created February 1, 2012 05:17
Show Gist options
  • Save paulegan/1715265 to your computer and use it in GitHub Desktop.
Save paulegan/1715265 to your computer and use it in GitHub Desktop.
Simple django admin command for processing incoming bounce reports
"""Simple django admin command for processing incoming bounce reports.
This script depends on flufl.bounce_ for processing the bounce reports. The
flufl packages are a spinoff from the mailman project so are pretty robust and
have good coverage of real-world bounce reports.
You will usually need a small wrapper script to use this with a mail server.
For example to use with sendmail put this in `/etc/smrsh/process_site_bounces`::
#!/bin/sh
exec python /path/to/django/project/manage.py process_bounce_email
And then in `/etc/aliases`::
bounces: |/etc/smrsh/process_site_bounces
You should ensure that your outgoing email uses this `bounces` address as the
`Return-Path`. For example if using django-ses_, this would be the address
set with `AWS_SES_RETURN_PATH`.
.. _flufl.bounce: https://launchpad.net/flufl.bounce
.. _django-ses: https://github.com/hmarr/django-ses
"""
import sys
import logging
from email import message_from_file
from django.core.management.base import BaseCommand
from flufl.bounce import all_failures
def disable_email(addresses):
"""Disable email for all users with matching addresses."""
from django.contrib.auth.models import User
User.objects.filter(email__in=addresses).update(email='')
for address in addresses:
logging.warning('Disabled email for %s', address)
class Command(BaseCommand):
help = "Process incoming bounce reports and disable bouncing addresses."
def handle(self, *args, **options):
# Parse email content sent on stdin looking for bounce messages
# and disable only those addresses found with permanent failure.
msg = message_from_file(sys.stdin)
id = msg.get('Message-Id', 'unknown')
temporary, permanent = all_failures(msg)
if temporary:
logging.info('Temporary address failures for message %s: %s',
id, ','.join(temporary))
if permanent:
logging.info('Permanent address failures for message %s: %s',
id, ','.join(permanent))
disable_email(permanent)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment