Mailman and Sympa are two very impressive free email list programs. I'm especially fond of Mailman, which has done a superb job powering Mayfirst/People Link email lists for years and years.

However, IMHO, the world is ready for the next generation email list. When I think of the needs of MFPL and the progressive movement, and I consider the number of activists with beginning php skills and the varied ecosystem of databases and communications programs written in PHP, it really points to a need for a fully modular, library-based, PHP based email system.

In other words, we don't need another monolithic program. I'd rather see a suite of libraries that do all the work and a simple, light-weight example implementation of that library. This way, the core work can happen on the libraries, and anyone in the world can tie the libraries together to meet their needs.

Here is my first stab at the libraries that are needed. Many of the libraries are already written!


Logger: logs all messages, errors or otherwise

Authenticater: the person with this username really is the owner o that user name.

Authorizer: the person with this username can do x, y, z.

Bouncer: takes a bounced message, extracts the list it was sent to, the address it was sent to, and whether or not it is a hard or soft bounce

BounceProcessor: takes an email address, a list name, and hard or soft bounce and records that information for the given address.

BounceManager: iterates through each list, reads the particular bounce processing rules for the given lists (unsubscribe after X bounces, etc.) and takes the required action.

UserManager: takes a single user and gets/sets subscriber settings, like digest, vacation, unsubscribe, change password, get lists they are subscribed to, etc.

SubscriptionManager: takes a given list and generates a list of emails with their preferences for the given list or adds/removes subscribers from a list.

ListManager: takes a single list and gets/sets configuration information, subject line tag, etc. The subscription object is a property of the list manager object, which enables the list object to know who is subscribed to it.

Generator: takes a ListManager object and generates every customized message. These are then handed to the injector.

Injector: takes a message and injects it into the mail system

Archiver: takes the name of a list and generates and pages and show search results for a given list archive.

Hasher: takes a list message and generates a secret hash (and stores it). Then takes each email address and list name and creates unique hash to be embedded in the message that a user can click on to unsubscribe from the list.


Here's a simple description of how a message would be sent using these libraries:

$message = "The email to send.";
$list_name = "thelist";

// create all the classes we'll want to use
$logger = new Logger();
$subscription_manager = new SubscriptionManager();
$list_manager = new ListManager();
$generator = new Generator();
$injector = new Injector();
$hasher = new Hasher();

// Each class should get the logger

// Initialize the subscription class with the
// list we're using
if(!$subscription_manager->set_list_name($list_name)) return false;

// Initialize the list class with the
// list we're using
if(!$list_manager->set_list_name($list_name)) return false;

// Now pass the subscription class on to the list class

// OK - now the list class knows all of it's configurations and
// because it has a subscription class, it knows how to get
// all the email addresses (and particular settings for those
// email addresses).

// Now pass the list class on to the generator class, which is going
// to generate all the individual messages

// Give the generator the hasher so it can append the unique hashes

// Now tell the generator object what message to send

// The generator's job is only to generate individual emails - not to inject
// them into the mail system. That's the job of the injector. So - pass the
// generator the injector class so it can use the class to actually inject
// the messages.


// Now tell the generator to send away
if(!$generator->send()) return false;

return true;

And bounces would be managed by an address that pipes them to a program like this:

// Dealing with bounces

// $message should be filled with standard in

$bouncer = new Bouncer();
$bounce_processor = new BounceProcessor();