[Mailman-Developers] Building a boucing detector

Barry A. Warsaw bwarsaw@beopen.com
Thu, 21 Sep 2000 15:46:29 -0400 (EDT)


>>>>> "PEN" == Paulo Eduardo Neves <neves@samba-choro.com.br> writes:

    PEN> Hi, In my site, I send a lot of emails to users. I'd like to
    PEN> build a software to detect bouncing email, and automatically
    PEN> take some actions, like removing the user from the
    PEN> database. I'm considering using mailman code to do it. Why
    PEN> build, if you can steal?:-)

Absolutely!  And feel free to contribute back any new bounce
dectectors you develop; it's a never ending battle with MTA authors
who feel the need to be clever and unique. ;/

    PEN> After a quick look in the code, here is my approach. I would
    PEN> like very much to hear people more knowledgeable about
    PEN> Mailman code criticize it.

    PEN> There's two spots that handle bouncing email. The files in
    PEN> directory Bouncers/ identify if a message is a
    PEN> bounce. Calling BounceAPI.py with a message instance and a
    PEN> list instance calls the RegisterBounce method in list if the
    PEN> email is a bounce.

    PEN> Bouncer.py is the mix-in class that handle the bounces and
    PEN> calls some methods of its sibiling and subclasses
    PEN> (e.g. IsMember and Save).

    PEN> I'd put a pipe in the alias file to pass it to a simple
    PEN> program that builds the message object, the list object and
    PEN> pass them to BounceAPI.

    PEN> Subclass Bouncer class in Bouncer.py to redefine list objects
    PEN> methods that would be defined in other classes. Some would be
    PEN> dummy methods, others do the real action.

    PEN> Any opinions? Is there any trap?

I think this is more work than you need to do actually.  If you look
at ScanMessages() in BouncerAPI.py, it really does two things:

1) iterate through the list of bounce detectors until one of them
  returns a match

2) calls into the MailList object to "register" the bouncing
  addresses

#2 probably has little use for you outside the context of Mailman, so
if all you're interested in is the bounce detection framework, I'd say
you should just re-implement ScanMessages() to do something more
useful for your application.

Forget the MailList instance; all you really need is a Message object.
I think, but am not positive, that Python's standard rfc822.Message
class should suffice here, although you'll need to be sure that file
object you pass to the constructor is rewindable.  Some sys.stdins are
not, and if that's the case for you, I suggest reading all of
sys.stdin into a StringIO instance and passing /that/ to the
rfc822.Message constructor.

You'll probably need to change the __import__() call in ScanMessages()
because your copy probably won't live in the Mailman.Bouncers package.

The API to the individual bounce detectors is this:

- the module must have a module-global function called process()
- process() must take a single argument, the Message object
- process() returns None (or any false value) to indicate it could not
  find a matching address in the message
- process() returns a list of matching addresses if it does find a
  match

The algorithm in ScanMessages() simply iterates through every bounce
detector until one of them returns a non-false value.  Given that list
of addresses, you can then do whatever is appropriate for your
application.

Hope that helps,
-Barry