mailer-q
v4.0.0
Published
A redis-backed mailer queue system
Readme
MailerQ
MailerQ is a small, Redis-backed mailer queue for Node.js, written in TypeScript. It wraps Nodemailer for sending and BullMQ for queueing, so you can send mail immediately or enqueue it for a worker to deliver — with pluggable template renderers and typed configuration.
Installation
npm install mailer-q --saveUsage
- It is easiest to keep MailerQ's configuration in its own module:
config/mailers.js
const MailerQ = require("mailer-q").default;
// or, with ESM / TypeScript: import MailerQ from "mailer-q";
const options = {
// Options here
};
module.exports = MailerQ(options);Available Options for MailerQ Configuration
- nodemailer: Configuration object for Nodemailer. An example is shown below but all options can be found in the Nodemailer documentation here: https://nodemailer.com/smtp/.
- defaultFrom (Optional): Set the default sender.
- defaultTo (Optional): Set the default recipient (not common).
- renderer (Optional): Method to render email templates.
- sendAttempts (Optional): Number of times MailerQ will attempt to send queued mail. Defaults to 3.
- redis (Optional): Redis connection options (BullMQ's
ConnectionOptions— an ioredis options object or instance). Requires Redis 5.0+ (6.2+ recommended). Required fordeliverLaterandprocessQueue. - queueName (Optional): Name of the BullMQ queue. Defaults to
"MailerQ SendEmail Process".
Example:
const config = {
nodemailer: {
host: "smtp.example.com",
port: 587,
auth: {
user: "your username",
pass: "your pass",
},
},
defaultFrom: "Test Tester <[email protected]>",
defaultTo: "[email protected]",
sendAttempts: 5,
redis: { host: "127.0.0.1", port: 6379 },
};Optional Renderers
- EJS Renderer: Use the EJS templating syntax.
- Handlebars Renderer: Use the Handlebars templating syntax.
- Pug Renderer: Use the Pug templating syntax.
A renderer is any function (templateFileName, locals) => htmlString.
Sending Mail
Build the message content with contents(), then chain either deliverNow() or
deliverLater():
deliverNow()sends immediately and resolves with Nodemailer'sinfo.deliverLater()enqueues the message and resolves with the BullMQJob. A worker then processes it (see Processing the queue).
const MailerQ = require("./config/mailers");
MailerQ.contents({
from: "Test Sender <[email protected]>",
to: "[email protected]",
subject: "Test message",
htmlBody: "<h1>HTML message here!</h1>",
})
.deliverNow()
.then((info) => {
console.log("Message sent!", info.messageId);
})
.catch((err) => {
console.log(err);
});Available Options for .contents()
- subject: Subject of the message (required).
- from (Optional): Sender address. Optional only if
defaultFromis configured. - to (Optional): Recipient address. Optional only if
defaultTois configured. - templateFileName (Optional): Name of the template file (only with a renderer plugin).
- htmlBody (Optional): HTML to send. Used when no
templateFileNameis provided. - locals (Optional): Variables passed to the renderer (only with a renderer plugin).
- attachments (Optional): Array of attachment objects per Nodemailer: https://nodemailer.com/message/attachments/.
Processing the queue
deliverLater() only enqueues. Run processQueue() once in a worker process to
consume the queue and actually send the mail. It returns the underlying BullMQ
Worker so you can listen for events:
const MailerQ = require("./config/mailers");
const worker = MailerQ.processQueue();
worker.on("completed", (job) => console.log("Sent:", job.id));
worker.on("failed", (job, err) => console.error("Failed:", job.id, err));Shutting down
Call close() to gracefully close the queue and transporter connections (e.g. on process
shutdown):
await MailerQ.close();Development
npm run build # compile TypeScript to dist/
npm test # run the Vitest suite
npm run lint # eslintChangelog
See CHANGELOG.md for the notable changes in each release.
