Notifications
Email notification system for important platform events using Nodemailer.
Overview
- Email notifications for key events
- Template-based emails
- Async processing (queued notifications)
- Multiple notification types
- Configurable SMTP
Notification Types
User Events
- Welcome email – After registration with activation link
- Account activated – Confirmation of activation
- Password reset – Reset link and instructions
- KYC approved – Identity verification approved
- KYC rejected – Identity verification rejected with reason
Order Events
- New order – Seller receives new order notification
- Order accepted – Customer notified seller accepted
- Order delivered – Customer notified work is ready
- Order completed – Seller notified of completion
- Order cancelled – Both parties notified
- Cancellation requested – Seller notified of cancellation request
- Dispute opened – Admin notified of dispute
Payment Events
- Payment received – Order payment confirmed
- Payout completed – Seller payout processed
- Refund processed – Customer refund completed
Notifier Interface
export abstract class Notifier {
abstract sendWelcomeMessage(token: string, user: User): Promise<void>;
abstract sendPasswordResetEmail(user: User, token: string): Promise<void>;
abstract sendKYCApprovedEmail(user: User): Promise<void>;
abstract sendKYCRejectedEmail(user: User, reason: string): Promise<void>;
abstract notifySellerNewOrder(seller: User, order: Order): Promise<void>;
abstract notifyCustomerOrderAccepted(customer: User, order: Order): Promise<void>;
// ... more methods
}
Email Implementation
export class EmailNotifier extends Notifier {
private transporter: nodemailer.Transporter;
constructor() {
this.transporter = nodemailer.createTransporter({
host: process.env.SMTP_HOST,
port: parseInt(process.env.SMTP_PORT!),
secure: process.env.SMTP_SECURE === 'true',
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASSWORD
}
});
}
async sendWelcomeMessage(token: string, user: User) {
const activationUrl = `${process.env.FRONTEND_URL}/activate?token=${token}`;
await this.transporter.sendMail({
from: process.env.SMTP_FROM,
to: user.email,
subject: 'Welcome to 2KRIKA',
html: this.renderTemplate('welcome', {
fullName: user.fullName,
activationUrl
})
});
}
async notifySellerNewOrder(seller: User, order: Order) {
await this.transporter.sendMail({
from: process.env.SMTP_FROM,
to: seller.email,
subject: `New Order: ${order.serviceTitle}`,
html: this.renderTemplate('new-order', {
sellerName: seller.fullName,
orderNumber: order.getNumber(),
serviceTitle: order.serviceTitle,
amount: order.totalAmount,
orderUrl: `${process.env.FRONTEND_URL}/orders/${order.id}`
})
});
}
}
Email Templates
Using simple template strings:
private renderTemplate(templateName: string, data: any): string {
const templates = {
'welcome': `
<h1>Welcome to 2KRIKA, ${data.fullName}!</h1>
<p>Thank you for registering. Please activate your account:</p>
<a href="${data.activationUrl}">Activate Account</a>
`,
'new-order': `
<h1>New Order Received!</h1>
<p>Hi ${data.sellerName},</p>
<p>You have a new order for <strong>${data.serviceTitle}</strong></p>
<p>Order #: ${data.orderNumber}</p>
<p>Amount: ${data.amount} XOF</p>
<a href="${data.orderUrl}">View Order</a>
`
};
return templates[templateName];
}
Environment Variables
# SMTP Configuration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=your-email@gmail.com
SMTP_PASSWORD=your-app-password
SMTP_FROM="2KRIKA <noreply@2krika.com>"
# Frontend URL (for links in emails)
FRONTEND_URL=https://2krika.com
Best Practices
✅ Do
- Use async/await for email sending
- Handle email failures gracefully
- Log email sending attempts
- Use email templates
- Include unsubscribe links (for marketing emails)
- Test emails in development
❌ Don't
- Don't block requests waiting for emails
- Don't expose email errors to users
- Don't send emails without user consent
- Don't hardcode email content
- Don't forget to handle SMTP errors
Testing
export class MockNotifier extends Notifier {
sentEmails: Array<{ to: string; subject: string; body: string }> = [];
async sendWelcomeMessage(token: string, user: User) {
this.sentEmails.push({
to: user.email,
subject: 'Welcome to 2KRIKA',
body: `Activation token: ${token}`
});
}
// ... implement other methods
}
Summary
The notification system provides: - Email notifications for all important events - Template-based emails for consistency - Async processing to not block requests - Configurable SMTP for any email provider - Testing support with mock notifier