2
0

🚸 (whatsapp) Avoid multiple replies to be sent concurently

Closes #972, closes #1453
This commit is contained in:
Baptiste Arnaud
2024-04-18 09:38:22 +02:00
parent 94539e8ed3
commit 7bec58e745
12 changed files with 84 additions and 21 deletions

View File

@ -5,15 +5,18 @@ import { SessionState } from '@typebot.io/schemas'
type Props = {
id?: string
state: SessionState
isReplying?: boolean
}
export const createSession = ({
id,
state,
isReplying,
}: Props): Prisma.PrismaPromise<any> =>
prisma.chatSession.create({
data: {
id,
state,
isReplying,
},
})

View File

@ -4,7 +4,7 @@ import { sessionStateSchema } from '@typebot.io/schemas'
export const getSession = async (sessionId: string) => {
const session = await prisma.chatSession.findUnique({
where: { id: sessionId },
select: { id: true, state: true, updatedAt: true },
select: { id: true, state: true, updatedAt: true, isReplying: true },
})
if (!session) return null
return { ...session, state: sessionStateSchema.parse(session.state) }

View File

@ -0,0 +1,20 @@
import prisma from '@typebot.io/lib/prisma'
type Props = {
existingSessionId: string | undefined
newSessionId: string
}
export const setChatSessionHasReplying = async ({
existingSessionId,
newSessionId,
}: Props) => {
if (existingSessionId) {
return prisma.chatSession.updateMany({
where: { id: existingSessionId },
data: { isReplying: true },
})
}
return prisma.chatSession.createMany({
data: { id: newSessionId, isReplying: true, state: {} },
})
}

View File

@ -5,15 +5,18 @@ import { SessionState } from '@typebot.io/schemas'
type Props = {
id: string
state: SessionState
isReplying: boolean
}
export const updateSession = ({
id,
state,
isReplying,
}: Props): Prisma.PrismaPromise<any> =>
prisma.chatSession.updateMany({
where: { id },
data: {
state,
isReplying,
},
})

View File

@ -16,7 +16,6 @@ type Props = {
logs: ContinueChatResponse['logs']
clientSideActions: ContinueChatResponse['clientSideActions']
visitedEdges: VisitedEdge[]
forceCreateSession?: boolean
hasCustomEmbedBubble?: boolean
}
@ -25,7 +24,6 @@ export const saveStateToDatabase = async ({
input,
logs,
clientSideActions,
forceCreateSession,
visitedEdges,
hasCustomEmbedBubble,
}: Props) => {
@ -43,13 +41,12 @@ export const saveStateToDatabase = async ({
if (id) {
if (isCompleted && resultId) queries.push(deleteSession(id))
else queries.push(updateSession({ id, state }))
else queries.push(updateSession({ id, state, isReplying: false }))
}
const session =
id && !forceCreateSession
? { state, id }
: await createSession({ id, state })
const session = id
? { state, id }
: await createSession({ id, state, isReplying: false })
if (!resultId) {
if (queries.length > 0) await prisma.$transaction(queries)

View File

@ -13,6 +13,7 @@ import { saveStateToDatabase } from '../saveStateToDatabase'
import prisma from '@typebot.io/lib/prisma'
import { isDefined } from '@typebot.io/lib/utils'
import { Reply } from '../types'
import { setChatSessionHasReplying } from '../queries/setChatSessionHasReplying'
type Props = {
receivedMessage: WhatsAppIncomingMessage
@ -67,6 +68,18 @@ export const resumeWhatsAppFlow = async ({
const session = await getSession(sessionId)
if (session?.isReplying) {
console.log('Is currently replying, skipping...')
return {
message: 'Message received',
}
}
await setChatSessionHasReplying({
existingSessionId: session?.id,
newSessionId: sessionId,
})
const isSessionExpired =
session &&
isDefined(session.state.expiryTimeout) &&
@ -116,7 +129,6 @@ export const resumeWhatsAppFlow = async ({
})
await saveStateToDatabase({
forceCreateSession: !session && isDefined(input),
clientSideActions: [],
input,
logs,