[pmwiki-users] Email notification on a page change

Patrick R. Michaud pmichaud at pobox.com
Thu Mar 2 16:44:55 CST 2006

Replying to myself here as I think further...

On Thu, Mar 02, 2006 at 03:48:49PM -0600, Patrick R. Michaud wrote:
> So, what we *really* want is to generalize MailPosts (which already
> handles the "wait and batch changes before sending" aspect) so that 
> it can handle arbitrary watch lists.  
> And perhaps watch lists should be specified using pagelist parameters, 
> [...]
> But that might be too much work for the system to keep up with --
> I'll have to think about it a bit.

I'm not so sure it's so much work.  Originally I was thinking
of implementing this with (:pagelist:), which is expensive,
but if we just process the parameters directly then it's not bad
at all.

So, let's look at a model very similar to MailPosts except it's
configured using a Site.NotifyList configuration page instead of 
config.php.  If the page ends up containing email addresses, then
it's read-only except to the administrator to keep the spam harvesters
at bay (or perhaps the email addresses are simply obfuscated, which is
very easy to manage in this case).

This gets a little complex (because I'm just figuring it out as we go),
so bear with me a bit here.

First, the Site.NotifyList page contains lines that indicate the type
of notifications people have indicated they want to receive.  The
lines look like argument lists to pagelist (even though they're not),
thus we end up with specifications such as

1.  Notify Alice of any changes to the site:

        mailto=alice at example.com

2.  Notify Bob of any changes to pages in the "Books" group:

        mailto=bob at example.com group=Books list=normal

3.  Notify Carol of changes to any of the pages listed on the
    "Profiles.Carol" trail:

        mailto=carol at example.com trail=Profiles.Carol

4.  Notify Dave of any changes to pages in the Skins category:

        mailto=dave at example.com link=Category.Skins

5.  Notify Carol of changes to any pages that link to her Profiles
    page, but don't send any messages more frequently than once per day:

        mailto=carol at example.com link=Profiles.Carol squelch=86400

The #3 option above, using trail=, becomes the mechanism whereby
most non-admins can easily maintain a "watch list" of pages on which to
receive notifications.  Essentially, we create an "?action=watchlist"
that is used to add entries to the Site.NotifyList.  (Admins can of
course edit the Site.NotifyList page directly.)

Let's take the example where Carol wants to use Profiles.Carol as
a watchlist trail.  Carol goes to the Profiles.Carol page, and adds
"?action=watchlist" to the url.  This presents a form that asks
her for her email address, and she submits "carol at example.com".
(The form can also provide options to set the minimum time between
notifications, the amount of time to wait after changes before
sending a notify message, etc.)

After Carol submits her form, PmWiki then generates a random key,
and places the information about her requests into a file corresponding
to the random key.  It also sends a message to carol at example.com
containing a link back to the site containing the random key --
i.e., something like


When Carol follows the link, PmWiki knows that she successfully
received the email message, so it can then add her request 
(trail=Profiles.Carol) to the list on the Site.NotifyLists page.

Note that Carol only needs to do this step once -- once she has 
her trail on the Site.NotifyList page, she can subscribe or unsubscribe
to pages simply by editing the Profiles.Carol page.  (Anyone with
edit access to Profiles.Carol can change her list, so she might want
to password-protect it.)

Of course, any page can be used as a source trail for this, so if 
Carol really just wants to watch the Books group, she could use


and go through the email verification process for that.

So, that's the user-interface, what goes on behind the scenes?  Well,
when someone saves a page, PmWiki goes through the Site.NotifyList
page to find out which notify lines encompass the changed page,
checking for a match of any list=, trail=, group=, name=, etc.
options that happen to be present.  When it finds a match, it
adds an entry in a .notifyposts (similar to .mailposts) file
containing the page name, the time of the change, and the email
address to be notified.  The email isn't immediately sent -- we
just keep track that one is queued to be sent.

Then, at random intervals (again, using a similar algorithm to what
MailPosts uses now), PmWiki batches up the entries from .notifyposts
and sends out email messages to whoever is supposed to receive them.
It also "holds off" sending anything to someone who has requested
delays between messages, or a minimum number of messages, or whatever
batching criteria we want to add.  

This seems like a pretty good approach, at least initially.  It
gives us very flexible configuration of mailposts and per-user
notify lists.  It also doesn't require a lot in the way of performing
searches, and spreads the load of processing mailposts over many
requests (and doesn't increase latency for visitors to the site).

Comments, thoughts, for anyone who managed to get this far...?


More information about the pmwiki-users mailing list