feat(integration): 🚸 Easy webhook config
This commit is contained in:
@ -6,10 +6,11 @@ import {
|
|||||||
AccordionItem,
|
AccordionItem,
|
||||||
AccordionPanel,
|
AccordionPanel,
|
||||||
Button,
|
Button,
|
||||||
Flex,
|
HStack,
|
||||||
Spinner,
|
Spinner,
|
||||||
Stack,
|
Stack,
|
||||||
useToast,
|
useToast,
|
||||||
|
Text,
|
||||||
} from '@chakra-ui/react'
|
} from '@chakra-ui/react'
|
||||||
import { InputWithVariableButton } from 'components/shared/TextboxWithVariableButton/InputWithVariableButton'
|
import { InputWithVariableButton } from 'components/shared/TextboxWithVariableButton/InputWithVariableButton'
|
||||||
import { useTypebot } from 'contexts/TypebotContext'
|
import { useTypebot } from 'contexts/TypebotContext'
|
||||||
@ -36,6 +37,7 @@ import { VariableForTestInputs } from './VariableForTestInputs'
|
|||||||
import { DataVariableInputs } from './ResponseMappingInputs'
|
import { DataVariableInputs } from './ResponseMappingInputs'
|
||||||
import { byId } from 'utils'
|
import { byId } from 'utils'
|
||||||
import { deepEqual } from 'fast-equals'
|
import { deepEqual } from 'fast-equals'
|
||||||
|
import { SwitchWithLabel } from 'components/shared/SwitchWithLabel'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
step: WebhookStep
|
step: WebhookStep
|
||||||
@ -111,6 +113,12 @@ export const WebhookSettings = ({
|
|||||||
responseVariableMapping: ResponseVariableMapping[]
|
responseVariableMapping: ResponseVariableMapping[]
|
||||||
) => onOptionsChange({ ...options, responseVariableMapping })
|
) => onOptionsChange({ ...options, responseVariableMapping })
|
||||||
|
|
||||||
|
const handleAdvancedConfigChange = (isAdvancedConfig: boolean) =>
|
||||||
|
onOptionsChange({ ...options, isAdvancedConfig })
|
||||||
|
|
||||||
|
const handleBodyFormStateChange = (isCustomBody: boolean) =>
|
||||||
|
onOptionsChange({ ...options, isCustomBody })
|
||||||
|
|
||||||
const handleTestRequestClick = async () => {
|
const handleTestRequestClick = async () => {
|
||||||
if (!typebot || !localWebhook) return
|
if (!typebot || !localWebhook) return
|
||||||
setIsTestResponseLoading(true)
|
setIsTestResponseLoading(true)
|
||||||
@ -139,107 +147,126 @@ export const WebhookSettings = ({
|
|||||||
if (!localWebhook) return <Spinner />
|
if (!localWebhook) return <Spinner />
|
||||||
return (
|
return (
|
||||||
<Stack spacing={4}>
|
<Stack spacing={4}>
|
||||||
|
<InputWithVariableButton
|
||||||
|
placeholder="Your Webhook URL..."
|
||||||
|
initialValue={localWebhook.url ?? ''}
|
||||||
|
onChange={handleUrlChange}
|
||||||
|
/>
|
||||||
|
<SwitchWithLabel
|
||||||
|
id={'easy-config'}
|
||||||
|
label="Advanced configuration"
|
||||||
|
initialValue={options.isAdvancedConfig ?? true}
|
||||||
|
onCheckChange={handleAdvancedConfigChange}
|
||||||
|
/>
|
||||||
|
{(options.isAdvancedConfig ?? true) && (
|
||||||
|
<Stack>
|
||||||
|
<HStack justify="space-between">
|
||||||
|
<Text>Method:</Text>
|
||||||
|
<DropdownList<HttpMethod>
|
||||||
|
currentItem={localWebhook.method as HttpMethod}
|
||||||
|
onItemSelect={handleMethodChange}
|
||||||
|
items={Object.values(HttpMethod)}
|
||||||
|
/>
|
||||||
|
</HStack>
|
||||||
|
<Accordion allowToggle allowMultiple>
|
||||||
|
<AccordionItem>
|
||||||
|
<AccordionButton justifyContent="space-between">
|
||||||
|
Query params
|
||||||
|
<AccordionIcon />
|
||||||
|
</AccordionButton>
|
||||||
|
<AccordionPanel pb={4} as={Stack} spacing="6">
|
||||||
|
<TableList<KeyValue>
|
||||||
|
initialItems={localWebhook.queryParams}
|
||||||
|
onItemsChange={handleQueryParamsChange}
|
||||||
|
Item={QueryParamsInputs}
|
||||||
|
addLabel="Add a param"
|
||||||
|
/>
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
<AccordionItem>
|
||||||
|
<AccordionButton justifyContent="space-between">
|
||||||
|
Headers
|
||||||
|
<AccordionIcon />
|
||||||
|
</AccordionButton>
|
||||||
|
<AccordionPanel pb={4} as={Stack} spacing="6">
|
||||||
|
<TableList<KeyValue>
|
||||||
|
initialItems={localWebhook.headers}
|
||||||
|
onItemsChange={handleHeadersChange}
|
||||||
|
Item={HeadersInputs}
|
||||||
|
addLabel="Add a value"
|
||||||
|
/>
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
<AccordionItem>
|
||||||
|
<AccordionButton justifyContent="space-between">
|
||||||
|
Body
|
||||||
|
<AccordionIcon />
|
||||||
|
</AccordionButton>
|
||||||
|
<AccordionPanel pb={4} as={Stack} spacing="6">
|
||||||
|
<SwitchWithLabel
|
||||||
|
id={'custom-body'}
|
||||||
|
label="Custom body"
|
||||||
|
initialValue={options.isCustomBody ?? true}
|
||||||
|
onCheckChange={handleBodyFormStateChange}
|
||||||
|
/>
|
||||||
|
{(options.isCustomBody ?? true) && (
|
||||||
|
<CodeEditor
|
||||||
|
value={localWebhook.body ?? ''}
|
||||||
|
lang="json"
|
||||||
|
onChange={handleBodyChange}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
<AccordionItem>
|
||||||
|
<AccordionButton justifyContent="space-between">
|
||||||
|
Variable values for test
|
||||||
|
<AccordionIcon />
|
||||||
|
</AccordionButton>
|
||||||
|
<AccordionPanel pb={4} as={Stack} spacing="6">
|
||||||
|
<TableList<VariableForTest>
|
||||||
|
initialItems={
|
||||||
|
options?.variablesForTest ?? { byId: {}, allIds: [] }
|
||||||
|
}
|
||||||
|
onItemsChange={handleVariablesChange}
|
||||||
|
Item={VariableForTestInputs}
|
||||||
|
addLabel="Add an entry"
|
||||||
|
/>
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
</Accordion>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
<Stack>
|
<Stack>
|
||||||
<Flex>
|
<Button
|
||||||
<DropdownList<HttpMethod>
|
onClick={handleTestRequestClick}
|
||||||
currentItem={localWebhook.method as HttpMethod}
|
colorScheme="blue"
|
||||||
onItemSelect={handleMethodChange}
|
isLoading={isTestResponseLoading}
|
||||||
items={Object.values(HttpMethod)}
|
>
|
||||||
/>
|
Test the request
|
||||||
</Flex>
|
</Button>
|
||||||
<InputWithVariableButton
|
{testResponse && (
|
||||||
placeholder="Your Webhook URL..."
|
<CodeEditor isReadOnly lang="json" value={testResponse} />
|
||||||
initialValue={localWebhook.url ?? ''}
|
)}
|
||||||
onChange={handleUrlChange}
|
{(testResponse || options?.responseVariableMapping) && (
|
||||||
/>
|
<Accordion allowToggle allowMultiple>
|
||||||
|
<AccordionItem>
|
||||||
|
<AccordionButton justifyContent="space-between">
|
||||||
|
Save in variables
|
||||||
|
<AccordionIcon />
|
||||||
|
</AccordionButton>
|
||||||
|
<AccordionPanel pb={4} as={Stack} spacing="6">
|
||||||
|
<TableList<ResponseVariableMapping>
|
||||||
|
initialItems={options.responseVariableMapping}
|
||||||
|
onItemsChange={handleResponseMappingChange}
|
||||||
|
Item={ResponseMappingInputs}
|
||||||
|
addLabel="Add an entry"
|
||||||
|
/>
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
</Accordion>
|
||||||
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
<Accordion allowToggle allowMultiple>
|
|
||||||
<AccordionItem>
|
|
||||||
<AccordionButton justifyContent="space-between">
|
|
||||||
Query params
|
|
||||||
<AccordionIcon />
|
|
||||||
</AccordionButton>
|
|
||||||
<AccordionPanel pb={4} as={Stack} spacing="6">
|
|
||||||
<TableList<KeyValue>
|
|
||||||
initialItems={localWebhook.queryParams}
|
|
||||||
onItemsChange={handleQueryParamsChange}
|
|
||||||
Item={QueryParamsInputs}
|
|
||||||
addLabel="Add a param"
|
|
||||||
/>
|
|
||||||
</AccordionPanel>
|
|
||||||
</AccordionItem>
|
|
||||||
<AccordionItem>
|
|
||||||
<AccordionButton justifyContent="space-between">
|
|
||||||
Headers
|
|
||||||
<AccordionIcon />
|
|
||||||
</AccordionButton>
|
|
||||||
<AccordionPanel pb={4} as={Stack} spacing="6">
|
|
||||||
<TableList<KeyValue>
|
|
||||||
initialItems={localWebhook.headers}
|
|
||||||
onItemsChange={handleHeadersChange}
|
|
||||||
Item={HeadersInputs}
|
|
||||||
addLabel="Add a value"
|
|
||||||
/>
|
|
||||||
</AccordionPanel>
|
|
||||||
</AccordionItem>
|
|
||||||
<AccordionItem>
|
|
||||||
<AccordionButton justifyContent="space-between">
|
|
||||||
Body
|
|
||||||
<AccordionIcon />
|
|
||||||
</AccordionButton>
|
|
||||||
<AccordionPanel pb={4} as={Stack} spacing="6">
|
|
||||||
<CodeEditor
|
|
||||||
value={localWebhook.body ?? ''}
|
|
||||||
lang="json"
|
|
||||||
onChange={handleBodyChange}
|
|
||||||
/>
|
|
||||||
</AccordionPanel>
|
|
||||||
</AccordionItem>
|
|
||||||
<AccordionItem>
|
|
||||||
<AccordionButton justifyContent="space-between">
|
|
||||||
Variable values for test
|
|
||||||
<AccordionIcon />
|
|
||||||
</AccordionButton>
|
|
||||||
<AccordionPanel pb={4} as={Stack} spacing="6">
|
|
||||||
<TableList<VariableForTest>
|
|
||||||
initialItems={
|
|
||||||
options?.variablesForTest ?? { byId: {}, allIds: [] }
|
|
||||||
}
|
|
||||||
onItemsChange={handleVariablesChange}
|
|
||||||
Item={VariableForTestInputs}
|
|
||||||
addLabel="Add an entry"
|
|
||||||
/>
|
|
||||||
</AccordionPanel>
|
|
||||||
</AccordionItem>
|
|
||||||
</Accordion>
|
|
||||||
<Button
|
|
||||||
onClick={handleTestRequestClick}
|
|
||||||
colorScheme="blue"
|
|
||||||
isLoading={isTestResponseLoading}
|
|
||||||
>
|
|
||||||
Test the request
|
|
||||||
</Button>
|
|
||||||
{testResponse && (
|
|
||||||
<CodeEditor isReadOnly lang="json" value={testResponse} />
|
|
||||||
)}
|
|
||||||
{(testResponse || options?.responseVariableMapping) && (
|
|
||||||
<Accordion allowToggle allowMultiple>
|
|
||||||
<AccordionItem>
|
|
||||||
<AccordionButton justifyContent="space-between">
|
|
||||||
Save in variables
|
|
||||||
<AccordionIcon />
|
|
||||||
</AccordionButton>
|
|
||||||
<AccordionPanel pb={4} as={Stack} spacing="6">
|
|
||||||
<TableList<ResponseVariableMapping>
|
|
||||||
initialItems={options.responseVariableMapping}
|
|
||||||
onItemsChange={handleResponseMappingChange}
|
|
||||||
Item={ResponseMappingInputs}
|
|
||||||
addLabel="Add an entry"
|
|
||||||
/>
|
|
||||||
</AccordionPanel>
|
|
||||||
</AccordionItem>
|
|
||||||
</Accordion>
|
|
||||||
)}
|
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
13
apps/builder/pages/api/mock/webhook-easy-config.ts
Normal file
13
apps/builder/pages/api/mock/webhook-easy-config.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { withSentry } from '@sentry/nextjs'
|
||||||
|
import { NextApiRequest, NextApiResponse } from 'next'
|
||||||
|
import { methodNotAllowed } from 'utils'
|
||||||
|
|
||||||
|
const handler = (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
|
console.log(req.method)
|
||||||
|
if (req.method === 'POST') {
|
||||||
|
return res.status(200).send(req.body)
|
||||||
|
}
|
||||||
|
return methodNotAllowed(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withSentry(handler)
|
@ -62,7 +62,12 @@
|
|||||||
"id": "soSmiE7zyb3WF77GxFxAjYX",
|
"id": "soSmiE7zyb3WF77GxFxAjYX",
|
||||||
"blockId": "8XnDM1QsqPms4LQHh8q3Jo",
|
"blockId": "8XnDM1QsqPms4LQHh8q3Jo",
|
||||||
"type": "Webhook",
|
"type": "Webhook",
|
||||||
"options": { "responseVariableMapping": [], "variablesForTest": [] },
|
"options": {
|
||||||
|
"responseVariableMapping": [],
|
||||||
|
"variablesForTest": [],
|
||||||
|
"isAdvancedConfig": false,
|
||||||
|
"isCustomBody": false
|
||||||
|
},
|
||||||
"webhookId": "webhook1"
|
"webhookId": "webhook1"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
PublicTypebot,
|
PublicTypebot,
|
||||||
Step,
|
Step,
|
||||||
Typebot,
|
Typebot,
|
||||||
|
Webhook,
|
||||||
} from 'models'
|
} from 'models'
|
||||||
import { CollaborationType, DashboardFolder, PrismaClient, User } from 'db'
|
import { CollaborationType, DashboardFolder, PrismaClient, User } from 'db'
|
||||||
import { readFileSync } from 'fs'
|
import { readFileSync } from 'fs'
|
||||||
@ -19,6 +20,7 @@ export const teardownDatabase = async () => {
|
|||||||
await prisma.user.deleteMany({
|
await prisma.user.deleteMany({
|
||||||
where: { id: { in: ['freeUser', 'proUser'] } },
|
where: { id: { in: ['freeUser', 'proUser'] } },
|
||||||
})
|
})
|
||||||
|
await prisma.webhook.deleteMany()
|
||||||
await prisma.credentials.deleteMany(ownerFilter)
|
await prisma.credentials.deleteMany(ownerFilter)
|
||||||
await prisma.dashboardFolder.deleteMany(ownerFilter)
|
await prisma.dashboardFolder.deleteMany(ownerFilter)
|
||||||
return prisma.typebot.deleteMany(ownerFilter)
|
return prisma.typebot.deleteMany(ownerFilter)
|
||||||
@ -37,8 +39,17 @@ export const createUsers = () =>
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
export const createWebhook = (typebotId: string) =>
|
export const createWebhook = async (
|
||||||
prisma.webhook.create({ data: { method: 'GET', typebotId, id: 'webhook1' } })
|
typebotId: string,
|
||||||
|
webhookProps?: Partial<Webhook>
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
await prisma.webhook.delete({ where: { id: 'webhook1' } })
|
||||||
|
} catch {}
|
||||||
|
return prisma.webhook.create({
|
||||||
|
data: { method: 'GET', typebotId, id: 'webhook1', ...webhookProps },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export const createCollaboration = (
|
export const createCollaboration = (
|
||||||
userId: string,
|
userId: string,
|
||||||
|
@ -2,11 +2,31 @@ import test, { expect, Page } from '@playwright/test'
|
|||||||
import { createWebhook, importTypebotInDatabase } from '../../services/database'
|
import { createWebhook, importTypebotInDatabase } from '../../services/database'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { generate } from 'short-uuid'
|
import { generate } from 'short-uuid'
|
||||||
|
import { HttpMethod } from 'models'
|
||||||
const typebotId = generate()
|
|
||||||
|
|
||||||
test.describe('Webhook step', () => {
|
test.describe('Webhook step', () => {
|
||||||
test('its configuration should work', async ({ page }) => {
|
test('easy configuration should work', async ({ page }) => {
|
||||||
|
const typebotId = generate()
|
||||||
|
await importTypebotInDatabase(
|
||||||
|
path.join(__dirname, '../../fixtures/typebots/integrations/webhook.json'),
|
||||||
|
{
|
||||||
|
id: typebotId,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
await createWebhook(typebotId, { method: HttpMethod.POST })
|
||||||
|
await page.goto(`/typebots/${typebotId}/edit`)
|
||||||
|
await page.click('text=Configure...')
|
||||||
|
await page.fill(
|
||||||
|
'input[placeholder="Your Webhook URL..."]',
|
||||||
|
`${process.env.PLAYWRIGHT_BUILDER_TEST_BASE_URL}/api/mock/webhook-easy-config`
|
||||||
|
)
|
||||||
|
await page.click('text=Test the request')
|
||||||
|
await expect(page.locator('div[role="textbox"] >> nth=-1')).toContainText(
|
||||||
|
'"statusCode": 200'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
test('Generated body should work', async ({ page }) => {
|
||||||
|
const typebotId = generate()
|
||||||
await importTypebotInDatabase(
|
await importTypebotInDatabase(
|
||||||
path.join(__dirname, '../../fixtures/typebots/integrations/webhook.json'),
|
path.join(__dirname, '../../fixtures/typebots/integrations/webhook.json'),
|
||||||
{
|
{
|
||||||
@ -17,12 +37,38 @@ test.describe('Webhook step', () => {
|
|||||||
|
|
||||||
await page.goto(`/typebots/${typebotId}/edit`)
|
await page.goto(`/typebots/${typebotId}/edit`)
|
||||||
await page.click('text=Configure...')
|
await page.click('text=Configure...')
|
||||||
|
await page.fill(
|
||||||
|
'input[placeholder="Your Webhook URL..."]',
|
||||||
|
`${process.env.PLAYWRIGHT_BUILDER_TEST_BASE_URL}/api/mock/webhook-easy-config`
|
||||||
|
)
|
||||||
|
await page.click('text=Advanced configuration')
|
||||||
await page.click('text=GET')
|
await page.click('text=GET')
|
||||||
await page.click('text=POST')
|
await page.click('text=POST')
|
||||||
|
|
||||||
|
await page.click('text=Test the request')
|
||||||
|
await expect(page.locator('div[role="textbox"] >> nth=-1')).toContainText(
|
||||||
|
'"message": "This is a sample result, it has been generated ⬇️"'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
test('its configuration should work', async ({ page }) => {
|
||||||
|
const typebotId = generate()
|
||||||
|
await importTypebotInDatabase(
|
||||||
|
path.join(__dirname, '../../fixtures/typebots/integrations/webhook.json'),
|
||||||
|
{
|
||||||
|
id: typebotId,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
await createWebhook(typebotId)
|
||||||
|
|
||||||
|
await page.goto(`/typebots/${typebotId}/edit`)
|
||||||
|
await page.click('text=Configure...')
|
||||||
await page.fill(
|
await page.fill(
|
||||||
'input[placeholder="Your Webhook URL..."]',
|
'input[placeholder="Your Webhook URL..."]',
|
||||||
`${process.env.PLAYWRIGHT_BUILDER_TEST_BASE_URL}/api/mock/webhook`
|
`${process.env.PLAYWRIGHT_BUILDER_TEST_BASE_URL}/api/mock/webhook`
|
||||||
)
|
)
|
||||||
|
await page.click('text=Advanced configuration')
|
||||||
|
await page.click('text=GET')
|
||||||
|
await page.click('text=POST')
|
||||||
|
|
||||||
await page.click('text=Query params')
|
await page.click('text=Query params')
|
||||||
await page.click('text=Add a param')
|
await page.click('text=Add a param')
|
||||||
@ -45,6 +91,7 @@ test.describe('Webhook step', () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
await page.click('text=Body')
|
await page.click('text=Body')
|
||||||
|
await page.click('text=Custom body')
|
||||||
await page.fill('div[role="textbox"]', '{ "customField": "{{secret 4}}" }')
|
await page.fill('div[role="textbox"]', '{ "customField": "{{secret 4}}" }')
|
||||||
|
|
||||||
await page.click('text=Variable values for test')
|
await page.click('text=Variable values for test')
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import prisma from 'libs/prisma'
|
import prisma from 'libs/prisma'
|
||||||
import {
|
import {
|
||||||
|
defaultWebhookAttributes,
|
||||||
KeyValue,
|
KeyValue,
|
||||||
PublicTypebot,
|
PublicTypebot,
|
||||||
ResultValues,
|
ResultValues,
|
||||||
Typebot,
|
Typebot,
|
||||||
Variable,
|
Variable,
|
||||||
Webhook,
|
Webhook,
|
||||||
|
WebhookOptions,
|
||||||
WebhookResponse,
|
WebhookResponse,
|
||||||
WebhookStep,
|
WebhookStep,
|
||||||
} from 'models'
|
} from 'models'
|
||||||
@ -35,14 +37,17 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||||||
where: { id: typebotId },
|
where: { id: typebotId },
|
||||||
include: { webhooks: true },
|
include: { webhooks: true },
|
||||||
})) as unknown as Typebot & { webhooks: Webhook[] }
|
})) as unknown as Typebot & { webhooks: Webhook[] }
|
||||||
const step = typebot.blocks.find(byId(blockId))?.steps.find(byId(stepId))
|
const step = typebot.blocks
|
||||||
const webhook = typebot.webhooks.find(byId((step as WebhookStep).webhookId))
|
.find(byId(blockId))
|
||||||
|
?.steps.find(byId(stepId)) as WebhookStep
|
||||||
|
const webhook = typebot.webhooks.find(byId(step.webhookId))
|
||||||
if (!webhook)
|
if (!webhook)
|
||||||
return res
|
return res
|
||||||
.status(404)
|
.status(404)
|
||||||
.send({ statusCode: 404, data: { message: `Couldn't find webhook` } })
|
.send({ statusCode: 404, data: { message: `Couldn't find webhook` } })
|
||||||
|
const preparedWebhook = prepareWebhookAttributes(webhook, step.options)
|
||||||
const result = await executeWebhook(typebot)(
|
const result = await executeWebhook(typebot)(
|
||||||
webhook,
|
preparedWebhook,
|
||||||
variables,
|
variables,
|
||||||
blockId,
|
blockId,
|
||||||
resultValues
|
resultValues
|
||||||
@ -52,6 +57,18 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||||||
return methodNotAllowed(res)
|
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
|
||||||
|
}
|
||||||
|
|
||||||
const executeWebhook =
|
const executeWebhook =
|
||||||
(typebot: Typebot) =>
|
(typebot: Typebot) =>
|
||||||
async (
|
async (
|
||||||
|
@ -116,6 +116,8 @@ export type ResponseVariableMapping = {
|
|||||||
export type WebhookOptions = {
|
export type WebhookOptions = {
|
||||||
variablesForTest: VariableForTest[]
|
variablesForTest: VariableForTest[]
|
||||||
responseVariableMapping: ResponseVariableMapping[]
|
responseVariableMapping: ResponseVariableMapping[]
|
||||||
|
isAdvancedConfig?: boolean
|
||||||
|
isCustomBody?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type VariableForTest = {
|
export type VariableForTest = {
|
||||||
@ -131,6 +133,8 @@ export const defaultGoogleAnalyticsOptions: GoogleAnalyticsOptions = {}
|
|||||||
export const defaultWebhookOptions: Omit<WebhookOptions, 'webhookId'> = {
|
export const defaultWebhookOptions: Omit<WebhookOptions, 'webhookId'> = {
|
||||||
responseVariableMapping: [],
|
responseVariableMapping: [],
|
||||||
variablesForTest: [],
|
variablesForTest: [],
|
||||||
|
isAdvancedConfig: false,
|
||||||
|
isCustomBody: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultSendEmailOptions: SendEmailOptions = {
|
export const defaultSendEmailOptions: SendEmailOptions = {
|
||||||
|
@ -32,7 +32,7 @@ export const defaultWebhookAttributes: Omit<
|
|||||||
Webhook,
|
Webhook,
|
||||||
'id' | 'body' | 'url' | 'typebotId'
|
'id' | 'body' | 'url' | 'typebotId'
|
||||||
> = {
|
> = {
|
||||||
method: HttpMethod.GET,
|
method: HttpMethod.POST,
|
||||||
headers: [],
|
headers: [],
|
||||||
queryParams: [],
|
queryParams: [],
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user