This commit is contained in:
2024-11-09 18:44:35 +07:00
parent 2736547b84
commit 95a092cec9
5 changed files with 61 additions and 4 deletions

View File

@@ -30,6 +30,7 @@ services:
- PAYOS_CHECKSUM_KEY=0b82fe148ab98083d471997df5cdd08f3c383013f8bc85e87d7ab1ab4433614e - PAYOS_CHECKSUM_KEY=0b82fe148ab98083d471997df5cdd08f3c383013f8bc85e87d7ab1ab4433614e
- PAYOS_WEBHOOK_URL=https://api.epess.org/v1/payos/webhook - PAYOS_WEBHOOK_URL=https://api.epess.org/v1/payos/webhook
- PAYOS_BASE_URL=https://api-merchant.payos.vn/v2 - PAYOS_BASE_URL=https://api-merchant.payos.vn/v2
- PAYOS_RETURN_URL=https://epess.org/services/<serviceId>/checkout
- MAILU_FROM=no-reply@mail.epess.org - MAILU_FROM=no-reply@mail.epess.org
- MAILU_HOST=10.0.27.1 - MAILU_HOST=10.0.27.1
- MAILU_PORT=25 - MAILU_PORT=25

View File

@@ -7,7 +7,12 @@ import {
} from '@smatch-corp/nestjs-pothos' } from '@smatch-corp/nestjs-pothos'
import { Builder, SchemaContext } from '../Graphql/graphql.builder' import { Builder, SchemaContext } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service' import { PrismaService } from '../Prisma/prisma.service'
import { Message, MessageContextType, MessageType } from '@prisma/client' import {
ChatRoomType,
Message,
MessageContextType,
MessageType,
} from '@prisma/client'
import { DateTimeUtils } from '../common/utils/datetime.utils' import { DateTimeUtils } from '../common/utils/datetime.utils'
import { PubSubEvent } from '../common/pubsub/pubsub-event' import { PubSubEvent } from '../common/pubsub/pubsub-event'
@@ -139,6 +144,25 @@ export class MessageSchema extends PothosSchema {
if (!args.input.sender) { if (!args.input.sender) {
throw new Error('Cannot get sender from context') throw new Error('Cannot get sender from context')
} }
let userIds: string[] = []
// get the recipient if messageContext is CHAT
if (messageContext === MessageContextType.CHAT) {
// get chatRoomId from input
const chatRoomId = args.input.chatRoom?.connect?.id
if (!chatRoomId) {
throw new Error('Cannot get chatRoomId from input')
}
// if chatroom type is SUPPORT, user 1 is mentorId, user 2 is customerId
// query the chatRoom to get the userIds
const chatRoom = await this.prisma.chatRoom.findUnique({
where: {
id: chatRoomId,
},
})
if (chatRoom?.type === ChatRoomType.SUPPORT) {
userIds = [chatRoom.mentorId!, chatRoom.customerId!]
}
}
// check if content is empty // check if content is empty
if (!args.input.content || args.input.content.trim() === '') { if (!args.input.content || args.input.content.trim() === '') {
throw new Error('Content cannot be empty') throw new Error('Content cannot be empty')
@@ -156,6 +180,13 @@ export class MessageSchema extends PothosSchema {
`${PubSubEvent.MESSAGE_SENT}.${message.chatRoomId}`, `${PubSubEvent.MESSAGE_SENT}.${message.chatRoomId}`,
message, message,
) )
// publish to new message subscribers
userIds.forEach((userId: string) => {
ctx.http.pubSub.publish(
`${PubSubEvent.NEW_MESSAGE}.${userId}`,
message,
)
})
return message return message
}, },
}), }),
@@ -176,9 +207,9 @@ export class MessageSchema extends PothosSchema {
const { const {
websocket: { pubSub }, websocket: { pubSub },
} = ctx } = ctx
return pubSub.asyncIterator( return pubSub.asyncIterator([
`${PubSubEvent.MESSAGE_SENT}.${args.chatRoomId}`, `${PubSubEvent.MESSAGE_SENT}.${args.chatRoomId}`,
) as unknown as AsyncIterable<Message> ]) as unknown as AsyncIterable<Message>
}, },
resolve: (payload: Message) => payload, resolve: (payload: Message) => payload,
}), }),

View File

@@ -1,6 +1,9 @@
import { Module } from '@nestjs/common' import { Module } from '@nestjs/common'
import { UserSchema } from './user.schema' import { UserSchema } from './user.schema'
import { MessageModule } from '../Message/message.module'
@Module({ @Module({
imports: [MessageModule],
providers: [UserSchema], providers: [UserSchema],
exports: [UserSchema], exports: [UserSchema],
}) })

View File

@@ -5,17 +5,21 @@ import {
PothosSchema, PothosSchema,
SchemaBuilderToken, SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos' } from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder' import { Builder, SchemaContext } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service' import { PrismaService } from '../Prisma/prisma.service'
import { clerkClient } from '@clerk/express' import { clerkClient } from '@clerk/express'
import { UnauthorizedException } from '@nestjs/common' import { UnauthorizedException } from '@nestjs/common'
import { MailService } from '../Mail/mail.service' import { MailService } from '../Mail/mail.service'
import { MessageSchema } from 'src/Message/message.schema'
import { Message } from '@prisma/client'
import { PubSubEvent } from 'src/common/pubsub/pubsub-event'
@Injectable() @Injectable()
export class UserSchema extends PothosSchema { export class UserSchema extends PothosSchema {
constructor( constructor(
@Inject(SchemaBuilderToken) private readonly builder: Builder, @Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService, private readonly prisma: PrismaService,
private readonly mailService: MailService, private readonly mailService: MailService,
private readonly messageSchema: MessageSchema,
) { ) {
super() super()
} }
@@ -366,5 +370,22 @@ export class UserSchema extends PothosSchema {
}, },
}), }),
})) }))
// Subscription section
this.builder.subscriptionFields((t) => ({
userScopedMessage: t.field({
type: this.messageSchema.message(),
subscribe: async (_, _args, ctx: SchemaContext) => {
if (!ctx.isSubscription) throw new Error('Not allowed')
const {
websocket: { pubSub },
} = ctx
return pubSub.asyncIterator([
`${PubSubEvent.NEW_MESSAGE}.${ctx.websocket.me?.id}`,
]) as unknown as AsyncIterable<Message>
},
resolve: async (payload: Message) => payload,
}),
}))
} }
} }

View File

@@ -1,5 +1,6 @@
export enum PubSubEvent { export enum PubSubEvent {
SERVICE_CREATED = 'SERVICE_CREATED', SERVICE_CREATED = 'SERVICE_CREATED',
MESSAGE_SENT = 'MESSAGE_SENT', MESSAGE_SENT = 'MESSAGE_SENT',
NEW_MESSAGE = 'NEW_MESSAGE',
NOTIFICATION = 'NOTIFICATION', NOTIFICATION = 'NOTIFICATION',
} }