An email plugin for the Seneca toolkit
This module is a plugin for the Seneca framework. It provides email capability for actions. It's also a good example of how you can provide different implementations for a plugin's functionality.
With this module you can:
- Compose email from templates
- Send email using various service providers
Each email template is identified by a code. The code is the unique identifier for each type of email template that you send. If you are sending a completely custom, dynamically generated email, then you can omit the code.
The default implementation uses the email-templates module to compose email and the nodemailer module to send it. You can customize this by overriding the appropriate actions.
For a customization example, see the seneca-postmark-mail. It shows how you can use the Seneca action pattern-matching concept to easily integrate and customize plugins, without needing to learn complex APIs.
This module can be used in a standalone fashion, but is most often used with the seneca-user plugin to handle transactional emails for user accounts, such as welcome mails and password reminders.
If you're using this module, feel free to contact me on twitter if you have any questions! :) @rjrodger
Current Version: 0.1.4
Tested on: node 0.10.29, seneca 0.5.18
This example uses a standard Gmail account to send the email. Use your own details for testing, but don't persist them anywhere!
var seneca = require('seneca')()
seneca.use('mail',{
folder: './email-templates',
mail: {
from: '[email protected]'
},
config:{
service: "Gmail",
auth: {
user: "[email protected]",
pass: "PASSWORD"
}
}
})
seneca.ready(function(err){
if( err ) return console.log(err);
seneca.act({
role:'mail',
cmd:'send',
code:'welcome',
to:'[email protected]',
subject:'Welcome!',
content:{
name:'Customer One'
}
})
})
The role:mail, cmd:send action sends out an email. The code identifies the email template that you want to use. You can also just provide the email body directly by providing html or text arguments containing an HTML or plain text body string.
The tradition email fields are what you would expect:
- to: to email address
- from: from email address - you can set this once (or any other fields) in the plugin configuration to avoid repetition, as per the example
- subject: email subject line
If you are using a template, the concrete values to insert into the template are taken from the properties of the content argument.
To use templates, create a folder in your project called email-templates, containing the sub-folder and file welcome/html.ejs:
<h1>Hello <%=name%>!</h1>
Welcome to our service!
This is the email template that generates the final text of the email that will be sent. You can use HTML to make your emails look nicer. You also use plain text by creating a welcome/text.ejs version of the email template file. See the email-templates module for more information.
To run this example, install the seneca-mail module as per the installation instructions below, copy the test/readme.js file into your own project, update the configuration with real values, and run from the command line with
node readme.js
Take a look at the Seneca user accounts example to see how this module provides transactional email for user account functionality.
npm install seneca
npm install seneca-mail
You'll need the seneca module to use this module - it's just a plugin.
To load the plugin:
seneca.use('mail', { ... options ... })
To isolate logging output from the plugin, use:
node your-app.js --seneca.log=plugin:mail
For more logging options, see the Seneca logging tutorial. You may, for example, wish to log email activity to a separate file for audit purposes.
- folder: contains email template sub-folders. In case this is missing the 'generate' seneca action should be customized.
- content: insertion values for all email templates (saves repetition), default: {}.
- non-string sub-objects allow for template-code-specific content (using email code as property name), for example: {content:{welcome:{subject:'Howdy!'}}}.
- _mail: to, from, etc, fields for all emails, good place for a common from address, default: {}.
- transport: the nodemailer transport, default: 'smtp'. For more transport plugins see available nodemailer transport
- config: the nodemailer configuration, default: {}.
If you are using a customer email template generator then the folder option is not be needed.
Example for loading email templates from DB can be found in seneca-mail-dbtemplate
If you are using a custom email transport plugin, use: * transport - transport name * transportPluginName - is the name of the transport plugin that will be loaded
Please see transport api plugin documentation for details
In both cases - custom transport or standard transport plugin - the specified transport should be loaded from project package.json, is not seneca-mail's concern.
All actions provide results via the standard callback format: function(error,data){ ... }
.
Send an email. Arguments override default settings in the mail plugin option.
- code: template code, name of the sub-folder of the email templates folder
- content: insertion values for the email template
- html and/or text: literal body of the email, only used if there's no code argument ( content is also ignored in this case)
- to: to email address, overrides options.mail.to
- from: from email address, overrides options.mail.from
- cc: cc email address, overrides options.mail.cc
- bcc: bcc email address, overrides options.mail.bcc
- replyTo: reply to email address, overrides options.mail.replyTo
- subject: email subject line, overrides options.mail.subject
Object with properties:
- ok: true if send succeeded, false if not
- details: underlying email module response data, if any
- role:mail, cmd:generate: to generate the literal email body
- role:mail, hook:send: to send the email, providing the literal email body as html and text arguments
Generate literal email HTML and plain text from a template.
- code: template code, name of the sub-folder of the email templates folder
- content: specific insertion values for this email, overrides and extends values in options.content
Object with properties:
- ok: true if generate succeeded, false if not
- html: literal HTML email body, generated from template by inserting content values
- text: literal plain text email body, generated from template by inserting content values
None.
- role:mail, hook:content: to customize content generation
To see what this plugin is doing, try:
node your-app.js --seneca.log=plugin:mail
This will print action logs and plugin logs for the user plugin. To skip the action logs, use:
node your-app.js --seneca.log=type:plugin,plugin:mail
You can also set up the logging programmatically:
var seneca = require('seneca')({
log:{
map:[
{plugin:'mail',handler:'print'}
]
}
})
For more on logging, see the seneca logging example.
As with all seneca plugins, you can customize behavior simply by overwriting actions. However, this plugin also provides customization hooks, which are sub actions called by the main cmd actions.
To see these in action, review the code of the seneca-postmark-mail module, which shows you how to use these hooks to send email using a different module.
Actually send email
- html: literal HTML email body
- text: literal plain text email body
- ALL: used by underlying mail module
As per action role:mail, cmd:send.
Modify or provide email content for template insertion
- code: template code
- content: merged content from action arguments and options
Object with content values.
Initialize plugin. Calls role:mail, hook:init, sub:templates and role:mail, hook:init, sub:transport in sequence.
- options: plugin options
Nothing.
Initialize email templates.
- options: plugin options
Implementation dependent object.
Initialize email transport
- options: plugin options
Implementation dependent object.
npm test
Copy sendconf.example.js to _sendconf.mine.js_and add real configuration values, and then send a mail with:
cd test
node send-mail.js --seneca.log.print
See the nodemailer module for configuration options.