This commit is contained in:
pradeepkumar
2026-04-08 09:36:08 +05:30
parent 50ef4d9a08
commit 3489fd913d

View File

@@ -1,7 +1,5 @@
import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as nodemailer from 'nodemailer';
import { Transporter } from 'nodemailer';
import {
getVerificationEmailTemplate,
@@ -14,73 +12,54 @@ export interface EmailOptions {
subject: string;
html: string;
text?: string;
cc?: string[];
bcc?: string[];
replyTo?: string;
}
@Injectable()
export class EmailService {
private readonly logger = new Logger(EmailService.name);
private transporter: Transporter;
private readonly endpoint: string;
constructor(private readonly configService: ConfigService) {
this.createTransporter();
}
private createTransporter() {
const host = this.configService.get<string>('SMTP_HOST');
const port = this.configService.get<number>('SMTP_PORT');
const user = this.configService.get<string>('SMTP_USER');
const pass = this.configService.get<string>('SMTP_PASS');
if (!host || !user || !pass) {
this.logger.warn('SMTP configuration incomplete. Emails will be logged only.');
return;
}
this.transporter = nodemailer.createTransport({
host,
port: port || 465,
secure: true, // SSL/TLS
auth: {
user,
pass,
},
});
// Verify connection
this.transporter.verify((error) => {
if (error) {
this.logger.error('SMTP connection failed:', error);
} else {
this.logger.log('SMTP connection established successfully');
}
});
this.endpoint =
this.configService.get<string>('EMAIL_API_URL') ||
'https://email.routes.hiffi.com/superlabs/v1/send';
this.logger.log(`Email service initialized → ${this.endpoint}`);
}
async sendEmail(options: EmailOptions): Promise<boolean> {
const from = this.configService.get<string>('SMTP_FROM') ||
this.configService.get<string>('SMTP_USER');
const payload: Record<string, any> = {
to: [options.to],
subject: options.subject,
html: options.html,
};
if (!this.transporter) {
this.logger.warn('No SMTP transporter. Logging email instead:');
this.logger.log(`To: ${options.to}`);
this.logger.log(`Subject: ${options.subject}`);
this.logger.log(`Body: ${options.text || 'HTML email'}`);
return false;
}
if (options.text) payload.text = options.text;
if (options.cc && options.cc.length > 0) payload.cc = options.cc;
if (options.bcc && options.bcc.length > 0) payload.bcc = options.bcc;
if (options.replyTo) payload.reply_to = options.replyTo;
try {
const info = await this.transporter.sendMail({
from: `"RE-QuestN" <${from}>`,
to: options.to,
subject: options.subject,
html: options.html,
text: options.text,
const res = await fetch(this.endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
this.logger.log(`Email sent successfully: ${info.messageId}`);
const data = await res.json().catch(() => null);
if (!res.ok || !data?.ok) {
const errMsg = data?.error || `HTTP ${res.status}`;
this.logger.error(`Failed to send email to ${options.to}: ${errMsg}`);
return false;
}
this.logger.log(`Email sent successfully to ${options.to}`);
return true;
} catch (error) {
this.logger.error(`Failed to send email to ${options.to}:`, error);
} catch (error: any) {
this.logger.error(`Email API request failed for ${options.to}: ${error.message}`);
return false;
}
}