Files
backend/libs/common/src/util/email.service.ts
2025-01-04 22:42:07 -06:00

220 lines
5.9 KiB
TypeScript

import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as nodemailer from 'nodemailer';
import axios from 'axios';
import {
SEND_EMAIL_API_URL_DEV,
SEND_EMAIL_API_URL_PROD,
} from '../constants/mail-trap';
@Injectable()
export class EmailService {
private smtpConfig: any;
constructor(private readonly configService: ConfigService) {
this.smtpConfig = {
host: this.configService.get<string>('email-config.SMTP_HOST'),
port: this.configService.get<number>('email-config.SMTP_PORT'),
sender: this.configService.get<string>('email-config.SMTP_SENDER'),
secure: this.configService.get<boolean>('email-config.SMTP_SECURE'), // true for 465, false for other ports
auth: {
user: this.configService.get<string>('email-config.SMTP_USER'),
pass: this.configService.get<string>('email-config.SMTP_PASSWORD'),
},
};
}
async sendEmail(
email: string,
subject: string,
message: string,
): Promise<void> {
const transporter = nodemailer.createTransport(this.smtpConfig);
const mailOptions = {
from: this.smtpConfig.sender,
to: email,
subject,
text: message,
};
await transporter.sendMail(mailOptions);
}
async sendEmailWithInvitationTemplate(
email: string,
emailInvitationData: any,
): Promise<void> {
const isProduction = process.env.NODE_ENV === 'production';
const API_TOKEN = this.configService.get<string>(
'email-config.MAILTRAP_API_TOKEN',
);
const API_URL = isProduction
? SEND_EMAIL_API_URL_PROD
: SEND_EMAIL_API_URL_DEV;
const TEMPLATE_UUID = this.configService.get<string>(
'email-config.MAILTRAP_INVITATION_TEMPLATE_UUID',
);
const emailData = {
from: {
email: this.smtpConfig.sender,
},
to: [
{
email: email,
},
],
template_uuid: TEMPLATE_UUID,
template_variables: emailInvitationData,
};
try {
await axios.post(API_URL, emailData, {
headers: {
Authorization: `Bearer ${API_TOKEN}`,
'Content-Type': 'application/json',
},
});
} catch (error) {
throw new HttpException(
error.response?.data?.message ||
'Error sending email using Mailtrap template',
error.response?.status || HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
async sendEmailWithTemplate(
email: string,
name: string,
isEnable: boolean,
isDelete: boolean,
): Promise<void> {
const isProduction = process.env.NODE_ENV === 'production';
const API_TOKEN = this.configService.get<string>(
'email-config.MAILTRAP_API_TOKEN',
);
const API_URL = isProduction
? SEND_EMAIL_API_URL_PROD
: SEND_EMAIL_API_URL_DEV;
// Determine the template UUID based on the arguments
const templateUuid = isDelete
? this.configService.get<string>(
'email-config.MAILTRAP_DELETE_USER_TEMPLATE_UUID',
)
: this.configService.get<string>(
isEnable
? 'email-config.MAILTRAP_ENABLE_TEMPLATE_UUID'
: 'email-config.MAILTRAP_DISABLE_TEMPLATE_UUID',
);
const emailData = {
from: {
email: this.smtpConfig.sender,
},
to: [
{
email,
},
],
template_uuid: templateUuid,
template_variables: {
name,
},
};
try {
await axios.post(API_URL, emailData, {
headers: {
Authorization: `Bearer ${API_TOKEN}`,
'Content-Type': 'application/json',
},
});
} catch (error) {
throw new HttpException(
error.response?.data?.message ||
'Error sending email using Mailtrap template',
error.response?.status || HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
async sendEditUserEmailWithTemplate(
email: string,
emailEditData: any,
): Promise<void> {
const isProduction = process.env.NODE_ENV === 'production';
const API_TOKEN = this.configService.get<string>(
'email-config.MAILTRAP_API_TOKEN',
);
const API_URL = isProduction
? SEND_EMAIL_API_URL_PROD
: SEND_EMAIL_API_URL_DEV;
const TEMPLATE_UUID = this.configService.get<string>(
'email-config.MAILTRAP_EDIT_USER_TEMPLATE_UUID',
);
const emailData = {
from: {
email: this.smtpConfig.sender,
},
to: [
{
email: email,
},
],
template_uuid: TEMPLATE_UUID,
template_variables: emailEditData,
};
try {
await axios.post(API_URL, emailData, {
headers: {
Authorization: `Bearer ${API_TOKEN}`,
'Content-Type': 'application/json',
},
});
} catch (error) {
throw new HttpException(
error.response?.data?.message ||
'Error sending email using Mailtrap template',
error.response?.status || HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
generateUserChangesEmailBody(
addedSpaceNames: string[],
removedSpaceNames: string[],
oldRole: string,
newRole: string,
oldName: string,
newName: string,
) {
const addedSpaceNamesChanged =
addedSpaceNames.length > 0
? `Access to the following spaces were added: ${addedSpaceNames.join(', ')}`
: '';
const removedSpaceNamesChanged =
removedSpaceNames.length > 0
? `Access to the following spaces were deleted: ${removedSpaceNames.join(', ')}`
: '';
const roleChanged =
oldRole !== newRole
? `Your user role has been changed from [${oldRole}] to [${newRole}]`
: '';
const nameChanged =
oldName !== newName
? `The name associated with your account has changed from [${oldName}] to [${newName}]`
: '';
return {
addedSpaceNamesChanged,
removedSpaceNamesChanged,
roleChanged,
nameChanged,
};
}
}