src/notifications/notification.service.ts
Methods |
|
constructor()
|
|
Defined in src/notifications/notification.service.ts:7
|
| Async sendAlertNotification | |||||||||||||||
sendAlertNotification(email: string, alertTitle: string, alertDescription: string, severity: string)
|
|||||||||||||||
|
Send alert escalation notification
Parameters :
Returns :
Promise<void>
|
| Async sendDeliveryConfirmation |
sendDeliveryConfirmation(clientEmail: string, orderNumber: string, recipientName: string)
|
|
Send delivery confirmation to client
Returns :
Promise<void>
|
| Async sendEmail |
sendEmail(to: string, subject: string, html: string)
|
|
Defined in src/notifications/notification.service.ts:30
|
|
Send an email notification
Returns :
Promise<boolean>
|
| Async sendEtaUpdate | |||||||||||||||
sendEtaUpdate(clientEmail: string, orderNumber: string, newEta: Date, reason?: string)
|
|||||||||||||||
|
Defined in src/notifications/notification.service.ts:88
|
|||||||||||||||
|
Send ETA update notification to client contact
Parameters :
Returns :
Promise<void>
|
| Async sendSms |
sendSms(to: string, message: string)
|
|
Defined in src/notifications/notification.service.ts:59
|
|
Send SMS via Twilio (or log if not configured)
Returns :
Promise<boolean>
|
import { Injectable, Logger } from '@nestjs/common';
import * as nodemailer from 'nodemailer';
@Injectable()
export class NotificationService {
private readonly logger = new Logger(NotificationService.name);
private emailTransport: nodemailer.Transporter | null = null;
constructor() {
// Set up email transport if SMTP configured
if (process.env.SMTP_HOST) {
this.emailTransport = nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: parseInt(process.env.SMTP_PORT || '587'),
secure: process.env.SMTP_SECURE === 'true',
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
});
this.logger.log('Email transport configured');
} else {
this.logger.warn('SMTP not configured — emails will be logged only');
}
}
/**
* Send an email notification
*/
async sendEmail(
to: string,
subject: string,
html: string,
): Promise<boolean> {
if (!this.emailTransport) {
this.logger.log(`[EMAIL LOG] To: ${to} | Subject: ${subject}`);
return true; // Log-only mode
}
try {
await this.emailTransport.sendMail({
from:
process.env.SMTP_FROM || 'FleetCommand <noreply@fleetcommand.io>',
to,
subject,
html,
});
this.logger.log(`Email sent to ${to}: ${subject}`);
return true;
} catch (err) {
this.logger.error(`Failed to send email to ${to}: ${err}`);
return false;
}
}
/**
* Send SMS via Twilio (or log if not configured)
*/
async sendSms(to: string, message: string): Promise<boolean> {
if (!process.env.TWILIO_ACCOUNT_SID) {
this.logger.log(`[SMS LOG] To: ${to} | Message: ${message}`);
return true;
}
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const twilio = require('twilio');
const client = twilio(
process.env.TWILIO_ACCOUNT_SID,
process.env.TWILIO_AUTH_TOKEN,
);
await client.messages.create({
body: message,
from: process.env.TWILIO_PHONE_NUMBER,
to,
});
this.logger.log(`SMS sent to ${to}`);
return true;
} catch (err) {
this.logger.error(`Failed to send SMS to ${to}: ${err}`);
return false;
}
}
/**
* Send ETA update notification to client contact
*/
async sendEtaUpdate(
clientEmail: string,
orderNumber: string,
newEta: Date,
reason?: string,
): Promise<void> {
const etaStr = newEta.toLocaleString('en-US', {
dateStyle: 'medium',
timeStyle: 'short',
});
const subject = `FleetCommand — ETA Update for ${orderNumber}`;
const html = `
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<div style="background: linear-gradient(135deg, #6366f1, #3b82f6); padding: 20px 30px; border-radius: 12px 12px 0 0;">
<h2 style="color: white; margin: 0;">FleetCommand</h2>
</div>
<div style="background: #f8fafc; padding: 30px; border: 1px solid #e2e8f0; border-radius: 0 0 12px 12px;">
<h3 style="color: #1e293b; margin-top: 0;">ETA Update for Order ${orderNumber}</h3>
<p style="color: #64748b;">The estimated time of arrival has been updated:</p>
<div style="background: white; border: 1px solid #e2e8f0; border-radius: 8px; padding: 16px; margin: 16px 0;">
<p style="margin: 0; font-size: 24px; font-weight: bold; color: #1e293b;">${etaStr}</p>
</div>
${reason ? `<p style="color: #64748b;">Reason: ${reason}</p>` : ''}
<p style="color: #94a3b8; font-size: 12px; margin-top: 20px;">This is an automated notification from FleetCommand TMS.</p>
</div>
</div>
`;
await this.sendEmail(clientEmail, subject, html);
}
/**
* Send alert escalation notification
*/
async sendAlertNotification(
email: string,
alertTitle: string,
alertDescription: string,
severity: string,
): Promise<void> {
const severityColor =
severity === 'CRITICAL'
? '#ef4444'
: severity === 'WARNING'
? '#f59e0b'
: '#3b82f6';
const subject = `[${severity}] FleetCommand Alert: ${alertTitle}`;
const html = `
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<div style="background: ${severityColor}; padding: 20px 30px; border-radius: 12px 12px 0 0;">
<h2 style="color: white; margin: 0;">${severity} Alert</h2>
</div>
<div style="background: #f8fafc; padding: 30px; border: 1px solid #e2e8f0; border-radius: 0 0 12px 12px;">
<h3 style="color: #1e293b; margin-top: 0;">${alertTitle}</h3>
<p style="color: #64748b;">${alertDescription}</p>
<a href="#" style="display: inline-block; background: #6366f1; color: white; padding: 10px 20px; border-radius: 8px; text-decoration: none; margin-top: 16px;">View in FleetCommand</a>
</div>
</div>
`;
await this.sendEmail(email, subject, html);
}
/**
* Send delivery confirmation to client
*/
async sendDeliveryConfirmation(
clientEmail: string,
orderNumber: string,
recipientName: string,
): Promise<void> {
const subject = `FleetCommand — Delivery Confirmed: ${orderNumber}`;
const html = `
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<div style="background: linear-gradient(135deg, #10b981, #14b8a6); padding: 20px 30px; border-radius: 12px 12px 0 0;">
<h2 style="color: white; margin: 0;">Delivery Confirmed</h2>
</div>
<div style="background: #f8fafc; padding: 30px; border: 1px solid #e2e8f0; border-radius: 0 0 12px 12px;">
<h3 style="color: #1e293b; margin-top: 0;">Order ${orderNumber} has been delivered</h3>
<p style="color: #64748b;">Received by: <strong>${recipientName}</strong></p>
<p style="color: #64748b;">Delivered at: ${new Date().toLocaleString('en-US', { dateStyle: 'medium', timeStyle: 'short' })}</p>
<p style="color: #94a3b8; font-size: 12px; margin-top: 20px;">Proof of delivery is available in your FleetCommand dashboard.</p>
</div>
</div>
`;
await this.sendEmail(clientEmail, subject, html);
}
}