@nixxie-international/email-service
v2.0.2
Published
A robust, modern, and comprehensive email service for Node.js with TypeScript support, advanced validation, tracking, analytics, A/B testing, and suppression lists
Maintainers
Readme
@nixxie-international/email-service
A robust, modern, and comprehensive email service for Node.js applications built with TypeScript. Features advanced email templating, tracking, analytics, A/B testing, and suppression lists.
✨ Features
- 📧 Email sending with Pug template engine
- 🔍 Advanced email validation with comprehensive error handling
- 📊 Email tracking and analytics with detailed metrics
- 🔄 Retry mechanism with exponential backoff and jitter
- 📦 Bulk email sending with intelligent batching
- ⏰ Email scheduling for future delivery
- 🎯 Template helpers for common formatting needs
- 🚫 Suppression lists (permanent and temporary)
- 🧪 A/B testing with statistical distribution
- 💥 Bounce handling and delivery notifications
- 📈 Email analytics and comprehensive reporting
- 🛡️ Type-safe with full TypeScript support
- 🏗️ Modern architecture with dependency injection
- ⚡ High performance with connection pooling and rate limiting
🚀 Installation
npm install @nixxie-international/email-service📋 Requirements
- Node.js >= 16.0.0
- TypeScript >= 4.5.0 (for TypeScript projects)
🎯 Quick Start
import { createEmailService } from '@nixxie-international/email-service';
const emailService = createEmailService({
smtp: {
host: 'smtp.gmail.com',
port: 587,
user: '[email protected]',
password: 'your-app-password'
},
defaults: {
companyName: 'Your Company',
emailFrom: '[email protected]'
},
templateDir: './email-templates'
});
// Initialize the service
await emailService.initialize();
// Send an email
const result = await emailService.sendEmail({
to: '[email protected]',
subject: 'Welcome to our platform!',
templateName: 'welcome',
data: {
userName: 'John Doe',
loginUrl: 'https://yourapp.com/login'
},
tracking: true
});
console.log(`Email sent: ${result.messageId}`);⚙️ Configuration
Basic Configuration
interface EmailServiceConfig {
smtp: {
host: string;
port: number;
secure?: boolean; // Use TLS (default: false)
user: string;
password: string;
maxConnections?: number; // Max concurrent connections (default: 5)
rateDelta?: number; // Rate limiting time window (default: 20000ms)
rateLimit?: number; // Max emails per time window (default: 5)
};
defaults: {
companyName: string;
emailFrom: string;
domain?: string; // For message ID generation
};
templateDir?: string; // Path to Pug templates (default: './email-templates')
apiUrl?: string; // For tracking URLs
logger?: Logger; // Custom logger (default: console)
retryConfig?: Partial<RetryConfig>;
}Advanced Configuration
const emailService = createAdvancedEmailService({
smtp: {
host: 'smtp.sendgrid.net',
port: 587,
user: 'apikey',
password: 'your-sendgrid-api-key',
maxConnections: 10,
rateLimit: 50,
rateDelta: 60000 // 1 minute
},
defaults: {
companyName: 'Acme Corp',
emailFrom: '[email protected]',
domain: 'acme.com'
},
templateDir: './src/email-templates',
retryConfig: {
maxRetries: 5,
baseDelay: 2000,
maxDelay: 60000,
factor: 2
}
});📧 Sending Emails
Single Email
await emailService.sendEmail({
to: '[email protected]',
subject: 'Welcome!',
templateName: 'welcome',
data: { name: 'John', code: '12345' },
cc: ['[email protected]'],
bcc: ['[email protected]'],
priority: 'high',
tracking: true,
metadata: { userId: '123', campaignId: 'welcome-series' }
});Bulk Email Sending
await emailService.sendBulkEmails({
recipients: [
{ to: '[email protected]', data: { name: 'User 1' } },
{ to: '[email protected]', data: { name: 'User 2' } },
// ... more recipients
],
subject: 'Monthly Newsletter',
templateName: 'newsletter',
batchSize: 100, // Send in batches of 100
delayBetweenBatches: 5000, // 5 second delay between batches
tracking: true
});Scheduled Emails
const scheduleId = await emailService.scheduleEmail({
to: '[email protected]',
subject: 'Reminder: Meeting tomorrow',
templateName: 'reminder',
data: { meetingTime: '2024-01-15 10:00 AM' },
sendAt: new Date('2024-01-14T18:00:00Z'),
tracking: true
});
console.log(`Email scheduled with ID: ${scheduleId}`);🎨 Template System
Template Helpers
Built-in helpers available in all Pug templates:
// welcome.pug
html
body
h1 Welcome #{userName}!
p Your account was created on #{formatDate(createdAt, 'MMMM DD, YYYY')}
p Current balance: #{formatCurrency(balance, 'USD')}
p= truncate(description, 150)
div!= linkify(userBio)
ul
each item in items
li= item.nameAvailable template helpers:
- formatDate(date, format) - Format dates using Intl.DateTimeFormat
- formatDateTime(date, format) - Format date and time
- formatCurrency(amount, currency) - Format currency values
- truncate(text, length) - Truncate text with ellipsis
- linkify(text) - Convert URLs to clickable links
- escapeHtml(html) - Escape HTML characters for security
- generateList(items, property) - Generate HTML lists
Custom Template Directory
const emailService = createEmailService({
// ... other config
templateDir: path.join(__dirname, 'custom-templates')
});🚫 Suppression Lists (Advanced)
Prevent emails from being sent to specific addresses:
const advancedService = createAdvancedEmailService(config);
// Add permanent suppression
advancedService.addToSuppressionList('[email protected]', true);
// Add temporary suppression (24 hours)
advancedService.addToSuppressionList('[email protected]', false);
// Check if email is suppressed
const isSuppressed = advancedService.isEmailSuppressed('[email protected]');
// Remove from suppression list
advancedService.removeFromSuppressionList('[email protected]');🧪 A/B Testing
Test different email subjects or content:
const results = await advancedService.sendABTestEmail({
recipients: ['[email protected]', '[email protected]', '[email protected]'],
subjectA: 'Special Offer Inside!',
subjectB: '50% Off Everything Today',
templateName: 'promotion',
data: { discount: 50 },
splitRatio: 0.5, // 50/50 split
testName: 'subject-line-test-q1-2024'
});
console.log(`Test ID: ${results.testId}`);
console.log(`Group A sent to ${results.groupA.length} recipients`);
console.log(`Group B sent to ${results.groupB.length} recipients`);📊 Analytics & Tracking
Get Email Analytics
const analytics = emailService.getEmailAnalytics({
templateName: 'welcome',
startDate: new Date('2024-01-01'),
endDate: new Date('2024-01-31')
});
console.log(analytics);
/*
{
sent: 1000,
delivered: 980,
opened: 450,
clicked: 120,
bounced: 20,
failed: 0,
openRate: 45.9, // percentage
clickRate: 12.2, // percentage
bounceRate: 2.0 // percentage
}
*/Track Email Status Updates
// Update email status when webhooks are received
emailService.updateTrackingStatus(trackingId, 'opened');
emailService.updateTrackingStatus(trackingId, 'clicked');
emailService.updateTrackingStatus(trackingId, 'bounced');
// Get tracking data for specific email
const trackingData = emailService.getTrackingData(trackingId);Handle Bounce Notifications
emailService.processBounceNotification({
messageId: 'original-message-id',
email: '[email protected]',
reason: 'Mailbox full',
bounceType: 'soft' // 'soft', 'hard', or 'complaint'
});🛡️ Error Handling
The service provides comprehensive error types for better error handling:
import {
EmailValidationError,
EmailTemplateError,
EmailTransportError,
EmailSuppressionError
} from '@nixxie-international/email-service';
try {
await emailService.sendEmail(invalidOptions);
} catch (error) {
if (error instanceof EmailValidationError) {
console.log('Validation failed:', error.message);
console.log('Error details:', error.details);
} else if (error instanceof EmailTemplateError) {
console.log('Template error:', error.message);
} else if (error instanceof EmailTransportError) {
console.log('SMTP transport error:', error.message);
} else if (error instanceof EmailSuppressionError) {
console.log('Email suppressed:', error.message);
}
}🔍 Email Validation
Robust email validation with comprehensive checks:
import { EmailValidator } from '@nixxie-international/email-service';
// Validate single email
const isValid = EmailValidator.validateEmail('[email protected]');
// Validate multiple emails
const { valid, invalid } = EmailValidator.validateEmails([
'[email protected]',
'bad-email',
'[email protected]'
]);
// Throw error for invalid emails
EmailValidator.requireValidEmail('[email protected]'); // throws if invalid
// Normalize email
const normalized = EmailValidator.normalizeEmail(' [email protected] ');
// Returns: '[email protected]'
// Check for disposable email services
const isDisposable = EmailValidator.isDisposableEmail('[email protected]');
// Extract domain
const domain = EmailValidator.extractDomain('[email protected]'); // 'example.com'🧪 Testing
Run the test suite:
npm test # Run all tests
npm run test:watch # Run tests in watch mode
npm run test:coverage # Run tests with coverage reportTest specific functionality:
npm test -- --testNamePattern="validation"
npm test -- src/__tests__/email-service.test.ts🏗️ Development
# Clone the repository
git clone https://github.com/sherghan7/email-service.git
cd email-service
# Install dependencies
npm install
# Run in development mode
npm run dev
# Build the project
npm run build
# Run linting
npm run lint
npm run lint:fix📚 API Reference
EmailService Methods
| Method | Description |
|--------|-------------|
| initialize() | Initialize SMTP connection |
| sendEmail(options) | Send single email |
| sendBulkEmails(options) | Send bulk emails |
| scheduleEmail(options) | Schedule email for future delivery |
| renderTemplate(name, data) | Render Pug template |
| validateEmailAddress(email) | Validate email address |
| getEmailAnalytics(filters) | Get email analytics |
| updateTrackingStatus(id, status) | Update tracking status |
| processBounceNotification(data) | Handle bounce notifications |
AdvancedEmailService Additional Methods
| Method | Description |
|--------|-------------|
| addToSuppressionList(email, permanent) | Add email to suppression list |
| removeFromSuppressionList(email) | Remove email from suppression list |
| isEmailSuppressed(email) | Check if email is suppressed |
| sendABTestEmail(options) | Send A/B test emails |
🔧 Configuration Examples
Gmail SMTP
{
smtp: {
host: 'smtp.gmail.com',
port: 587,
user: '[email protected]',
password: 'your-app-password' // Use app password, not regular password
}
}SendGrid SMTP
{
smtp: {
host: 'smtp.sendgrid.net',
port: 587,
user: 'apikey',
password: 'your-sendgrid-api-key'
}
}AWS SES SMTP
{
smtp: {
host: 'email-smtp.us-east-1.amazonaws.com',
port: 587,
user: 'your-access-key-id',
password: 'your-secret-access-key'
}
}🔒 Security Considerations
- Never commit SMTP credentials to version control
- Use environment variables for sensitive configuration
- Validate all email addresses before sending
- Implement rate limiting to prevent abuse
- Use suppression lists to respect user preferences
- Sanitize template data to prevent XSS attacks
🤝 Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
👨💻 Author
Sher Ghan
- GitHub: @sherghan7
- Email: [email protected]
🆘 Support
If you have any questions or need help:
- Check the GitHub Issues
- Create a new issue if your problem isn't already listed
- For urgent support, contact: [email protected]
🎯 Roadmap
- [ ] Webhook endpoints for email events
- [ ] Email templates marketplace
- [ ] Visual template editor
- [ ] Advanced analytics dashboard
- [ ] Integration with popular email marketing platforms
- [ ] Support for other template engines (Handlebars, Mustache)
- [ ] Queue-based email processing
- [ ] Multi-tenant support
Made with ❤️ by Sher Ghan at Nixxie International
