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('email-config.SMTP_HOST'), port: this.configService.get('email-config.SMTP_PORT'), sender: this.configService.get('email-config.SMTP_SENDER'), secure: this.configService.get('email-config.SMTP_SECURE'), // true for 465, false for other ports auth: { user: this.configService.get('email-config.SMTP_USER'), pass: this.configService.get('email-config.SMTP_PASSWORD'), }, }; } async sendEmail( email: string, subject: string, message: string, ): Promise { 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 { const isProduction = process.env.NODE_ENV === 'production'; const API_TOKEN = this.configService.get( '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( '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 { const isProduction = process.env.NODE_ENV === 'production'; const API_TOKEN = this.configService.get( '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( 'email-config.MAILTRAP_DELETE_USER_TEMPLATE_UUID', ) : this.configService.get( 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 { const isProduction = process.env.NODE_ENV === 'production'; const API_TOKEN = this.configService.get( '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( '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, }; } }