⚗️ Implement bot v2 MVP (#194)

Closes #190
This commit is contained in:
Baptiste Arnaud
2022-12-22 17:02:34 +01:00
committed by GitHub
parent e55823e011
commit 1a3869ae6d
202 changed files with 8060 additions and 1152 deletions

View File

@@ -35,37 +35,46 @@ export const executeWebhookBlock = async (
where: { id: block.webhookId },
})) as Webhook | null
if (!webhook) {
await saveErrorLog({
resultId: result.id,
message: `Couldn't find webhook`,
})
result &&
(await saveErrorLog({
resultId: result.id,
message: `Couldn't find webhook`,
}))
return { outgoingEdgeId: block.outgoingEdgeId }
}
const preparedWebhook = prepareWebhookAttributes(webhook, block.options)
const resultValues = await getResultValues(result.id)
const resultValues = result && (await getResultValues(result.id))
if (!resultValues) return { outgoingEdgeId: block.outgoingEdgeId }
const webhookResponse = await executeWebhook({ typebot })(
preparedWebhook,
typebot.variables,
block.groupId,
resultValues,
result.id
result?.id
)
const status = webhookResponse.statusCode.toString()
const isError = status.startsWith('4') || status.startsWith('5')
if (isError) {
await saveErrorLog({
resultId: result.id,
message: `Webhook returned error: ${webhookResponse.data}`,
details: JSON.stringify(webhookResponse.data, null, 2).substring(0, 1000),
})
result &&
(await saveErrorLog({
resultId: result.id,
message: `Webhook returned error: ${webhookResponse.data}`,
details: JSON.stringify(webhookResponse.data, null, 2).substring(
0,
1000
),
}))
} else {
await saveSuccessLog({
resultId: result.id,
message: `Webhook returned success: ${webhookResponse.data}`,
details: JSON.stringify(webhookResponse.data, null, 2).substring(0, 1000),
})
result &&
(await saveSuccessLog({
resultId: result.id,
message: `Webhook returned success: ${webhookResponse.data}`,
details: JSON.stringify(webhookResponse.data, null, 2).substring(
0,
1000
),
}))
}
const newVariables = block.options.responseVariableMapping.reduce<
@@ -265,6 +274,7 @@ const convertKeyValueTableToObject = (
}, {})
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const safeJsonParse = (json: string): { data: any; isJson: boolean } => {
try {
return { data: JSON.parse(json), isJson: true }

View File

@@ -20,29 +20,33 @@ test.describe('Bot', () => {
publicId: `${typebotId}-public`,
})
await createWebhook(typebotId, {
id: 'failing-webhook',
url: 'http://localhost:3001/api/mock/fail',
method: HttpMethod.POST,
})
try {
await createWebhook(typebotId, {
id: 'failing-webhook',
url: 'http://localhost:3001/api/mock/fail',
method: HttpMethod.POST,
})
await createWebhook(typebotId, {
id: 'partial-body-webhook',
url: 'http://localhost:3000/api/mock/webhook-easy-config',
method: HttpMethod.POST,
body: `{
await createWebhook(typebotId, {
id: 'partial-body-webhook',
url: 'http://localhost:3000/api/mock/webhook-easy-config',
method: HttpMethod.POST,
body: `{
"name": "{{Name}}",
"age": {{Age}},
"gender": "{{Gender}}"
}`,
})
})
await createWebhook(typebotId, {
id: 'full-body-webhook',
url: 'http://localhost:3000/api/mock/webhook-easy-config',
method: HttpMethod.POST,
body: `{{Full body}}`,
})
await createWebhook(typebotId, {
id: 'full-body-webhook',
url: 'http://localhost:3000/api/mock/webhook-easy-config',
method: HttpMethod.POST,
body: `{{Full body}}`,
})
} catch (err) {
console.log(err)
}
})
test.afterEach(async () => {

View File

@@ -0,0 +1,78 @@
import test, { expect } from '@playwright/test'
import cuid from 'cuid'
import { HttpMethod } from 'models'
import {
createWebhook,
deleteTypebots,
deleteWebhooks,
importTypebotInDatabase,
} from 'utils/playwright/databaseActions'
import { getTestAsset } from '@/test/utils/playwright'
const typebotId = cuid()
test.beforeEach(async () => {
await importTypebotInDatabase(getTestAsset('typebots/webhook.json'), {
id: typebotId,
publicId: `${typebotId}-public`,
})
try {
await createWebhook(typebotId, {
id: 'failing-webhook',
url: 'http://localhost:3001/api/mock/fail',
method: HttpMethod.POST,
})
await createWebhook(typebotId, {
id: 'partial-body-webhook',
url: 'http://localhost:3000/api/mock/webhook-easy-config',
method: HttpMethod.POST,
body: `{
"name": "{{Name}}",
"age": {{Age}},
"gender": "{{Gender}}"
}`,
})
await createWebhook(typebotId, {
id: 'full-body-webhook',
url: 'http://localhost:3000/api/mock/webhook-easy-config',
method: HttpMethod.POST,
body: `{{Full body}}`,
})
} catch (err) {
console.log(err)
}
})
test.afterEach(async () => {
await deleteTypebots([typebotId])
await deleteWebhooks([
'failing-webhook',
'partial-body-webhook',
'full-body-webhook',
])
})
test('should execute webhooks properly', async ({ page }) => {
await page.goto(`/next/${typebotId}-public`)
await page.locator('text=Send failing webhook').click()
await page.locator('[placeholder="Type a name..."]').fill('John')
await page.locator('text="Send"').click()
await page.locator('[placeholder="Type an age..."]').fill('30')
await page.locator('text="Send"').click()
await page.locator('text="Male"').click()
await expect(
page.getByText('{"name":"John","age":25,"gender":"male"}')
).toBeVisible()
await expect(
page.getByText('{"name":"John","age":30,"gender":"Male"}')
).toBeVisible()
await page.goto(`http://localhost:3000/typebots/${typebotId}/results`)
await page.click('text="See logs"')
await expect(
page.locator('text="Webhook successfuly executed." >> nth=1')
).toBeVisible()
await expect(page.locator('text="Webhook returned an error"')).toBeVisible()
})