Diligence is still under development and incomplete, and some this documentation is wrong. For a more comprehensive but experimental version download the Savory Framework, which was the preview release of Diligence.

Notification Service
Sending out email from your application can quickly become difficult to manage when you have hundreds of thousands of emails to send out. But Diligence's Notification Service is here to help! Some key features:
- The implementation is optimized for high concurrency, making good use of MongoDB's atomic update features. This means that it's easy to scale: you can have many nodes all sending queued notices at the same time. They won't interfere with each other and there's no fear of having the same email sent more than once.
- It supports subscription channels: you can send a notice to the channel, and it would then be sent to all subscribers. This greatly minimizes the load on MongoDB. Moreover, you can use a notice template such that each subscriber gets a personalized email. Of course, you can also send direct notices to a single addressee.
- Automatic handling of daily and weekly digests for subscribers who prefer not to get individual emails. This works by merging notices into a digest document at scheduled times.
- You don't have to use email: the service implementation is pluggable, allowing you support other kinds of mailboxes if they make sense. For example, you might want to have an internal messaging feature for your application. The implementation is configured per subscriber, so you can support different kinds of mailboxes quite transparently.
- Supports both plain text and mixed-media HTML email.
Note that Diligence connects to but is not itself an SMTP server. SMTP servers are complex beasts in their own right: they must handle errors and retries, queuing of outgoing messages, as well as incoming ones if they are configured for relaying or for mailboxes. It's a good idea to keep that separate from your main application. We like Postfix, a mature SMTP server that offers excellent scalability and security.
If you want your application to receive email, which is quite a different task than relaying it onward, then we can recommend the SubEtha SMTP library. If there's interest, we may incorporate it into Diligence directly in the future.
Usage
Make sure to check out the API documentation for Diligence.Notification.
Here's an example of two ways for queuing a notice, the first by a direct address, and the second to all subscribers of a channel:
document.executeOnce('/diligence/service/notification/') Diligence.Notification.queueForAddress('Email', 'email@myorg.org', {subject: 'The Subject', text: 'The content.}) Diligence.Notification.queueForChannel('main', {subject: 'The Subject', text: 'The content.'})
The first option doesn't require any subscription: it uses "Email" as the implementation (see "configuration," below), with the second argument being an identifier for that implementation (in this case, simply an email address). The second option queues the notice on the channel named "main". To add a subscription, you can do the following:
Diligence.Notification.subscribe('main', {service: 'Email', address: 'email@myorg.org', mode: 'daily'})
The "mode" key can be "immediate", "daily" or "weekly", with the latter two modes for digests. You don't need to create the channel itself: adding at least one subscription will automatically do that.
In the above examples we've sent plain text emails. To add HTML, add an "html" key. Note that if you use "html" you need to also add "text" to specify the plain text version. This is very good practice: not all email clients support HTML, and if they don't your HTML will be unreadable without a plain text fallback.
It might be useful to make use of the Sincerity.Mail.MessageTemplate class, which lets you store messages in text packs. For more information on text packs, see the Internationalization Service.
Configuration
In your application's "settings.js" you want to make sure to enable lazy configuration:
document.executeOnce('/prudence/lazy/')
And then add something like this to your app.globals:
app.globals = { ... diligence: { service: { notification: { services: { '.': Prudence.Lazy.build({ Email: { dependencies: '/diligence/service/notification/service/email/', name: 'Diligence.Notification.EmailService', config: { from: 'myaddress@mymail.org', site: 'Diligence Example' } } }) } } } } }
Note the use of Prudence.Lazy.build: this allows the Notification Service to lazily create the email implementation on demand during runtime. The key, "Email", will be used in subscriptions, as in the examples above. Note that it is case-sensitive. Within the lazy configuration, the "name" key is the class to instantiate, the "config" is sent to the class constructor, and values in the "dependencies" key are used for "document.executeOnce". Also note the use of the "." key to avoid flattening of the resulting lazy build (see Sincerity.Objects.flatten).
If you want to write your own service implementations, see the source code for the Diligence.Notification.EmailService.
To set up the background tasks for sending out queued notices, add something like the following to your application's "crontab":
<% document.executeOnce('/diligence/service/notification/'); Diligence.Notification.sendQueuedNotices(); %> 4 <% document.executeOnce('/diligence/service/notification/'); Diligence.Notification.sendQueuedDigests('daily'); %> 5 0 <% document.executeOnce('/diligence/service/notification/'); Diligence.Notification.sendQueuedDigests('weekly'); %>
The above will check for and send regular notices every minute, send daily digests at 4am, and send weekly digests every Sunday at 5am. As stated above, you can have this same "crontab" running on many nodes. Because the implementation relies on MongoDB's atomic updates, you can be sure that notices will not be sent more than once.
The Diligence Manual is provided for you under the terms of the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. The complete manual is available for download as a PDF.