🐛 (webhook) Fix parent linked typebot data parsing in webhook
This commit is contained in:
@ -1,4 +1,3 @@
|
||||
import { getLinkedTypebots } from '@/features/blocks/logic/typebotLink/api'
|
||||
import { ExecuteIntegrationResponse } from '@/features/chat'
|
||||
import { saveErrorLog, saveSuccessLog } from '@/features/logs/api'
|
||||
import { parseVariables } from '@/features/variables'
|
||||
@ -183,13 +182,12 @@ const getEmailBody = async ({
|
||||
where: { typebotId },
|
||||
})) as unknown as PublicTypebot
|
||||
if (!typebot) return
|
||||
const linkedTypebots = await getLinkedTypebots(typebot)
|
||||
const resultValues = (await prisma.result.findUnique({
|
||||
where: { id: resultId },
|
||||
include: { answers: true },
|
||||
})) as ResultValues | null
|
||||
if (!resultValues) return
|
||||
const answers = parseAnswers(typebot, linkedTypebots)(resultValues)
|
||||
const answers = parseAnswers(typebot, [])(resultValues)
|
||||
return {
|
||||
html: render(
|
||||
<DefaultBotNotificationEmail
|
||||
|
@ -24,7 +24,6 @@ import { stringify } from 'qs'
|
||||
import { byId, omit, parseAnswers } from 'utils'
|
||||
import got, { Method, Headers, HTTPError } from 'got'
|
||||
import { getResultValues } from '@/features/results/api'
|
||||
import { getLinkedTypebots } from '@/features/blocks/logic/typebotLink/api'
|
||||
import { parseSampleResult } from './parseSampleResult'
|
||||
|
||||
export const executeWebhookBlock = async (
|
||||
@ -45,7 +44,7 @@ export const executeWebhookBlock = async (
|
||||
const preparedWebhook = prepareWebhookAttributes(webhook, block.options)
|
||||
const resultValues = await getResultValues(result.id)
|
||||
if (!resultValues) return { outgoingEdgeId: block.outgoingEdgeId }
|
||||
const webhookResponse = await executeWebhook(typebot)(
|
||||
const webhookResponse = await executeWebhook({ typebot })(
|
||||
preparedWebhook,
|
||||
typebot.variables,
|
||||
block.groupId,
|
||||
@ -112,7 +111,7 @@ const prepareWebhookAttributes = (
|
||||
const checkIfBodyIsAVariable = (body: string) => /^{{.+}}$/.test(body)
|
||||
|
||||
export const executeWebhook =
|
||||
(typebot: SessionState['typebot']) =>
|
||||
({ typebot }: Pick<SessionState, 'typebot'>) =>
|
||||
async (
|
||||
webhook: Webhook,
|
||||
variables: Variable[],
|
||||
@ -148,11 +147,10 @@ export const executeWebhook =
|
||||
convertKeyValueTableToObject(webhook.queryParams, variables)
|
||||
)
|
||||
const contentType = headers ? headers['Content-Type'] : undefined
|
||||
const linkedTypebots = await getLinkedTypebots(typebot)
|
||||
|
||||
const bodyContent = await getBodyContent(
|
||||
typebot,
|
||||
linkedTypebots
|
||||
[]
|
||||
)({
|
||||
body: webhook.body,
|
||||
resultValues,
|
||||
|
@ -1,41 +1,20 @@
|
||||
import prisma from '@/lib/prisma'
|
||||
import { canReadTypebots } from '@/utils/api/dbRules'
|
||||
import { User } from 'db'
|
||||
import {
|
||||
LogicBlockType,
|
||||
PublicTypebot,
|
||||
Typebot,
|
||||
TypebotLinkBlock,
|
||||
} from 'models'
|
||||
import { isDefined } from 'utils'
|
||||
import { PublicTypebot, Typebot } from 'models'
|
||||
|
||||
export const getLinkedTypebots = async (
|
||||
typebot: Pick<PublicTypebot, 'groups'>,
|
||||
user?: User
|
||||
): Promise<(Typebot | PublicTypebot)[]> => {
|
||||
const linkedTypebotIds = (
|
||||
typebot.groups
|
||||
.flatMap((g) => g.blocks)
|
||||
.filter(
|
||||
(s) =>
|
||||
s.type === LogicBlockType.TYPEBOT_LINK &&
|
||||
isDefined(s.options.typebotId)
|
||||
) as TypebotLinkBlock[]
|
||||
).map((s) => s.options.typebotId as string)
|
||||
if (linkedTypebotIds.length === 0) return []
|
||||
const typebots = (await ('typebotId' in typebot
|
||||
? prisma.publicTypebot.findMany({
|
||||
where: { id: { in: linkedTypebotIds } },
|
||||
})
|
||||
: prisma.typebot.findMany({
|
||||
where: user
|
||||
? {
|
||||
AND: [
|
||||
{ id: { in: linkedTypebotIds } },
|
||||
canReadTypebots(linkedTypebotIds, user as User),
|
||||
],
|
||||
}
|
||||
: { id: { in: linkedTypebotIds } },
|
||||
}))) as unknown as (Typebot | PublicTypebot)[]
|
||||
return typebots
|
||||
type Props = {
|
||||
isPreview: boolean
|
||||
typebotIds: string[]
|
||||
}
|
||||
|
||||
export const getLinkedTypebots = async ({ isPreview, typebotIds }: Props) => {
|
||||
const linkedTypebots = (
|
||||
isPreview
|
||||
? await prisma.typebot.findMany({
|
||||
where: { id: { in: typebotIds } },
|
||||
})
|
||||
: await prisma.publicTypebot.findMany({
|
||||
where: { id: { in: typebotIds } },
|
||||
})
|
||||
) as (Typebot | PublicTypebot)[]
|
||||
return linkedTypebots
|
||||
}
|
||||
|
@ -0,0 +1,63 @@
|
||||
import prisma from '@/lib/prisma'
|
||||
import { canReadTypebots } from '@/utils/api/dbRules'
|
||||
import { User } from 'db'
|
||||
import {
|
||||
LogicBlockType,
|
||||
PublicTypebot,
|
||||
Typebot,
|
||||
TypebotLinkBlock,
|
||||
} from 'models'
|
||||
import { isDefined } from 'utils'
|
||||
|
||||
type Props = {
|
||||
typebots: Pick<PublicTypebot, 'groups'>[]
|
||||
user?: User
|
||||
isPreview?: boolean
|
||||
}
|
||||
|
||||
export const getLinkedTypebotsChildren =
|
||||
({ typebots, user, isPreview }: Props) =>
|
||||
async (
|
||||
capturedLinkedBots: (Typebot | PublicTypebot)[]
|
||||
): Promise<(Typebot | PublicTypebot)[]> => {
|
||||
const linkedTypebotIds = typebots
|
||||
.flatMap((typebot) =>
|
||||
(
|
||||
typebot.groups
|
||||
.flatMap((group) => group.blocks)
|
||||
.filter(
|
||||
(block) =>
|
||||
block.type === LogicBlockType.TYPEBOT_LINK &&
|
||||
isDefined(block.options.typebotId) &&
|
||||
!capturedLinkedBots.some(
|
||||
(bot) =>
|
||||
('typebotId' in bot ? bot.typebotId : bot.id) ===
|
||||
block.options.typebotId
|
||||
)
|
||||
) as TypebotLinkBlock[]
|
||||
).map((s) => s.options.typebotId)
|
||||
)
|
||||
.filter(isDefined)
|
||||
if (linkedTypebotIds.length === 0) return capturedLinkedBots
|
||||
const linkedTypebots = (
|
||||
isPreview
|
||||
? await prisma.typebot.findMany({
|
||||
where: user
|
||||
? {
|
||||
AND: [
|
||||
{ id: { in: linkedTypebotIds } },
|
||||
canReadTypebots(linkedTypebotIds, user as User),
|
||||
],
|
||||
}
|
||||
: { id: { in: linkedTypebotIds } },
|
||||
})
|
||||
: await prisma.publicTypebot.findMany({
|
||||
where: { id: { in: linkedTypebotIds } },
|
||||
})
|
||||
) as (Typebot | PublicTypebot)[]
|
||||
return getLinkedTypebotsChildren({
|
||||
typebots: linkedTypebots,
|
||||
user,
|
||||
isPreview,
|
||||
})([...capturedLinkedBots, ...linkedTypebots])
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
export * from './executeTypebotLink'
|
||||
export * from './getLinkedTypebots'
|
||||
export * from './getLinkedTypebotsChildren'
|
||||
|
@ -21,7 +21,10 @@ import Cors from 'cors'
|
||||
import prisma from '@/lib/prisma'
|
||||
import { saveErrorLog, saveSuccessLog } from '@/features/logs/api'
|
||||
import { parseSampleResult } from '@/features/blocks/integrations/webhook/api'
|
||||
import { getLinkedTypebots } from '@/features/blocks/logic/typebotLink/api'
|
||||
import {
|
||||
getLinkedTypebots,
|
||||
getLinkedTypebotsChildren,
|
||||
} from '@/features/blocks/logic/typebotLink/api'
|
||||
|
||||
const cors = initMiddleware(Cors())
|
||||
|
||||
@ -31,11 +34,12 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const typebotId = req.query.typebotId as string
|
||||
const blockId = req.query.blockId as string
|
||||
const resultId = req.query.resultId as string | undefined
|
||||
const { resultValues, variables } = (
|
||||
const { resultValues, variables, parentTypebotIds } = (
|
||||
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
|
||||
) as {
|
||||
resultValues: ResultValues | undefined
|
||||
variables: Variable[]
|
||||
parentTypebotIds: string[]
|
||||
}
|
||||
const typebot = (await prisma.typebot.findUnique({
|
||||
where: { id: typebotId },
|
||||
@ -51,13 +55,14 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
.status(404)
|
||||
.send({ statusCode: 404, data: { message: `Couldn't find webhook` } })
|
||||
const preparedWebhook = prepareWebhookAttributes(webhook, block.options)
|
||||
const result = await executeWebhook(typebot)(
|
||||
preparedWebhook,
|
||||
const result = await executeWebhook(typebot)({
|
||||
webhook: preparedWebhook,
|
||||
variables,
|
||||
block.groupId,
|
||||
groupId: block.groupId,
|
||||
resultValues,
|
||||
resultId
|
||||
)
|
||||
resultId,
|
||||
parentTypebotIds,
|
||||
})
|
||||
return res.status(200).send(result)
|
||||
}
|
||||
return methodNotAllowed(res)
|
||||
@ -79,13 +84,21 @@ const checkIfBodyIsAVariable = (body: string) => /^{{.+}}$/.test(body)
|
||||
|
||||
export const executeWebhook =
|
||||
(typebot: Typebot) =>
|
||||
async (
|
||||
webhook: Webhook,
|
||||
variables: Variable[],
|
||||
groupId: string,
|
||||
resultValues?: ResultValues,
|
||||
async ({
|
||||
webhook,
|
||||
variables,
|
||||
groupId,
|
||||
resultValues,
|
||||
resultId,
|
||||
parentTypebotIds = [],
|
||||
}: {
|
||||
webhook: Webhook
|
||||
variables: Variable[]
|
||||
groupId: string
|
||||
resultValues?: ResultValues
|
||||
resultId?: string
|
||||
): Promise<WebhookResponse> => {
|
||||
parentTypebotIds: string[]
|
||||
}): Promise<WebhookResponse> => {
|
||||
if (!webhook.url || !webhook.method)
|
||||
return {
|
||||
statusCode: 400,
|
||||
@ -114,11 +127,18 @@ export const executeWebhook =
|
||||
convertKeyValueTableToObject(webhook.queryParams, variables)
|
||||
)
|
||||
const contentType = headers ? headers['Content-Type'] : undefined
|
||||
const linkedTypebots = await getLinkedTypebots(typebot)
|
||||
const bodyContent = await getBodyContent(
|
||||
typebot,
|
||||
linkedTypebots
|
||||
)({
|
||||
const linkedTypebotsParents = await getLinkedTypebots({
|
||||
isPreview: !('typebotId' in typebot),
|
||||
typebotIds: parentTypebotIds,
|
||||
})
|
||||
const linkedTypebotsChildren = await getLinkedTypebotsChildren({
|
||||
isPreview: !('typebotId' in typebot),
|
||||
typebots: [typebot],
|
||||
})([])
|
||||
const bodyContent = await getBodyContent(typebot, [
|
||||
...linkedTypebotsParents,
|
||||
...linkedTypebotsChildren,
|
||||
])({
|
||||
body: webhook.body,
|
||||
resultValues,
|
||||
groupId,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { authenticateUser } from '@/features/auth/api'
|
||||
import { getLinkedTypebots } from '@/features/blocks/logic/typebotLink/api'
|
||||
import { getLinkedTypebotsChildren } from '@/features/blocks/logic/typebotLink/api'
|
||||
import { parseSampleResult } from '@/features/blocks/integrations/webhook/api'
|
||||
import prisma from '@/lib/prisma'
|
||||
import { Typebot } from 'models'
|
||||
@ -23,7 +23,11 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
.flatMap((g) => g.blocks)
|
||||
.find((s) => s.id === blockId)
|
||||
if (!block) return res.status(404).send({ message: 'Group not found' })
|
||||
const linkedTypebots = await getLinkedTypebots(typebot, user)
|
||||
const linkedTypebots = await getLinkedTypebotsChildren({
|
||||
isPreview: true,
|
||||
typebots: [typebot],
|
||||
user,
|
||||
})([])
|
||||
return res.send(
|
||||
await parseSampleResult(typebot, linkedTypebots)(block.groupId)
|
||||
)
|
||||
|
@ -23,11 +23,12 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const groupId = req.query.groupId as string
|
||||
const blockId = req.query.blockId as string
|
||||
const resultId = req.query.resultId as string | undefined
|
||||
const { resultValues, variables } = (
|
||||
const { resultValues, variables, parentTypebotIds } = (
|
||||
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
|
||||
) as {
|
||||
resultValues: ResultValues
|
||||
variables: Variable[]
|
||||
parentTypebotIds: string[]
|
||||
}
|
||||
const typebot = (await prisma.typebot.findUnique({
|
||||
where: { id: typebotId },
|
||||
@ -43,13 +44,14 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
.status(404)
|
||||
.send({ statusCode: 404, data: { message: `Couldn't find webhook` } })
|
||||
const preparedWebhook = prepareWebhookAttributes(webhook, block.options)
|
||||
const result = await executeWebhook(typebot)(
|
||||
preparedWebhook,
|
||||
const result = await executeWebhook(typebot)({
|
||||
webhook: preparedWebhook,
|
||||
variables,
|
||||
groupId,
|
||||
resultValues,
|
||||
resultId
|
||||
)
|
||||
resultId,
|
||||
parentTypebotIds,
|
||||
})
|
||||
return res.status(200).send(result)
|
||||
}
|
||||
return methodNotAllowed(res)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { authenticateUser } from '@/features/auth/api'
|
||||
import { getLinkedTypebots } from '@/features/blocks/logic/typebotLink/api'
|
||||
import { getLinkedTypebotsChildren } from '@/features/blocks/logic/typebotLink/api'
|
||||
import { parseSampleResult } from '@/features/blocks/integrations/webhook/api'
|
||||
import prisma from '@/lib/prisma'
|
||||
import { Typebot } from 'models'
|
||||
@ -19,7 +19,11 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
},
|
||||
})) as unknown as Typebot | undefined
|
||||
if (!typebot) return res.status(400).send({ message: 'Typebot not found' })
|
||||
const linkedTypebots = await getLinkedTypebots(typebot, user)
|
||||
const linkedTypebots = await getLinkedTypebotsChildren({
|
||||
isPreview: true,
|
||||
typebots: [typebot],
|
||||
user,
|
||||
})([])
|
||||
return res.send(await parseSampleResult(typebot, linkedTypebots)(groupId))
|
||||
}
|
||||
methodNotAllowed(res)
|
||||
|
@ -15,7 +15,7 @@ import Mail from 'nodemailer/lib/mailer'
|
||||
import { DefaultBotNotificationEmail } from 'emails'
|
||||
import { render } from '@faire/mjml-react/dist/src/utils/render'
|
||||
import prisma from '@/lib/prisma'
|
||||
import { getLinkedTypebots } from '@/features/blocks/logic/typebotLink/api'
|
||||
import { getLinkedTypebotsChildren } from '@/features/blocks/logic/typebotLink/api'
|
||||
|
||||
const cors = initMiddleware(Cors())
|
||||
|
||||
@ -189,7 +189,9 @@ const getEmailBody = async ({
|
||||
where: { typebotId },
|
||||
})) as unknown as PublicTypebot
|
||||
if (!typebot) return
|
||||
const linkedTypebots = await getLinkedTypebots(typebot)
|
||||
const linkedTypebots = await getLinkedTypebotsChildren({
|
||||
typebots: [typebot],
|
||||
})([])
|
||||
const answers = parseAnswers(typebot, linkedTypebots)(resultValues)
|
||||
return {
|
||||
html: render(
|
||||
|
Reference in New Issue
Block a user