Skip to content

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