Skip to content

Commit d79d01e

Browse files
committed
feat: add send mail for bot
1 parent 6ecaa88 commit d79d01e

File tree

10 files changed

+90
-14
lines changed

10 files changed

+90
-14
lines changed

client/src/components/forms/variables-setting.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ export const VariablesSettingForm = ({
120120

121121
if (
122122
!_.isEmpty(form.formState.errors.variables) ||
123-
variablesWatch?.some((field) => !field.name || !field.value)
123+
variablesWatch?.some((field) => !field.name)
124124
)
125125
return
126126

server/src/constants/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ export const ENDPOINTS = {
7171
INDEX: '/conversation-live-chat',
7272
GET_MESSAGES: '/conversation-live-chat/:userId/:contactId',
7373
},
74+
BOT_MAIL: {
75+
SEND_MAIL: '/bot-mail/send',
76+
},
7477
}
7578

7679
export const LOCALE_KEY = 'lang'
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { LOCALE_KEY } from '@/constants'
2+
import { BotMailDto } from '@/dtos/bot-mail.dto'
3+
import { LocaleService } from '@/i18n/ctx'
4+
import { BotMailService } from '@/services/bot-mail.service'
5+
import { catchAsync } from '@/utils/catch-async'
6+
import { StatusCodes } from 'http-status-codes'
7+
import Container from 'typedi'
8+
9+
export class BotMailController {
10+
private readonly botMailService = Container.get(BotMailService)
11+
private readonly localeService: LocaleService = Container.get(LOCALE_KEY)
12+
13+
sendMail = catchAsync(async (req, res) => {
14+
await this.botMailService.sendMail(req.body as BotMailDto)
15+
16+
res.status(StatusCodes.OK).json({
17+
message: this.localeService.i18n().COMMON.SEND_MAIL_SUCCESS(),
18+
})
19+
})
20+
}

server/src/dtos/bot-mail.dto.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { IsEmail, IsNotEmpty, IsObject, IsString } from 'class-validator'
1+
import { IsEmail, IsNotEmpty, IsString } from 'class-validator'
22

33
export class BotMailDto {
44
@IsString()
@@ -19,6 +19,7 @@ export class BotMailDto {
1919
@IsNotEmpty()
2020
template: string
2121

22-
@IsObject()
23-
variables: Record<string, any>
22+
@IsString()
23+
@IsNotEmpty()
24+
contactId: string
2425
}

server/src/i18n/ctx.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,28 @@ export class LocaleService {
1010
this.locale = locale
1111
}
1212

13+
/**
14+
* Gets the current locale.
15+
*
16+
* @returns The current locale.
17+
*/
1318
getLocale() {
1419
return this.locale
1520
}
1621

22+
/**
23+
* Sets the locale for the context.
24+
* @param locale The locale to set.
25+
*/
1726
setLocale(locale: Locales) {
18-
console.log('setLocale', locale)
1927
this.locale = locale
2028
}
2129

30+
/**
31+
* Returns the localized language object based on the current locale.
32+
* @returns The localized language object.
33+
*/
2234
i18n() {
23-
console.log(this.locale)
2435
return L[this.locale]
2536
}
2637
}

server/src/i18n/en/common.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ export const COMMON = {
44
NAME: 'Name',
55
CONFIRM_PASSWORD: 'Confirm password',
66
OLD_PASSWORD: 'Old password',
7+
SEND_MAIL_SUCCESS: 'Send mail successfully',
78
}

server/src/i18n/i18n-types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ type RootTranslation = {
188188
* O​l​d​ ​p​a​s​s​w​o​r​d
189189
*/
190190
OLD_PASSWORD: string
191+
/**
192+
* S​e​n​d​ ​m​a​i​l​ ​s​u​c​c​e​s​s​f​u​l​l​y
193+
*/
194+
SEND_MAIL_SUCCESS: string
191195
}
192196
CHANNEL: {
193197
/**
@@ -481,6 +485,10 @@ export type TranslationFunctions = {
481485
* Old password
482486
*/
483487
OLD_PASSWORD: () => LocalizedString
488+
/**
489+
* Send mail successfully
490+
*/
491+
SEND_MAIL_SUCCESS: () => LocalizedString
484492
}
485493
CHANNEL: {
486494
/**

server/src/i18n/vi/common.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ export const COMMON = {
44
NAME: 'Tên',
55
CONFIRM_PASSWORD: 'Xác nhận mật khẩu',
66
OLD_PASSWORD: 'Mật khẩu cũ',
7+
SEND_MAIL_SUCCESS: 'Gửi mail thành công',
78
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { ENDPOINTS } from '@/constants'
2+
import { BotMailController } from '@/controllers/bot-mail.controller'
3+
import { BotMailDto } from '@/dtos/bot-mail.dto'
4+
import { Routes } from '@/interfaces/routes.interface'
5+
import { validate } from '@/middlewares/validation.middleware'
6+
import { Router } from 'express'
7+
8+
export class BotMailRoute implements Routes {
9+
router = Router()
10+
controller = new BotMailController()
11+
12+
constructor() {
13+
this.initializeRoutes()
14+
}
15+
16+
initializeRoutes() {
17+
this.router.post(
18+
ENDPOINTS.BOT_MAIL.SEND_MAIL,
19+
validate(BotMailDto),
20+
this.controller.sendMail,
21+
)
22+
}
23+
}

server/src/services/bot-mail.service.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,39 @@ import { BotMailDto } from '@/dtos/bot-mail.dto'
44
import { SendMailQueue } from '@/queues/mail.queue'
55
import { eq } from 'drizzle-orm'
66
import { Service } from 'typedi'
7+
import { ChannelService } from './channels.service'
78

89
@Service()
910
export class BotMailService {
10-
constructor(private readonly sendMailQueue: SendMailQueue) {}
11+
constructor(
12+
private readonly sendMailQueue: SendMailQueue,
13+
private readonly channelService: ChannelService,
14+
) {}
1115

1216
async sendMail(fields: BotMailDto) {
13-
const { from, subject, template, to, variables } = fields
17+
const { from, subject, template, to, contactId } = fields
1418

15-
const userId = '1'
19+
const channel = await this.channelService.findOneByContactId(contactId)
1620

17-
const [user] = await db
21+
if (!channel) {
22+
return
23+
}
24+
25+
const [userSetting] = await db
1826
.select()
1927
.from(settings)
20-
.where(eq(settings.userId, userId))
28+
.where(eq(settings.userId, channel.userId))
2129

22-
if (!user) {
30+
if (!userSetting) {
2331
return
2432
}
2533

26-
const { email, password } = user.email
34+
const { email, password } = userSetting.email
2735

2836
await this.sendMailQueue.addJob({
2937
from,
3038
to,
31-
props: variables as any,
39+
props: {} as any,
3240
subject,
3341
template: template as any,
3442
pass: password,

0 commit comments

Comments
 (0)