11.3. Notification Tutorial

This section deals with several types of notification services you can create in WAF — simple notification, notification with attachment, notification digest, and email alerts.

11.3.1. Creating a Simple Notification

A basic notification requires a sender, a receiver, a subject, and a body. All notifications require a Message object to send, but in the case of a simple text message, an API allows you to provide the relevant information and constructs a temporary Message object for you. By default, these notifications will be deleted after they are sent.

The following code fragment depicts the simplest case of sending a notification to a user:

User to   = getRecipient();
User from = getSender();

Notification n = new Notification(to, from, "Subject", "Body");
n.save();

This notification will be sent to the user on the next run of SimpleQueueManager. to and from must be persistent Parties in the database.

You can also create a notification and send it to a Group. When the notification is processed, it will be sent to each individual User in the Group.

Group group = getTargetGroup();
User  from  = getSender();

Notification n = new Notification(group, from, "Subject", "Body");
n.setExpandGroup(Boolean.TRUE);
n.save();

Note that this option is turned on by default, so the call to setExpandGroup is not strictly necessary.

11.3.2. Creating a Simple Notification with an Attachment

For more complicated notifications, it is better to construct a separate Message object and then wrap a notification around it for email delivery to a user. The following example shows how to construct a multipart message with attachments, using both an HTML document fetched from a URL and a simple text document constructed on the fly.

// Create a message for the body of the notification
User from = getSender();
Message msg = new Message(from, "subject", "See attachments");

// Attach some content fetched from a URL
URL url = new URL("http://www.yahoo.com/");
MessagePart part = new MessagePart("Yahoo", "Yahoo index page");
part.setDataHandler(new DataHandler(url));
msg.attach(part);

// Attach a simple text document
msg.attach("Some additional text", "file.txt", "description);

// Save the message
msg.save();

// Send the message to the recipient
User to = getRecipient();
Notification n = new Notification(to, msg);
n.save();

11.3.3. Creating an Hourly Digest

Applications that send frequent notifications to users are often designed to group those messages into a digest. A common example is a workflow application that sends users a summary of new and completed tasks every hour.

The notification service supports using an explicit digest. After creating a digest, you can use it to send future notifications by passing the digest to the notification constructor. All messages sent to a user through the same digest will be combined into a single outbound message when the digest is next processed.

// Party responsible for sending the digest
User from = getDigestSender();

String subject = "my-digest";
String header  = "Recent messages";
String footer  = "To unsubscribe, visit
 http://mysite.net/unsubscribe";

Digest digest = new Digest(from, subject,
 header, footer);
digest.setFrequency(Digest.HOURLY);
digest.save();

// Create a couple of notifications and send
// them using the hourly digest

Notification n0 = new Notification(digest, user,
 from, "Subject0", "Body0");
n0.save();

Notification n1 = new Notification(digest, user,
 from, "Subject1", "Body1");
n1.save();

These two separate notifications will be composed into a single email message and sent to the user during the next run of the digest queue manager.

Applications typically create their digests when they are installed, and then use them as part of processing alerts for users.

11.3.4. Email Alerts

The examples above assume that applications will simply need to notify users of some event via email. However, one of the powerful features of the notification service is that it is built on top of the WAF messaging service. One of the goals of this design is to make it efficient for messaging applications to send Message objects directly to users via email, without the need to store any additional information in the database.

A simple example of this is a bulletin-board (bboard) application that stores each post as a Message, and then sends each post via email to Users who have subscribed to bboard alerts. In addition to the basic text of the message, such an application might also need to wrap additional text around it to include introductory remarks and possibly action links that users can manipulate.

For example, a simple message such as this is my post would typically be sent out with additional information:

Message-ID: <574077721.1185532184.CCMMail@localhost>
Date: Fri, 5 Oct 2001 00:43:21 -0700 (PDT)
From: [email protected]
To: [email protected]
Subject: a simple post
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Posted by: Bboard User
Category: Announcement

this is my post

----------
This is a posting from the company news bboard.
To reply you can go to:
http://mysite.com/bboard/news/
To unsubscribe from this or other bboard posts go to:
http://mysite.com/bboard/subscriptions/

The notification API includes methods to define the additional text that is wrapped around the contained Message object so that these emails can be generated without creating and storing a duplicate Message object in the database. In the example above, the header and signature of the notification would be specified as follows:

Notification notice = new Notification(to,msg);
notice.setHeader
    ("Posted by: " + poster.getName() + "\n" +
     "Category: " + forum.getCategory());
notice.setSignature
    ("---------\n" +
     "This is a posting from the company news bboard.\n" +
     "To reply you can go to:\n" +
     "http://mysite.com/bboard/news/\n" +
     "To unsubscribe from this or other bboard posts go to:\n" +
     "http://mysite.com/bboard/subscriptions/");
notice.save();

Applications that use extensive email alerts will probably want to extend Notification so that the header and signature are set in a special constructor for each notification to be sent out.

For efficiency, applications should avoid sending email alerts to individual users. It is much more efficient to store the list of recipients in a Group and send a single notification to the group, letting the notification service expand the group into the list of individual recipients. If you follow this approach, an email alert going out to 1000 users will occupy the same amount of space in the database as a single email.