Re_Backend/src/emailtemplates
2025-12-09 13:06:28 +05:30
..
approvalConfirmation.template.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
approvalRequest.template.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
approverSkipped.template.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
branding.config.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
EMAIL_STRATEGY.md email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
emailPreferences.helper.ts gcp setup and local upload callback with notification rule modification done 2025-12-09 13:06:28 +05:30
helpers.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
IMPLEMENTATION_PLAN.md email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
index.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
multiApproverRequest.template.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
participantAdded.template.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
quick-preview.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
README.md email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
rejectionNotification.template.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
requestClosed.template.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
requestCreated.template.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
RICHTEXT_SUPPORT.md email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
tatBreached.template.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
tatReminder.template.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
TEMPLATE_MAPPING.md email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
test-email.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
test-real-scenario.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
types.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
USAGE.md email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
workflowPaused.template.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30
workflowResumed.template.ts email template flow added with test account and templates for all cenerios 2025-12-04 20:58:32 +05:30

📧 Royal Enfield Workflow - Email Templates

Professional, responsive, and dynamic email templates for the Royal Enfield Workflow System.


🎯 Key Features

Dynamic & Adaptive - Templates adjust based on request data, priority, and workflow state
Single Action Button - Only "View Request Details" button that redirects to request URL
Fully Responsive - Mobile-friendly design that works across all devices
Professional Design - Royal Enfield branded with color-coded scenarios
Email Client Compatible - Table-based layout for maximum compatibility
Placeholder-Based - Easy to integrate with backend templating engines


📁 Template Files (12 Templates)

Core Workflow Templates

  1. RequestCreated.html - Request submission confirmation
  2. ApprovalRequest.html - Single approver notification
  3. MultiApproverRequest.html - Multi-level approver notification with chain
  4. ApprovalConfirmation.html - Approval confirmation notification
  5. RejectionNotification.html - Rejection notification

TAT Management Templates

  1. TATReminder.html - TAT deadline reminder (80% threshold)
  2. TATBreached.html - TAT breach escalation

Workflow Control Templates

  1. WorkflowPaused.html - Workflow pause notification
  2. WorkflowResumed.html - Workflow resume notification

Participant Management Templates

  1. ParticipantAdded.html - New approver/spectator welcome
  2. ApproverSkipped.html - Approver skip notification
  3. RequestClosed.html - Request closure summary

🎨 Visual Design

Each template uses color-coded gradients to indicate the scenario:

Template Header Color Purpose
RequestCreated Purple (#667eea) Information
ApprovalRequest Purple (#667eea) Action Required
MultiApproverRequest Purple (#667eea) Action Required
ApprovalConfirmation Green (#28a745) Success
RejectionNotification Red (#dc3545) Error/Rejection
TATReminder Orange (#ff9800) Warning
TATBreached Red (#dc3545) Critical
WorkflowPaused Gray (#6c757d) Neutral
WorkflowResumed Green (#28a745) Success
ParticipantAdded Purple (#667eea) Information
ApproverSkipped Cyan (#17a2b8) Information
RequestClosed Purple (#6f42c1) Complete

🔗 View Details Button

All templates feature a single action button:

  • Text: "View Request Details" / "Review Request Now" / "Take Action Now"
  • Link Format: {baseURL}/request/{requestNumber}
  • Example: https://workflow.royalenfield.com/request/REQ-2025-12-0013

No approval/rejection buttons in emails - all actions happen within the application.


📋 How to Use Templates

1. Load Template File

const fs = require('fs');
const template = fs.readFileSync('./emailtemplates/ApprovalRequest.html', 'utf8');

2. Replace Placeholders

let emailContent = template
  .replace(/\[ApproverName\]/g, approverName)
  .replace(/\[InitiatorName\]/g, initiatorName)
  .replace(/\[RequestId\]/g, requestId)
  .replace(/\[ViewDetailsLink\]/g, `${baseURL}/request/${requestNumber}`)
  .replace(/\[CompanyName\]/g, 'Royal Enfield');

3. Handle Dynamic Sections

// Priority Section Example
if (priority === 'HIGH' || priority === 'CRITICAL') {
  const priorityHTML = `
    <div style="padding: 20px; background-color: #fff3cd; border-left: 4px solid #ffc107; border-radius: 4px; margin-bottom: 30px;">
      <h3 style="margin: 0 0 10px; color: #856404; font-size: 16px; font-weight: 600;">High Priority</h3>
      <p style="margin: 0; color: #856404; font-size: 14px; line-height: 1.6;">
        This request has been marked as ${priority} priority and requires prompt attention.
      </p>
    </div>
  `;
  emailContent = emailContent.replace('[PrioritySection]', priorityHTML);
} else {
  emailContent = emailContent.replace('[PrioritySection]', '');
}

4. Send Email

await sendEmail({
  to: recipientEmail,
  subject: `[${requestId}] New Approval Request`,
  html: emailContent
});

📖 Complete Documentation

See TEMPLATE_MAPPING.md for:

  • Complete list of all placeholders for each template
  • Dynamic section handling instructions
  • Priority-based sending strategy
  • Usage scenarios and triggers
  • Security considerations
  • Implementation examples

🚀 Integration Steps

Step 1: Email Service Setup

// services/email.service.ts
import nodemailer from 'nodemailer';
import fs from 'fs';
import path from 'path';

class EmailService {
  private transporter;
  
  constructor() {
    this.transporter = nodemailer.createTransport({
      host: process.env.SMTP_HOST,
      port: process.env.SMTP_PORT,
      secure: process.env.SMTP_SECURE === 'true',
      auth: {
        user: process.env.SMTP_USER,
        pass: process.env.SMTP_PASSWORD
      }
    });
  }
  
  async sendEmail(to: string, subject: string, html: string) {
    return await this.transporter.sendMail({
      from: process.env.EMAIL_FROM,
      to,
      subject,
      html
    });
  }
  
  loadTemplate(templateName: string): string {
    const templatePath = path.join(__dirname, '../emailtemplates', `${templateName}.html`);
    return fs.readFileSync(templatePath, 'utf8');
  }
  
  replaceplaceholders(template: string, data: Record<string, string>): string {
    let result = template;
    for (const [key, value] of Object.entries(data)) {
      const regex = new RegExp(`\\[${key}\\]`, 'g');
      result = result.replace(regex, value);
    }
    return result;
  }
}

export const emailService = new EmailService();

Step 2: Create Email Handlers

// services/emailNotification.service.ts
export async function sendApprovalRequest(approverEmail: string, requestData: any) {
  const template = emailService.loadTemplate('ApprovalRequest');
  
  const placeholders = {
    ApproverName: approverEmail.split('@')[0],
    InitiatorName: requestData.initiatorName,
    RequestId: requestData.requestNumber,
    RequestDate: formatDate(requestData.createdAt),
    RequestTime: formatTime(requestData.createdAt),
    RequestType: requestData.requestType,
    RequestDescription: requestData.description,
    PrioritySection: getPrioritySection(requestData.priority),
    ViewDetailsLink: `${process.env.BASE_URL}/request/${requestData.requestNumber}`,
    CompanyName: 'Royal Enfield'
  };
  
  const html = emailService.replaceplaceholders(template, placeholders);
  
  await emailService.sendEmail(
    approverEmail,
    `[${requestData.requestNumber}] New Approval Request`,
    html
  );
}

Step 3: Add to Workflow Events

// In workflow.service.ts
await sendApprovalRequest(approverEmail, requestData);

🔧 Environment Variables Required

Add to your .env file:

# SMTP Configuration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=your-email@domain.com
SMTP_PASSWORD=your-app-password

# Email Settings
EMAIL_FROM=RE Workflow System <notifications@royalenfield.com>
BASE_URL=https://workflow.royalenfield.com
COMPANY_NAME=Royal Enfield

Testing Templates

Preview in Browser

Open any .html file directly in a browser to see the design. Placeholders will be visible as [PlaceholderName].

Test Email Sending

// test/email.test.ts
import { emailService } from '../services/email.service';

describe('Email Templates', () => {
  it('should send approval request email', async () => {
    const template = emailService.loadTemplate('ApprovalRequest');
    const testData = {
      ApproverName: 'John Doe',
      InitiatorName: 'Jane Smith',
      RequestId: 'REQ-2025-12-0013',
      // ... other test data
    };
    
    const html = emailService.replaceplaceholders(template, testData);
    
    // Send to test email
    await emailService.sendEmail('test@example.com', 'Test Email', html);
  });
});

📊 Template Selection Logic

function getTemplateForScenario(scenario: string, hasMultipleApprovers: boolean): string {
  switch(scenario) {
    case 'request_created':
      return 'RequestCreated';
    case 'approval_required':
      return hasMultipleApprovers ? 'MultiApproverRequest' : 'ApprovalRequest';
    case 'request_approved':
      return 'ApprovalConfirmation';
    case 'request_rejected':
      return 'RejectionNotification';
    case 'tat_reminder':
      return 'TATReminder';
    case 'tat_breached':
      return 'TATBreached';
    case 'workflow_paused':
      return 'WorkflowPaused';
    case 'workflow_resumed':
      return 'WorkflowResumed';
    case 'participant_added':
      return 'ParticipantAdded';
    case 'approver_skipped':
      return 'ApproverSkipped';
    case 'request_closed':
      return 'RequestClosed';
    default:
      throw new Error(`Unknown scenario: ${scenario}`);
  }
}

🎯 Priority Queue Implementation

Use Bull/BullMQ for reliable email delivery:

import Queue from 'bull';

const emailQueue = new Queue('email-notifications', {
  redis: {
    host: process.env.REDIS_HOST,
    port: process.env.REDIS_PORT
  }
});

// Add email to queue with priority
export async function queueEmail(emailData: any, priority: 'critical' | 'high' | 'medium' | 'low') {
  const priorityMap = { critical: 1, high: 2, medium: 3, low: 4 };
  
  await emailQueue.add('send-email', emailData, {
    priority: priorityMap[priority],
    attempts: 3,
    backoff: {
      type: 'exponential',
      delay: 5000
    }
  });
}

// Process email queue
emailQueue.process('send-email', async (job) => {
  const { to, subject, html } = job.data;
  await emailService.sendEmail(to, subject, html);
});

📞 Support & Customization

For template customization or issues:

  1. Check TEMPLATE_MAPPING.md for complete documentation
  2. Test templates in email clients (Gmail, Outlook, Apple Mail)
  3. Validate HTML using online validators
  4. Use email testing services (Litmus, Email on Acid)

📝 Change Log

Version 2.0 (Dec 4, 2025)

  • Removed all action buttons (Approve/Reject)
  • Added single "View Request Details" button
  • Made templates fully dynamic with conditional sections
  • Added 12 templates for all scenarios
  • Improved mobile responsiveness
  • Professional design without emojis
  • Added comprehensive documentation

Version 1.0 (Initial Release)

  • Basic templates with action buttons
  • 4 templates (Approval, Rejection, Multi-Approver, Confirmation)

Maintained by: Royal Enfield Development Team
Last Updated: December 4, 2025
Email Template Version: 2.0