Merge pull request #184 from SyncrowIOT/SP-986-be-send-email-for-inviting-user-role

Sp 986 be send email for inviting user role
This commit is contained in:
faris Aljohari
2025-01-04 03:21:30 -06:00
committed by GitHub
6 changed files with 82 additions and 2 deletions

View File

@ -1,3 +1,5 @@
NODE_ENV=
ACCESS_KEY= ACCESS_KEY=
AZURE_POSTGRESQL_DATABASE= AZURE_POSTGRESQL_DATABASE=
@ -52,6 +54,10 @@ SMTP_SECURE=
SMTP_USER= SMTP_USER=
MAILTRAP_API_TOKEN=
MAILTRAP_INVITATION_TEMPLATE_UUID=
WEBSITES_ENABLE_APP_SERVICE_STORAGE= WEBSITES_ENABLE_APP_SERVICE_STORAGE=
PORT= PORT=

View File

@ -10,5 +10,8 @@ export default registerAs(
SMTP_USER: process.env.SMTP_USER, SMTP_USER: process.env.SMTP_USER,
SMTP_SENDER: process.env.SMTP_SENDER, SMTP_SENDER: process.env.SMTP_SENDER,
SMTP_PASSWORD: process.env.SMTP_PASSWORD, SMTP_PASSWORD: process.env.SMTP_PASSWORD,
MAILTRAP_API_TOKEN: process.env.MAILTRAP_API_TOKEN,
MAILTRAP_INVITATION_TEMPLATE_UUID:
process.env.MAILTRAP_INVITATION_TEMPLATE_UUID,
}), }),
); );

View File

@ -0,0 +1,3 @@
export const SEND_EMAIL_API_URL_PROD = 'https://send.api.mailtrap.io/api/send/';
export const SEND_EMAIL_API_URL_DEV =
'https://sandbox.api.mailtrap.io/api/send/2634012';

View File

@ -1,6 +1,11 @@
import { Injectable } from '@nestjs/common'; import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config'; import { ConfigService } from '@nestjs/config';
import * as nodemailer from 'nodemailer'; 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() @Injectable()
export class EmailService { export class EmailService {
@ -35,4 +40,47 @@ export class EmailService {
await transporter.sendMail(mailOptions); 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,
);
}
}
} }

View File

@ -9,6 +9,7 @@ import {
InviteUserRepository, InviteUserRepository,
InviteUserSpaceRepository, InviteUserSpaceRepository,
} from '@app/common/modules/Invite-user/repositiories'; } from '@app/common/modules/Invite-user/repositiories';
import { EmailService } from '@app/common/util/email.service';
@Module({ @Module({
imports: [ConfigModule, InviteUserRepositoryModule], imports: [ConfigModule, InviteUserRepositoryModule],
@ -17,6 +18,7 @@ import {
InviteUserService, InviteUserService,
InviteUserRepository, InviteUserRepository,
UserRepository, UserRepository,
EmailService,
InviteUserSpaceRepository, InviteUserSpaceRepository,
], ],
exports: [InviteUserService], exports: [InviteUserService],

View File

@ -4,7 +4,7 @@ import { BaseResponseDto } from '@app/common/dto/base.response.dto';
import { UserStatusEnum } from '@app/common/constants/user-status.enum'; import { UserStatusEnum } from '@app/common/constants/user-status.enum';
import { SuccessResponseDto } from '@app/common/dto/success.response.dto'; import { SuccessResponseDto } from '@app/common/dto/success.response.dto';
import { generateRandomString } from '@app/common/helper/randomString'; import { generateRandomString } from '@app/common/helper/randomString';
import { IsNull, Not } from 'typeorm'; import { In, IsNull, Not } from 'typeorm';
import { DataSource } from 'typeorm'; import { DataSource } from 'typeorm';
import { UserEntity } from '@app/common/modules/user/entities'; import { UserEntity } from '@app/common/modules/user/entities';
import { RoleType } from '@app/common/constants/role.type.enum'; import { RoleType } from '@app/common/constants/role.type.enum';
@ -14,12 +14,15 @@ import {
} from '@app/common/modules/Invite-user/repositiories'; } from '@app/common/modules/Invite-user/repositiories';
import { CheckEmailDto } from '../dtos/check-email.dto'; import { CheckEmailDto } from '../dtos/check-email.dto';
import { UserRepository } from '@app/common/modules/user/repositories'; import { UserRepository } from '@app/common/modules/user/repositories';
import { EmailService } from '@app/common/util/email.service';
import { SpaceEntity } from '@app/common/modules/space';
@Injectable() @Injectable()
export class InviteUserService { export class InviteUserService {
constructor( constructor(
private readonly inviteUserRepository: InviteUserRepository, private readonly inviteUserRepository: InviteUserRepository,
private readonly userRepository: UserRepository, private readonly userRepository: UserRepository,
private readonly emailService: EmailService,
private readonly inviteUserSpaceRepository: InviteUserSpaceRepository, private readonly inviteUserSpaceRepository: InviteUserSpaceRepository,
private readonly dataSource: DataSource, private readonly dataSource: DataSource,
) {} ) {}
@ -76,7 +79,16 @@ export class InviteUserService {
}); });
const invitedUser = await queryRunner.manager.save(inviteUser); const invitedUser = await queryRunner.manager.save(inviteUser);
const spaceRepo = queryRunner.manager.getRepository(SpaceEntity);
const spaces = await spaceRepo.find({
where: {
uuid: In(spaceUuids),
},
});
const spaceNames = spaces.map((space) => space.spaceName);
const spaceNamesString = spaceNames.join(', ');
const spacePromises = spaceUuids.map(async (spaceUuid) => { const spacePromises = spaceUuids.map(async (spaceUuid) => {
const inviteUserSpace = this.inviteUserSpaceRepository.create({ const inviteUserSpace = this.inviteUserSpaceRepository.create({
inviteUser: { uuid: invitedUser.uuid }, inviteUser: { uuid: invitedUser.uuid },
@ -86,6 +98,12 @@ export class InviteUserService {
}); });
await Promise.all(spacePromises); await Promise.all(spacePromises);
await this.emailService.sendEmailWithInvitationTemplate(email, {
name: firstName + ' ' + lastName,
invitationCode,
role: roleType,
spacesList: spaceNamesString,
});
await queryRunner.commitTransaction(); await queryRunner.commitTransaction();