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 { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config'; import { ConfigService } from '@nestjs/config';
import * as nodemailer from 'nodemailer';
import { Transporter } from 'nodemailer';
import { import {
getVerificationEmailTemplate, getVerificationEmailTemplate,
@@ -14,73 +12,54 @@ export interface EmailOptions {
subject: string; subject: string;
html: string; html: string;
text?: string; text?: string;
cc?: string[];
bcc?: string[];
replyTo?: string;
} }
@Injectable() @Injectable()
export class EmailService { export class EmailService {
private readonly logger = new Logger(EmailService.name); private readonly logger = new Logger(EmailService.name);
private transporter: Transporter; private readonly endpoint: string;
constructor(private readonly configService: ConfigService) { constructor(private readonly configService: ConfigService) {
this.createTransporter(); this.endpoint =
} this.configService.get<string>('EMAIL_API_URL') ||
'https://email.routes.hiffi.com/superlabs/v1/send';
private createTransporter() { this.logger.log(`Email service initialized → ${this.endpoint}`);
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');
}
});
} }
async sendEmail(options: EmailOptions): Promise<boolean> { async sendEmail(options: EmailOptions): Promise<boolean> {
const from = this.configService.get<string>('SMTP_FROM') || const payload: Record<string, any> = {
this.configService.get<string>('SMTP_USER'); to: [options.to],
subject: options.subject,
html: options.html,
};
if (!this.transporter) { if (options.text) payload.text = options.text;
this.logger.warn('No SMTP transporter. Logging email instead:'); if (options.cc && options.cc.length > 0) payload.cc = options.cc;
this.logger.log(`To: ${options.to}`); if (options.bcc && options.bcc.length > 0) payload.bcc = options.bcc;
this.logger.log(`Subject: ${options.subject}`); if (options.replyTo) payload.reply_to = options.replyTo;
this.logger.log(`Body: ${options.text || 'HTML email'}`);
try {
const res = await fetch(this.endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
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; return false;
} }
try { this.logger.log(`Email sent successfully to ${options.to}`);
const info = await this.transporter.sendMail({
from: `"RE-QuestN" <${from}>`,
to: options.to,
subject: options.subject,
html: options.html,
text: options.text,
});
this.logger.log(`Email sent successfully: ${info.messageId}`);
return true; return true;
} catch (error) { } catch (error: any) {
this.logger.error(`Failed to send email to ${options.to}:`, error); this.logger.error(`Email API request failed for ${options.to}: ${error.message}`);
return false; return false;
} }
} }