@@ -76,11 +76,40 @@ const nextConfig = {
|
||||
}))
|
||||
)
|
||||
: []
|
||||
).concat({
|
||||
source: '/api/typebots/:typebotId/blocks/:blockId/storage/upload-url',
|
||||
destination:
|
||||
'/api/v1/typebots/:typebotId/blocks/:blockId/storage/upload-url',
|
||||
}),
|
||||
).concat([
|
||||
{
|
||||
source: '/api/typebots/:typebotId/blocks/:blockId/storage/upload-url',
|
||||
destination:
|
||||
'/api/v1/typebots/:typebotId/blocks/:blockId/storage/upload-url',
|
||||
},
|
||||
{
|
||||
source:
|
||||
'/api/typebots/:typebotId/blocks/:blockId/steps/:stepId/sampleResult',
|
||||
destination: `${process.env.NEXTAUTH_URL}/api/v1/typebots/:typebotId/webhookBlocks/:blockId/getResultExample`,
|
||||
},
|
||||
{
|
||||
source: '/api/typebots/:typebotId/blocks/:blockId/sampleResult',
|
||||
destination: `${process.env.NEXTAUTH_URL}/api/v1/typebots/:typebotId/webhookBlocks/:blockId/getResultExample`,
|
||||
},
|
||||
{
|
||||
source:
|
||||
'/api/typebots/:typebotId/blocks/:blockId/steps/:stepId/unsubscribeWebhook',
|
||||
destination: `${process.env.NEXTAUTH_URL}/api/v1/typebots/:typebotId/webhookBlocks/:blockId/unsubscribe`,
|
||||
},
|
||||
{
|
||||
source: '/api/typebots/:typebotId/blocks/:blockId/unsubscribeWebhook',
|
||||
destination: `${process.env.NEXTAUTH_URL}/api/v1/typebots/:typebotId/webhookBlocks/:blockId/unsubscribe`,
|
||||
},
|
||||
{
|
||||
source:
|
||||
'/api/typebots/:typebotId/blocks/:blockId/steps/:stepId/subscribeWebhook',
|
||||
destination: `${process.env.NEXTAUTH_URL}/api/v1/typebots/:typebotId/webhookBlocks/:blockId/subscribe`,
|
||||
},
|
||||
{
|
||||
source: '/api/typebots/:typebotId/blocks/:blockId/subscribeWebhook',
|
||||
destination: `${process.env.NEXTAUTH_URL}/api/v1/typebots/:typebotId/webhookBlocks/:blockId/subscribe`,
|
||||
},
|
||||
]),
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
WebhookResponse,
|
||||
WebhookOptions,
|
||||
defaultWebhookAttributes,
|
||||
HttpMethod,
|
||||
PublicTypebot,
|
||||
KeyValue,
|
||||
ReplyLog,
|
||||
@@ -26,6 +25,7 @@ import { parseSampleResult } from './parseSampleResult'
|
||||
import { ExecuteIntegrationResponse } from '@/features/chat/types'
|
||||
import { parseVariables } from '@/features/variables/parseVariables'
|
||||
import { resumeWebhookExecution } from './resumeWebhookExecution'
|
||||
import { HttpMethod } from '@typebot.io/schemas/features/blocks/integrations/webhook/enums'
|
||||
|
||||
type ParsedWebhook = ExecutableWebhook & {
|
||||
basicAuth: { username?: string; password?: string }
|
||||
@@ -38,9 +38,11 @@ export const executeWebhookBlock = async (
|
||||
): Promise<ExecuteIntegrationResponse> => {
|
||||
const { typebot, result } = state
|
||||
const logs: ReplyLog[] = []
|
||||
const webhook = (await prisma.webhook.findUnique({
|
||||
where: { id: block.webhookId },
|
||||
})) as Webhook | null
|
||||
const webhook =
|
||||
block.options.webhook ??
|
||||
((await prisma.webhook.findUnique({
|
||||
where: { id: block.webhookId },
|
||||
})) as Webhook | null)
|
||||
if (!webhook) {
|
||||
logs.push({
|
||||
status: 'error',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import test, { expect } from '@playwright/test'
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
import { HttpMethod } from '@typebot.io/schemas'
|
||||
import { HttpMethod } from '@typebot.io/schemas/features/blocks/integrations/webhook/enums'
|
||||
import {
|
||||
createWebhook,
|
||||
importTypebotInDatabase,
|
||||
|
||||
@@ -2,13 +2,14 @@ import { getTestAsset } from '@/test/utils/playwright'
|
||||
import test, { expect } from '@playwright/test'
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
import prisma from '@/lib/prisma'
|
||||
import { HttpMethod, SendMessageInput } from '@typebot.io/schemas'
|
||||
import { SendMessageInput } from '@typebot.io/schemas'
|
||||
import {
|
||||
createWebhook,
|
||||
deleteTypebots,
|
||||
deleteWebhooks,
|
||||
importTypebotInDatabase,
|
||||
} from '@typebot.io/lib/playwright/databaseActions'
|
||||
import { HttpMethod } from '@typebot.io/schemas/features/blocks/integrations/webhook/enums'
|
||||
|
||||
test.afterEach(async () => {
|
||||
await deleteWebhooks(['chat-webhook-id'])
|
||||
|
||||
@@ -162,7 +162,7 @@ const App = ({
|
||||
return <NotFoundPage />
|
||||
if (publishedTypebot.typebot.isClosed)
|
||||
return <ErrorPage error={new Error('This bot is now closed')} />
|
||||
return publishedTypebot.version === '3' ? (
|
||||
return publishedTypebot.version ? (
|
||||
<TypebotPageV3
|
||||
url={props.url}
|
||||
typebot={{
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
WebhookOptions,
|
||||
WebhookResponse,
|
||||
WebhookBlock,
|
||||
HttpMethod,
|
||||
} from '@typebot.io/schemas'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import got, { Method, Headers, HTTPError } from 'got'
|
||||
@@ -25,6 +24,7 @@ import { fetchLinkedTypebots } from '@/features/blocks/logic/typebotLink/fetchLi
|
||||
import { getPreviouslyLinkedTypebots } from '@/features/blocks/logic/typebotLink/getPreviouslyLinkedTypebots'
|
||||
import { saveErrorLog } from '@/features/logs/saveErrorLog'
|
||||
import { saveSuccessLog } from '@/features/logs/saveSuccessLog'
|
||||
import { HttpMethod } from '@typebot.io/schemas/features/blocks/integrations/webhook/enums'
|
||||
|
||||
const cors = initMiddleware(Cors())
|
||||
|
||||
@@ -49,7 +49,8 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const block = typebot.groups
|
||||
.flatMap((g) => g.blocks)
|
||||
.find(byId(blockId)) as WebhookBlock
|
||||
const webhook = typebot.webhooks.find(byId(block.webhookId))
|
||||
const webhook =
|
||||
block.options.webhook ?? typebot.webhooks.find(byId(block.webhookId))
|
||||
if (!webhook)
|
||||
return res
|
||||
.status(404)
|
||||
@@ -84,116 +85,131 @@ const checkIfBodyIsAVariable = (body: string) => /^{{.+}}$/.test(body)
|
||||
|
||||
export const executeWebhook =
|
||||
(typebot: Typebot) =>
|
||||
async ({
|
||||
webhook,
|
||||
variables,
|
||||
groupId,
|
||||
resultValues,
|
||||
resultId,
|
||||
parentTypebotIds = [],
|
||||
}: {
|
||||
webhook: Webhook
|
||||
variables: Variable[]
|
||||
groupId: string
|
||||
resultValues?: ResultValues
|
||||
resultId?: string
|
||||
parentTypebotIds: string[]
|
||||
}): Promise<WebhookResponse> => {
|
||||
if (!webhook.url || !webhook.method)
|
||||
return {
|
||||
statusCode: 400,
|
||||
data: { message: `Webhook doesn't have url or method` },
|
||||
}
|
||||
const basicAuth: { username?: string; password?: string } = {}
|
||||
const basicAuthHeaderIdx = webhook.headers.findIndex(
|
||||
(h) =>
|
||||
h.key?.toLowerCase() === 'authorization' &&
|
||||
h.value?.toLowerCase()?.includes('basic')
|
||||
)
|
||||
const isUsernamePasswordBasicAuth =
|
||||
basicAuthHeaderIdx !== -1 &&
|
||||
webhook.headers[basicAuthHeaderIdx].value?.includes(':')
|
||||
if (isUsernamePasswordBasicAuth) {
|
||||
const [username, password] =
|
||||
webhook.headers[basicAuthHeaderIdx].value?.slice(6).split(':') ?? []
|
||||
basicAuth.username = username
|
||||
basicAuth.password = password
|
||||
webhook.headers.splice(basicAuthHeaderIdx, 1)
|
||||
}
|
||||
const headers = convertKeyValueTableToObject(webhook.headers, variables) as
|
||||
| Headers
|
||||
| undefined
|
||||
const queryParams = stringify(
|
||||
convertKeyValueTableToObject(webhook.queryParams, variables)
|
||||
)
|
||||
const contentType = headers ? headers['Content-Type'] : undefined
|
||||
const linkedTypebotsParents = await fetchLinkedTypebots({
|
||||
isPreview: !('typebotId' in typebot),
|
||||
typebotIds: parentTypebotIds,
|
||||
})
|
||||
const linkedTypebotsChildren = await getPreviouslyLinkedTypebots({
|
||||
isPreview: !('typebotId' in typebot),
|
||||
typebots: [typebot],
|
||||
})([])
|
||||
const bodyContent = await getBodyContent(typebot, [
|
||||
...linkedTypebotsParents,
|
||||
...linkedTypebotsChildren,
|
||||
])({
|
||||
body: webhook.body,
|
||||
resultValues,
|
||||
groupId,
|
||||
async ({
|
||||
webhook,
|
||||
variables,
|
||||
})
|
||||
const { data: body, isJson } =
|
||||
bodyContent && webhook.method !== HttpMethod.GET
|
||||
? safeJsonParse(
|
||||
groupId,
|
||||
resultValues,
|
||||
resultId,
|
||||
parentTypebotIds = [],
|
||||
}: {
|
||||
webhook: Webhook
|
||||
variables: Variable[]
|
||||
groupId: string
|
||||
resultValues?: ResultValues
|
||||
resultId?: string
|
||||
parentTypebotIds: string[]
|
||||
}): Promise<WebhookResponse> => {
|
||||
if (!webhook.url || !webhook.method)
|
||||
return {
|
||||
statusCode: 400,
|
||||
data: { message: `Webhook doesn't have url or method` },
|
||||
}
|
||||
const basicAuth: { username?: string; password?: string } = {}
|
||||
const basicAuthHeaderIdx = webhook.headers.findIndex(
|
||||
(h) =>
|
||||
h.key?.toLowerCase() === 'authorization' &&
|
||||
h.value?.toLowerCase()?.includes('basic')
|
||||
)
|
||||
const isUsernamePasswordBasicAuth =
|
||||
basicAuthHeaderIdx !== -1 &&
|
||||
webhook.headers[basicAuthHeaderIdx].value?.includes(':')
|
||||
if (isUsernamePasswordBasicAuth) {
|
||||
const [username, password] =
|
||||
webhook.headers[basicAuthHeaderIdx].value?.slice(6).split(':') ?? []
|
||||
basicAuth.username = username
|
||||
basicAuth.password = password
|
||||
webhook.headers.splice(basicAuthHeaderIdx, 1)
|
||||
}
|
||||
const headers = convertKeyValueTableToObject(webhook.headers, variables) as
|
||||
| Headers
|
||||
| undefined
|
||||
const queryParams = stringify(
|
||||
convertKeyValueTableToObject(webhook.queryParams, variables)
|
||||
)
|
||||
const contentType = headers ? headers['Content-Type'] : undefined
|
||||
const linkedTypebotsParents = await fetchLinkedTypebots({
|
||||
isPreview: !('typebotId' in typebot),
|
||||
typebotIds: parentTypebotIds,
|
||||
})
|
||||
const linkedTypebotsChildren = await getPreviouslyLinkedTypebots({
|
||||
isPreview: !('typebotId' in typebot),
|
||||
typebots: [typebot],
|
||||
})([])
|
||||
const bodyContent = await getBodyContent(typebot, [
|
||||
...linkedTypebotsParents,
|
||||
...linkedTypebotsChildren,
|
||||
])({
|
||||
body: webhook.body,
|
||||
resultValues,
|
||||
groupId,
|
||||
variables,
|
||||
})
|
||||
const { data: body, isJson } =
|
||||
bodyContent && webhook.method !== HttpMethod.GET
|
||||
? safeJsonParse(
|
||||
parseVariables(variables, {
|
||||
escapeForJson: !checkIfBodyIsAVariable(bodyContent),
|
||||
})(bodyContent)
|
||||
)
|
||||
: { data: undefined, isJson: false }
|
||||
: { data: undefined, isJson: false }
|
||||
|
||||
const request = {
|
||||
url: parseVariables(variables)(
|
||||
webhook.url + (queryParams !== '' ? `?${queryParams}` : '')
|
||||
),
|
||||
method: webhook.method as Method,
|
||||
headers,
|
||||
...basicAuth,
|
||||
json:
|
||||
!contentType?.includes('x-www-form-urlencoded') && body && isJson
|
||||
? body
|
||||
: undefined,
|
||||
form:
|
||||
contentType?.includes('x-www-form-urlencoded') && body
|
||||
? body
|
||||
: undefined,
|
||||
body: body && !isJson ? body : undefined,
|
||||
}
|
||||
try {
|
||||
const response = await got(request.url, omit(request, 'url'))
|
||||
await saveSuccessLog({
|
||||
resultId,
|
||||
message: 'Webhook successfuly executed.',
|
||||
details: {
|
||||
statusCode: response.statusCode,
|
||||
request,
|
||||
response: safeJsonParse(response.body).data,
|
||||
},
|
||||
})
|
||||
return {
|
||||
statusCode: response.statusCode,
|
||||
data: safeJsonParse(response.body).data,
|
||||
const request = {
|
||||
url: parseVariables(variables)(
|
||||
webhook.url + (queryParams !== '' ? `?${queryParams}` : '')
|
||||
),
|
||||
method: webhook.method as Method,
|
||||
headers,
|
||||
...basicAuth,
|
||||
json:
|
||||
!contentType?.includes('x-www-form-urlencoded') && body && isJson
|
||||
? body
|
||||
: undefined,
|
||||
form:
|
||||
contentType?.includes('x-www-form-urlencoded') && body
|
||||
? body
|
||||
: undefined,
|
||||
body: body && !isJson ? body : undefined,
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof HTTPError) {
|
||||
const response = {
|
||||
statusCode: error.response.statusCode,
|
||||
data: safeJsonParse(error.response.body as string).data,
|
||||
try {
|
||||
const response = await got(request.url, omit(request, 'url'))
|
||||
await saveSuccessLog({
|
||||
resultId,
|
||||
message: 'Webhook successfuly executed.',
|
||||
details: {
|
||||
statusCode: response.statusCode,
|
||||
request,
|
||||
response: safeJsonParse(response.body).data,
|
||||
},
|
||||
})
|
||||
return {
|
||||
statusCode: response.statusCode,
|
||||
data: safeJsonParse(response.body).data,
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof HTTPError) {
|
||||
const response = {
|
||||
statusCode: error.response.statusCode,
|
||||
data: safeJsonParse(error.response.body as string).data,
|
||||
}
|
||||
await saveErrorLog({
|
||||
resultId,
|
||||
message: 'Webhook returned an error',
|
||||
details: {
|
||||
request,
|
||||
response,
|
||||
},
|
||||
})
|
||||
return response
|
||||
}
|
||||
const response = {
|
||||
statusCode: 500,
|
||||
data: { message: `Error from Typebot server: ${error}` },
|
||||
}
|
||||
console.error(error)
|
||||
await saveErrorLog({
|
||||
resultId,
|
||||
message: 'Webhook returned an error',
|
||||
message: 'Webhook failed to execute',
|
||||
details: {
|
||||
request,
|
||||
response,
|
||||
@@ -201,51 +217,36 @@ export const executeWebhook =
|
||||
})
|
||||
return response
|
||||
}
|
||||
const response = {
|
||||
statusCode: 500,
|
||||
data: { message: `Error from Typebot server: ${error}` },
|
||||
}
|
||||
console.error(error)
|
||||
await saveErrorLog({
|
||||
resultId,
|
||||
message: 'Webhook failed to execute',
|
||||
details: {
|
||||
request,
|
||||
response,
|
||||
},
|
||||
})
|
||||
return response
|
||||
}
|
||||
}
|
||||
|
||||
const getBodyContent =
|
||||
(
|
||||
typebot: Pick<Typebot | PublicTypebot, 'groups' | 'variables' | 'edges'>,
|
||||
linkedTypebots: (Typebot | PublicTypebot)[]
|
||||
) =>
|
||||
async ({
|
||||
body,
|
||||
resultValues,
|
||||
groupId,
|
||||
variables,
|
||||
}: {
|
||||
body?: string | null
|
||||
resultValues?: ResultValues
|
||||
groupId: string
|
||||
variables: Variable[]
|
||||
}): Promise<string | undefined> => {
|
||||
if (!body) return
|
||||
return body === '{{state}}'
|
||||
? JSON.stringify(
|
||||
async ({
|
||||
body,
|
||||
resultValues,
|
||||
groupId,
|
||||
variables,
|
||||
}: {
|
||||
body?: string | null
|
||||
resultValues?: ResultValues
|
||||
groupId: string
|
||||
variables: Variable[]
|
||||
}): Promise<string | undefined> => {
|
||||
if (!body) return
|
||||
return body === '{{state}}'
|
||||
? JSON.stringify(
|
||||
resultValues
|
||||
? parseAnswers(typebot, linkedTypebots)(resultValues)
|
||||
: await parseSampleResult(typebot, linkedTypebots)(
|
||||
groupId,
|
||||
variables
|
||||
)
|
||||
groupId,
|
||||
variables
|
||||
)
|
||||
)
|
||||
: body
|
||||
}
|
||||
: body
|
||||
}
|
||||
|
||||
const convertKeyValueTableToObject = (
|
||||
keyValues: KeyValue[] | undefined,
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
import { authenticateUser } from '@/helpers/authenticateUser'
|
||||
import prisma from '@/lib/prisma'
|
||||
import { Typebot } from '@typebot.io/schemas'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { methodNotAllowed } from '@typebot.io/lib/api'
|
||||
import { getPreviouslyLinkedTypebots } from '@/features/blocks/logic/typebotLink/getPreviouslyLinkedTypebots'
|
||||
import { parseSampleResult } from '@/features/blocks/integrations/webhook/parseSampleResult'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const user = await authenticateUser(req)
|
||||
if (!user) return res.status(401).json({ message: 'Not authenticated' })
|
||||
if (req.method === 'GET') {
|
||||
const typebotId = req.query.typebotId as string
|
||||
const blockId = req.query.blockId as string
|
||||
const typebot = (await prisma.typebot.findFirst({
|
||||
where: {
|
||||
id: typebotId,
|
||||
workspace: { members: { some: { userId: user.id } } },
|
||||
},
|
||||
})) as unknown as Typebot | undefined
|
||||
if (!typebot) return res.status(400).send({ message: 'Typebot not found' })
|
||||
const block = typebot.groups
|
||||
.flatMap((g) => g.blocks)
|
||||
.find((s) => s.id === blockId)
|
||||
if (!block) return res.status(404).send({ message: 'Group not found' })
|
||||
const linkedTypebots = await getPreviouslyLinkedTypebots({
|
||||
isPreview: true,
|
||||
typebots: [typebot],
|
||||
user,
|
||||
})([])
|
||||
return res.send(
|
||||
await parseSampleResult(typebot, linkedTypebots)(block.groupId, [])
|
||||
)
|
||||
}
|
||||
methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
@@ -1,72 +0,0 @@
|
||||
import prisma from '@/lib/prisma'
|
||||
import {
|
||||
defaultWebhookAttributes,
|
||||
ResultValues,
|
||||
Typebot,
|
||||
Variable,
|
||||
Webhook,
|
||||
WebhookOptions,
|
||||
WebhookBlock,
|
||||
} from '@typebot.io/schemas'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { initMiddleware, methodNotAllowed, notFound } from '@typebot.io/lib/api'
|
||||
import { byId } from '@typebot.io/lib'
|
||||
import Cors from 'cors'
|
||||
import { executeWebhook } from '../../executeWebhook'
|
||||
|
||||
const cors = initMiddleware(Cors())
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
await cors(req, res)
|
||||
if (req.method === 'POST') {
|
||||
const typebotId = req.query.typebotId as string
|
||||
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, 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 },
|
||||
include: { webhooks: true },
|
||||
})) as unknown as (Typebot & { webhooks: Webhook[] }) | null
|
||||
if (!typebot) return notFound(res)
|
||||
const block = typebot.groups
|
||||
.find(byId(groupId))
|
||||
?.blocks.find(byId(blockId)) as WebhookBlock
|
||||
const webhook = typebot.webhooks.find(byId(block.webhookId))
|
||||
if (!webhook)
|
||||
return res
|
||||
.status(404)
|
||||
.send({ statusCode: 404, data: { message: `Couldn't find webhook` } })
|
||||
const preparedWebhook = prepareWebhookAttributes(webhook, block.options)
|
||||
const result = await executeWebhook(typebot)({
|
||||
webhook: preparedWebhook,
|
||||
variables,
|
||||
groupId,
|
||||
resultValues,
|
||||
resultId,
|
||||
parentTypebotIds,
|
||||
})
|
||||
return res.status(200).send(result)
|
||||
}
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
const prepareWebhookAttributes = (
|
||||
webhook: Webhook,
|
||||
options: WebhookOptions
|
||||
): Webhook => {
|
||||
if (options.isAdvancedConfig === false) {
|
||||
return { ...webhook, body: '{{state}}', ...defaultWebhookAttributes }
|
||||
} else if (options.isCustomBody === false) {
|
||||
return { ...webhook, body: '{{state}}' }
|
||||
}
|
||||
return webhook
|
||||
}
|
||||
|
||||
export default handler
|
||||
@@ -1,34 +0,0 @@
|
||||
import prisma from '@/lib/prisma'
|
||||
import { Typebot } from '@typebot.io/schemas'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { methodNotAllowed } from '@typebot.io/lib/api'
|
||||
import { parseSampleResult } from '@/features/blocks/integrations/webhook/parseSampleResult'
|
||||
import { getPreviouslyLinkedTypebots } from '@/features/blocks/logic/typebotLink/getPreviouslyLinkedTypebots'
|
||||
import { authenticateUser } from '@/helpers/authenticateUser'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const user = await authenticateUser(req)
|
||||
if (!user) return res.status(401).json({ message: 'Not authenticated' })
|
||||
if (req.method === 'GET') {
|
||||
const typebotId = req.query.typebotId as string
|
||||
const groupId = req.query.groupId as string
|
||||
const typebot = (await prisma.typebot.findFirst({
|
||||
where: {
|
||||
id: typebotId,
|
||||
workspace: { members: { some: { userId: user.id } } },
|
||||
},
|
||||
})) as unknown as Typebot | undefined
|
||||
if (!typebot) return res.status(400).send({ message: 'Typebot not found' })
|
||||
const linkedTypebots = await getPreviouslyLinkedTypebots({
|
||||
isPreview: true,
|
||||
typebots: [typebot],
|
||||
user,
|
||||
})([])
|
||||
return res.send(
|
||||
await parseSampleResult(typebot, linkedTypebots)(groupId, [])
|
||||
)
|
||||
}
|
||||
methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
@@ -1,53 +0,0 @@
|
||||
import { Typebot, WebhookBlock } from '@typebot.io/schemas'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { methodNotAllowed } from '@typebot.io/lib/api'
|
||||
import { byId } from '@typebot.io/lib'
|
||||
import prisma from '@/lib/prisma'
|
||||
import { authenticateUser } from '@/helpers/authenticateUser'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const user = await authenticateUser(req)
|
||||
if (!user) return res.status(401).json({ message: 'Not authenticated' })
|
||||
if (req.method === 'POST') {
|
||||
const body = req.body as Record<string, string>
|
||||
if (!('url' in body))
|
||||
return res.status(403).send({ message: 'url is missing in body' })
|
||||
const { url } = body
|
||||
const typebotId = req.query.typebotId as string
|
||||
const groupId = req.query.groupId as string
|
||||
const blockId = req.query.blockId as string
|
||||
const typebot = (await prisma.typebot.findFirst({
|
||||
where: {
|
||||
id: typebotId,
|
||||
workspace: { members: { some: { userId: user.id } } },
|
||||
},
|
||||
})) as unknown as Typebot | undefined
|
||||
if (!typebot) return res.status(400).send({ message: 'Typebot not found' })
|
||||
try {
|
||||
const { webhookId } = typebot.groups
|
||||
.find(byId(groupId))
|
||||
?.blocks.find(byId(blockId)) as WebhookBlock
|
||||
await prisma.webhook.upsert({
|
||||
where: { id: webhookId },
|
||||
update: { url, body: '{{state}}', method: 'POST' },
|
||||
create: {
|
||||
url,
|
||||
body: '{{state}}',
|
||||
method: 'POST',
|
||||
typebotId,
|
||||
headers: [],
|
||||
queryParams: [],
|
||||
},
|
||||
})
|
||||
|
||||
return res.send({ message: 'success' })
|
||||
} catch (err) {
|
||||
return res
|
||||
.status(400)
|
||||
.send({ message: "blockId doesn't point to a Webhook block" })
|
||||
}
|
||||
}
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
@@ -1,41 +0,0 @@
|
||||
import { Typebot, WebhookBlock } from '@typebot.io/schemas'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { methodNotAllowed } from '@typebot.io/lib/api'
|
||||
import { byId } from '@typebot.io/lib'
|
||||
import { authenticateUser } from '@/helpers/authenticateUser'
|
||||
import prisma from '@/lib/prisma'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const user = await authenticateUser(req)
|
||||
if (!user) return res.status(401).json({ message: 'Not authenticated' })
|
||||
if (req.method === 'POST') {
|
||||
const typebotId = req.query.typebotId as string
|
||||
const groupId = req.query.groupId as string
|
||||
const blockId = req.query.blockId as string
|
||||
const typebot = (await prisma.typebot.findFirst({
|
||||
where: {
|
||||
id: typebotId,
|
||||
workspace: { members: { some: { userId: user.id } } },
|
||||
},
|
||||
})) as unknown as Typebot | undefined
|
||||
if (!typebot) return res.status(400).send({ message: 'Typebot not found' })
|
||||
try {
|
||||
const { webhookId } = typebot.groups
|
||||
.find(byId(groupId))
|
||||
?.blocks.find(byId(blockId)) as WebhookBlock
|
||||
await prisma.webhook.updateMany({
|
||||
where: { id: webhookId },
|
||||
data: { url: null },
|
||||
})
|
||||
|
||||
return res.send({ message: 'success' })
|
||||
} catch (err) {
|
||||
return res
|
||||
.status(400)
|
||||
.send({ message: "blockId doesn't point to a Webhook block" })
|
||||
}
|
||||
}
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
@@ -1,52 +0,0 @@
|
||||
import { authenticateUser } from '@/helpers/authenticateUser'
|
||||
import prisma from '@/lib/prisma'
|
||||
import { Typebot, WebhookBlock } from '@typebot.io/schemas'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { byId } from '@typebot.io/lib'
|
||||
import { methodNotAllowed } from '@typebot.io/lib/api'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const user = await authenticateUser(req)
|
||||
if (!user) return res.status(401).json({ message: 'Not authenticated' })
|
||||
if (req.method === 'POST') {
|
||||
const body = req.body as Record<string, string>
|
||||
if (!('url' in body))
|
||||
return res.status(403).send({ message: 'url is missing in body' })
|
||||
const { url } = body
|
||||
const typebotId = req.query.typebotId as string
|
||||
const blockId = req.query.blockId as string
|
||||
const typebot = (await prisma.typebot.findFirst({
|
||||
where: {
|
||||
id: typebotId,
|
||||
workspace: { members: { some: { userId: user.id } } },
|
||||
},
|
||||
})) as unknown as Typebot | undefined
|
||||
if (!typebot) return res.status(400).send({ message: 'Typebot not found' })
|
||||
try {
|
||||
const { webhookId } = typebot.groups
|
||||
.flatMap((g) => g.blocks)
|
||||
.find(byId(blockId)) as WebhookBlock
|
||||
await prisma.webhook.upsert({
|
||||
where: { id: webhookId },
|
||||
update: { url, body: '{{state}}', method: 'POST' },
|
||||
create: {
|
||||
url,
|
||||
body: '{{state}}',
|
||||
method: 'POST',
|
||||
typebotId,
|
||||
headers: [],
|
||||
queryParams: [],
|
||||
},
|
||||
})
|
||||
|
||||
return res.send({ message: 'success' })
|
||||
} catch (err) {
|
||||
return res
|
||||
.status(400)
|
||||
.send({ message: "groupId doesn't point to a Webhook block" })
|
||||
}
|
||||
}
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
@@ -1,40 +0,0 @@
|
||||
import { authenticateUser } from '@/helpers/authenticateUser'
|
||||
import prisma from '@/lib/prisma'
|
||||
import { Typebot, WebhookBlock } from '@typebot.io/schemas'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { byId } from '@typebot.io/lib'
|
||||
import { methodNotAllowed } from '@typebot.io/lib/api'
|
||||
|
||||
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const user = await authenticateUser(req)
|
||||
if (!user) return res.status(401).json({ message: 'Not authenticated' })
|
||||
if (req.method === 'POST') {
|
||||
const typebotId = req.query.typebotId as string
|
||||
const blockId = req.query.blockId as string
|
||||
const typebot = (await prisma.typebot.findFirst({
|
||||
where: {
|
||||
id: typebotId,
|
||||
workspace: { members: { some: { userId: user.id } } },
|
||||
},
|
||||
})) as unknown as Typebot | undefined
|
||||
if (!typebot) return res.status(400).send({ message: 'Typebot not found' })
|
||||
try {
|
||||
const { webhookId } = typebot.groups
|
||||
.flatMap((g) => g.blocks)
|
||||
.find(byId(blockId)) as WebhookBlock
|
||||
await prisma.webhook.updateMany({
|
||||
where: { id: webhookId },
|
||||
data: { url: null },
|
||||
})
|
||||
|
||||
return res.send({ message: 'success' })
|
||||
} catch (err) {
|
||||
return res
|
||||
.status(400)
|
||||
.send({ message: "groupId doesn't point to a Webhook block" })
|
||||
}
|
||||
}
|
||||
return methodNotAllowed(res)
|
||||
}
|
||||
|
||||
export default handler
|
||||
Reference in New Issue
Block a user