@kandleconsultinggroup/email-blaster
v0.1.3
Published
Production-ready email blast system with queue management, templates, and unsubscribe handling.
Downloads
427
Readme
@kandleconsultinggroup/email-blaster
Production-ready email blast system with queue management, templates, and unsubscribe handling.
Features
- ✉️ Email blast campaigns with draft/send workflow
- 📝 Reusable email templates with token replacement
- 🚫 Automatic unsubscribe management
- 📊 Send logs and tracking
- ⚡ Optional Redis queue for rate limiting
- 🔌 Multi-provider support (SendGrid, AWS SES, SMTP)
- 🎨 Token replacement ({{firstName}}, {{companyName}}, etc.)
Installation
npm install @kandleconsultinggroup/email-blaster mongoose express
npm install ioredis --save-optional # Optional for queueQuick Start
const express = require("express");
const mongoose = require("mongoose");
const {
initMailBlaster,
routes,
} = require("@kandleconsultinggroup/email-blaster");
const app = express();
app.use(express.json());
// Connect MongoDB
mongoose.connect(process.env.MONGODB_URI);
// Initialize email blaster
initMailBlaster({
mongoUri: process.env.MONGODB_URI,
provider: "nodemailer",
rateLimit: { perMinute: 30 },
unsubscribe: {
enabled: true,
baseUrl: "http://localhost:3000",
},
nodemailer: {
host: "smtp.gmail.com",
port: 587,
user: "[email protected]",
pass: "your-app-password",
},
});
// Mount routes
app.use("/api/email/blasts", routes.blasts);
app.use("/api/email/templates", routes.templates);
app.use("/api/email/unsubscribe", routes.unsubscribe);
app.use("/api/email/logs", routes.logs);
app.listen(3000);API Endpoints
Email Blasts
Create Blast (Draft)
POST /api/email/blasts
Content-Type: application/json
{
"subject": "Welcome to our platform!",
"bodyHtml": "<h1>Hello {{firstName}}!</h1>",
"sender": {
"email": "[email protected]",
"name": "Your App"
},
"recipients": [
{
"email": "[email protected]",
"firstName": "John",
"companyName": "Acme Corp"
}
]
}Get All Blasts
GET /api/email/blastsGet Single Blast
GET /api/email/blasts/:idUpdate Blast
PUT /api/email/blasts/:id
Content-Type: application/json
{
"subject": "Updated subject"
}Send Blast
POST /api/email/blasts/:id/sendResponse:
{
"queued": 100,
"skipped": 5
}Delete Blast
DELETE /api/email/blasts/:idTemplates
Create Template
POST /api/email/templates
Content-Type: application/json
{
"name": "Welcome Email",
"subject": "Welcome {{firstName}}!",
"bodyHtml": "<h1>Hi {{firstName}}</h1>"
}Get All Templates
GET /api/email/templatesGet Single Template
GET /api/email/templates/:idUpdate Template
PUT /api/email/templates/:idDelete Template
DELETE /api/email/templates/:idSend Logs
Get All Logs
GET /api/email/logs
GET /api/email/logs?status=sent
GET /api/email/logs?blastId=123
GET /api/email/[email protected]Get Logs for Blast
GET /api/email/logs/blast/:blastIdUnsubscribes
Public Unsubscribe (from email link)
GET /api/email/[email protected]Admin: Get Unsubscribe List
GET /api/email/unsubscribe/listAdmin: Add to Unsubscribe List
POST /api/email/unsubscribe
Content-Type: application/json
{
"email": "[email protected]"
}Admin: Remove from Unsubscribe List
DELETE /api/email/unsubscribe/:emailConfiguration
Required Options
initMailBlaster({
provider: "sendgrid" | "ses" | "nodemailer",
rateLimit: {
perMinute: 30, // Required
perDay: 10000, // Optional
},
unsubscribe: {
enabled: true,
baseUrl: "https://yourapp.com",
},
});Provider Configurations
SendGrid
initMailBlaster({
provider: "sendgrid",
sendgrid: {
apiKey: process.env.SENDGRID_API_KEY,
},
});AWS SES
initMailBlaster({
provider: "ses",
ses: {
region: "us-east-1",
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
},
},
});SMTP (Nodemailer)
initMailBlaster({
provider: "nodemailer",
nodemailer: {
host: "smtp.gmail.com",
port: 587,
secure: false,
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
});Optional: Redis Queue
For production deployments with high volume:
const Redis = require("ioredis");
initMailBlaster({
// ...other config
redis: new Redis({
host: "localhost",
port: 6379,
}),
});Token Replacement
Tokens in email templates are automatically replaced with recipient data:
{
subject: "Hello {{firstName}}!",
bodyHtml: "<p>Welcome to {{companyName}}</p>",
recipients: [
{
email: "[email protected]",
firstName: "John",
companyName: "Acme Corp"
}
]
}Result: "Hello John!" and "Welcome to Acme Corp"
Workflow
- Create Blast - Save as draft with recipients
- Edit Blast - Modify subject, body, or recipients
- Send Blast - Trigger email sending
- View Logs - Track delivery status
Models
EmailBlast
subject: StringbodyHtml: Stringsender: { email, name }recipients: Array of { email, ...custom fields }status: 'draft' | 'sent'timestamps: createdAt, updatedAt
EmailTemplate
name: Stringsubject: StringbodyHtml: Stringtimestamps: createdAt, updatedAt
EmailSendLog
blastId: ObjectIdto: Stringstatus: 'pending' | 'sent' | 'failed' | 'unsubscribed'timestamps: createdAt, updatedAt
Unsubscribe
email: String (unique)timestamps: createdAt, updatedAt
License
MIT
