diff --git a/apps/builder/src/features/blocks/integrations/makeCom/components/MakeComSettings.tsx b/apps/builder/src/features/blocks/integrations/makeCom/components/MakeComSettings.tsx index b2e66bafd..7b2f228a1 100644 --- a/apps/builder/src/features/blocks/integrations/makeCom/components/MakeComSettings.tsx +++ b/apps/builder/src/features/blocks/integrations/makeCom/components/MakeComSettings.tsx @@ -1,8 +1,8 @@ import { Alert, AlertIcon, Button, Link, Stack, Text } from '@chakra-ui/react' import { ExternalLinkIcon } from '@/components/icons' -import { MakeComBlock, Webhook } from '@typebot.io/schemas' +import { MakeComBlock, HttpRequest } from '@typebot.io/schemas' import React from 'react' -import { WebhookAdvancedConfigForm } from '../../webhook/components/WebhookAdvancedConfigForm' +import { HttpRequestAdvancedConfigForm } from '../../webhook/components/HttpRequestAdvancedConfigForm' type Props = { block: MakeComBlock @@ -13,7 +13,7 @@ export const MakeComSettings = ({ block: { id: blockId, options }, onOptionsChange, }: Props) => { - const setLocalWebhook = async (newLocalWebhook: Webhook) => { + const setLocalWebhook = async (newLocalWebhook: HttpRequest) => { onOptionsChange({ ...options, webhook: newLocalWebhook, @@ -42,7 +42,7 @@ export const MakeComSettings = ({ )} - { - const setLocalWebhook = async (newLocalWebhook: Webhook) => { + const setLocalWebhook = async (newLocalWebhook: HttpRequest) => { onOptionsChange({ ...options, webhook: newLocalWebhook, @@ -54,7 +54,7 @@ export const PabblyConnectSettings = ({ withVariableButton={false} debounceTimeout={0} /> - ((g) => g.blocks) - .find(byId(blockId)) as WebhookBlock | null + .find(byId(blockId)) as HttpRequestBlock | null if (!webhookBlock || !isWebhookBlock(webhookBlock)) throw new TRPCError({ diff --git a/apps/builder/src/features/blocks/integrations/webhook/api/unsubscribeWebhook.ts b/apps/builder/src/features/blocks/integrations/webhook/api/unsubscribeWebhook.ts index 2aefafc05..cff53f36f 100644 --- a/apps/builder/src/features/blocks/integrations/webhook/api/unsubscribeWebhook.ts +++ b/apps/builder/src/features/blocks/integrations/webhook/api/unsubscribeWebhook.ts @@ -2,7 +2,7 @@ import prisma from '@typebot.io/lib/prisma' import { canWriteTypebots } from '@/helpers/databaseRules' import { authenticatedProcedure } from '@/helpers/server/trpc' import { TRPCError } from '@trpc/server' -import { Block, WebhookBlock, parseGroups } from '@typebot.io/schemas' +import { Block, HttpRequestBlock, parseGroups } from '@typebot.io/schemas' import { byId, isWebhookBlock } from '@typebot.io/lib' import { z } from 'zod' @@ -46,7 +46,7 @@ export const unsubscribeWebhook = authenticatedProcedure const webhookBlock = groups .flatMap((g) => g.blocks) - .find(byId(blockId)) as WebhookBlock | null + .find(byId(blockId)) as HttpRequestBlock | null if (!webhookBlock || !isWebhookBlock(webhookBlock)) throw new TRPCError({ diff --git a/apps/builder/src/features/blocks/integrations/webhook/components/WebhookAdvancedConfigForm.tsx b/apps/builder/src/features/blocks/integrations/webhook/components/HttpRequestAdvancedConfigForm.tsx similarity index 97% rename from apps/builder/src/features/blocks/integrations/webhook/components/WebhookAdvancedConfigForm.tsx rename to apps/builder/src/features/blocks/integrations/webhook/components/HttpRequestAdvancedConfigForm.tsx index 7453803d8..ff51c178a 100644 --- a/apps/builder/src/features/blocks/integrations/webhook/components/WebhookAdvancedConfigForm.tsx +++ b/apps/builder/src/features/blocks/integrations/webhook/components/HttpRequestAdvancedConfigForm.tsx @@ -19,8 +19,8 @@ import { KeyValue, VariableForTest, ResponseVariableMapping, - Webhook, - WebhookBlock, + HttpRequest, + HttpRequestBlock, } from '@typebot.io/schemas' import { useState, useMemo } from 'react' import { executeWebhook } from '../queries/executeWebhookQuery' @@ -41,13 +41,13 @@ import { NumberInput } from '@/components/inputs' type Props = { blockId: string - webhook: Webhook | undefined - options: WebhookBlock['options'] - onWebhookChange: (webhook: Webhook) => void - onOptionsChange: (options: WebhookBlock['options']) => void + webhook: HttpRequest | undefined + options: HttpRequestBlock['options'] + onWebhookChange: (webhook: HttpRequest) => void + onOptionsChange: (options: HttpRequestBlock['options']) => void } -export const WebhookAdvancedConfigForm = ({ +export const HttpRequestAdvancedConfigForm = ({ blockId, webhook, options, diff --git a/apps/builder/src/features/blocks/integrations/webhook/components/WebhookContent.tsx b/apps/builder/src/features/blocks/integrations/webhook/components/HttpRequestContent.tsx similarity index 91% rename from apps/builder/src/features/blocks/integrations/webhook/components/WebhookContent.tsx rename to apps/builder/src/features/blocks/integrations/webhook/components/HttpRequestContent.tsx index c9a28fec0..50b52d36c 100644 --- a/apps/builder/src/features/blocks/integrations/webhook/components/WebhookContent.tsx +++ b/apps/builder/src/features/blocks/integrations/webhook/components/HttpRequestContent.tsx @@ -1,10 +1,10 @@ import { Stack, Text } from '@chakra-ui/react' import { useTypebot } from '@/features/editor/providers/TypebotProvider' -import { WebhookBlock } from '@typebot.io/schemas' +import { HttpRequestBlock } from '@typebot.io/schemas' import { SetVariableLabel } from '@/components/SetVariableLabel' type Props = { - block: WebhookBlock + block: HttpRequestBlock } export const WebhookContent = ({ block: { options } }: Props) => { diff --git a/apps/builder/src/features/blocks/integrations/webhook/components/HttpRequestIcon.tsx b/apps/builder/src/features/blocks/integrations/webhook/components/HttpRequestIcon.tsx new file mode 100644 index 000000000..48bf47d48 --- /dev/null +++ b/apps/builder/src/features/blocks/integrations/webhook/components/HttpRequestIcon.tsx @@ -0,0 +1,5 @@ +import { WebhookIcon } from '@/components/icons' +import { IconProps } from '@chakra-ui/react' +import React from 'react' + +export const HttpRequestIcon = (props: IconProps) => diff --git a/apps/builder/src/features/blocks/integrations/webhook/components/WebhookSettings.tsx b/apps/builder/src/features/blocks/integrations/webhook/components/HttpRequestSettings.tsx similarity index 63% rename from apps/builder/src/features/blocks/integrations/webhook/components/WebhookSettings.tsx rename to apps/builder/src/features/blocks/integrations/webhook/components/HttpRequestSettings.tsx index c8d652a6d..0cc736f8c 100644 --- a/apps/builder/src/features/blocks/integrations/webhook/components/WebhookSettings.tsx +++ b/apps/builder/src/features/blocks/integrations/webhook/components/HttpRequestSettings.tsx @@ -1,19 +1,19 @@ import React from 'react' import { Stack } from '@chakra-ui/react' -import { Webhook, WebhookBlock } from '@typebot.io/schemas' +import { HttpRequest, HttpRequestBlock } from '@typebot.io/schemas' import { TextInput } from '@/components/inputs' -import { WebhookAdvancedConfigForm } from './WebhookAdvancedConfigForm' +import { HttpRequestAdvancedConfigForm } from './HttpRequestAdvancedConfigForm' type Props = { - block: WebhookBlock - onOptionsChange: (options: WebhookBlock['options']) => void + block: HttpRequestBlock + onOptionsChange: (options: HttpRequestBlock['options']) => void } -export const WebhookSettings = ({ +export const HttpRequestSettings = ({ block: { id: blockId, options }, onOptionsChange, }: Props) => { - const setLocalWebhook = async (newLocalWebhook: Webhook) => { + const setLocalWebhook = async (newLocalWebhook: HttpRequest) => { onOptionsChange({ ...options, webhook: newLocalWebhook }) } @@ -24,11 +24,11 @@ export const WebhookSettings = ({ return ( - diff --git a/apps/builder/src/features/blocks/integrations/webhook/queries/executeWebhookQuery.ts b/apps/builder/src/features/blocks/integrations/webhook/queries/executeWebhookQuery.ts index 312759196..0ec6f3971 100644 --- a/apps/builder/src/features/blocks/integrations/webhook/queries/executeWebhookQuery.ts +++ b/apps/builder/src/features/blocks/integrations/webhook/queries/executeWebhookQuery.ts @@ -1,4 +1,4 @@ -import { Variable, WebhookResponse } from '@typebot.io/schemas' +import { Variable, HttpResponse } from '@typebot.io/schemas' import { sendRequest } from '@typebot.io/lib' import { env } from '@typebot.io/env' @@ -7,7 +7,7 @@ export const executeWebhook = ( variables: Variable[], { blockId }: { blockId: string } ) => - sendRequest({ + sendRequest({ url: `${env.NEXT_PUBLIC_VIEWER_URL[0]}/api/typebots/${typebotId}/blocks/${blockId}/executeWebhook`, method: 'POST', body: { diff --git a/apps/builder/src/features/blocks/integrations/zapier/components/ZapierSettings.tsx b/apps/builder/src/features/blocks/integrations/zapier/components/ZapierSettings.tsx index 1f0251bff..91bbfffea 100644 --- a/apps/builder/src/features/blocks/integrations/zapier/components/ZapierSettings.tsx +++ b/apps/builder/src/features/blocks/integrations/zapier/components/ZapierSettings.tsx @@ -1,19 +1,19 @@ import { Alert, AlertIcon, Button, Link, Stack, Text } from '@chakra-ui/react' import { ExternalLinkIcon } from '@/components/icons' -import { Webhook, WebhookBlock, ZapierBlock } from '@typebot.io/schemas' +import { HttpRequest, HttpRequestBlock, ZapierBlock } from '@typebot.io/schemas' import React from 'react' -import { WebhookAdvancedConfigForm } from '../../webhook/components/WebhookAdvancedConfigForm' +import { HttpRequestAdvancedConfigForm } from '../../webhook/components/HttpRequestAdvancedConfigForm' type Props = { block: ZapierBlock - onOptionsChange: (options: WebhookBlock['options']) => void + onOptionsChange: (options: HttpRequestBlock['options']) => void } export const ZapierSettings = ({ block: { id: blockId, options }, onOptionsChange, }: Props) => { - const setLocalWebhook = async (newLocalWebhook: Webhook) => { + const setLocalWebhook = async (newLocalWebhook: HttpRequest) => { onOptionsChange({ ...options, webhook: newLocalWebhook, @@ -43,7 +43,7 @@ export const ZapierSettings = ({ )} - { {t('editor.sidebarBlock.analytics.label')} ) case IntegrationBlockType.WEBHOOK: - return {t('editor.sidebarBlock.webhook.label')} + return HTTP request case IntegrationBlockType.ZAPIER: return {t('editor.sidebarBlock.zapier.label')} case IntegrationBlockType.MAKE_COM: diff --git a/apps/builder/src/features/editor/components/BlocksSideBar.tsx b/apps/builder/src/features/editor/components/BlocksSideBar.tsx index 12f747a6d..0a30cf85c 100644 --- a/apps/builder/src/features/editor/components/BlocksSideBar.tsx +++ b/apps/builder/src/features/editor/components/BlocksSideBar.tsx @@ -30,6 +30,7 @@ import { useDebouncedCallback } from 'use-debounce' const legacyIntegrationBlocks = [ IntegrationBlockType.OPEN_AI, IntegrationBlockType.ZEMANTIC_AI, + IntegrationBlockType.WEBHOOK, ] export const BlocksSideBar = () => { diff --git a/apps/builder/src/features/editor/providers/typebotActions/blocks.ts b/apps/builder/src/features/editor/providers/typebotActions/blocks.ts index 9180fa875..a2d420235 100644 --- a/apps/builder/src/features/editor/providers/typebotActions/blocks.ts +++ b/apps/builder/src/features/editor/providers/typebotActions/blocks.ts @@ -2,7 +2,7 @@ import { Block, Typebot, BlockIndices, - Webhook, + HttpRequest, BlockV6, TypebotV6, } from '@typebot.io/schemas' @@ -26,7 +26,7 @@ export type BlocksActions = { } export type WebhookCallBacks = { - onWebhookBlockCreated: (data: Partial) => void + onWebhookBlockCreated: (data: Partial) => void onWebhookBlockDuplicated: ( existingWebhookId: string, newWebhookId: string diff --git a/apps/builder/src/features/graph/components/nodes/block/BlockNodeContent.tsx b/apps/builder/src/features/graph/components/nodes/block/BlockNodeContent.tsx index 1e2988b54..3420a5719 100644 --- a/apps/builder/src/features/graph/components/nodes/block/BlockNodeContent.tsx +++ b/apps/builder/src/features/graph/components/nodes/block/BlockNodeContent.tsx @@ -21,7 +21,7 @@ import { GoogleSheetsNodeContent } from '@/features/blocks/integrations/googleSh import { MakeComContent } from '@/features/blocks/integrations/makeCom/components/MakeComContent' import { PabblyConnectContent } from '@/features/blocks/integrations/pabbly/components/PabblyConnectContent' import { SendEmailContent } from '@/features/blocks/integrations/sendEmail/components/SendEmailContent' -import { WebhookContent } from '@/features/blocks/integrations/webhook/components/WebhookContent' +import { WebhookContent } from '@/features/blocks/integrations/webhook/components/HttpRequestContent' import { ZapierContent } from '@/features/blocks/integrations/zapier/components/ZapierContent' import { RedirectNodeContent } from '@/features/blocks/logic/redirect/components/RedirectNodeContent' import { SetVariableContent } from '@/features/blocks/logic/setVariable/components/SetVariableContent' diff --git a/apps/builder/src/features/graph/components/nodes/block/SettingsPopoverContent.tsx b/apps/builder/src/features/graph/components/nodes/block/SettingsPopoverContent.tsx index 700836d91..f27bf33da 100644 --- a/apps/builder/src/features/graph/components/nodes/block/SettingsPopoverContent.tsx +++ b/apps/builder/src/features/graph/components/nodes/block/SettingsPopoverContent.tsx @@ -23,7 +23,7 @@ import { RatingInputSettings } from '@/features/blocks/inputs/rating/components/ import { TextInputSettings } from '@/features/blocks/inputs/textInput/components/TextInputSettings' import { GoogleAnalyticsSettings } from '@/features/blocks/integrations/googleAnalytics/components/GoogleAnalyticsSettings' import { SendEmailSettings } from '@/features/blocks/integrations/sendEmail/components/SendEmailSettings' -import { WebhookSettings } from '@/features/blocks/integrations/webhook/components/WebhookSettings' +import { HttpRequestSettings } from '@/features/blocks/integrations/webhook/components/HttpRequestSettings' import { ZapierSettings } from '@/features/blocks/integrations/zapier/components/ZapierSettings' import { RedirectSettings } from '@/features/blocks/logic/redirect/components/RedirectSettings' import { SetVariableSettings } from '@/features/blocks/logic/setVariable/components/SetVariableSettings' @@ -288,7 +288,9 @@ export const BlockSettings = ({ ) } case IntegrationBlockType.WEBHOOK: { - return + return ( + + ) } case IntegrationBlockType.EMAIL: { return ( diff --git a/apps/docs/editor/blocks/integrations/webhook.mdx b/apps/docs/editor/blocks/integrations/webhook.mdx index 3e0a0dde6..8e55c7e59 100644 --- a/apps/docs/editor/blocks/integrations/webhook.mdx +++ b/apps/docs/editor/blocks/integrations/webhook.mdx @@ -1,34 +1,16 @@ --- -title: Webhook / API Request +title: HTTP Request --- import { LoomVideo } from '/snippets/loom-video.mdx' -The Webhook block allows you to either: - -- Call a Webhook URL of a 3rd party service to send information from the bot. -- Make an API request to a 3rd party service to fetch information and use it in the bot. - -## Call a Webhook URL - -Your 3rd party service (Make.com, Zapier, etc) is giving you a Webhook URL. - -You only have to paste this URL in the Webhook block and click on "Test the request". By default the 3rd party service will receive a snapshot of what the bot could send. - - - Simple Webhook POST - - -You can also decide to customize the request sent to the 3rd party service. +The HTTP Request block allows you to send an HTTP request to a 3rd party service. This is useful to send information from the bot to another service or to fetch information from another service and use it in the bot. ## Make an API request and fetch data This gets more technical as you'll need to know more about HTTP request parameters. -Lots of services offer an API. They also, most likely have an API documentation. Depending on the parameters you are giving the Webhook block, it should return different info from the 3rd party service. +Lots of services offer an API. They also, most likely have an API documentation. Depending on the parameters you are giving the HTTP request block, it should return different info from the 3rd party service. ## Custom body @@ -43,9 +25,9 @@ You can set a custom body with your collected variables. Here is a working examp ### Example with a dummy API: CREATE and GET -This video provides a step-by-step guide to successfully configure webhook blocks in Typebot. +This video provides a step-by-step guide to successfully configure HTTP request blocks in Typebot. -I demonstrate how to configure the webhook block, including the URL, method, and custom body. I also show you how to test the webhook call and save the newly created employee ID. Finally, I explain how to implement the find employee by ID endpoint and map the employee name to a variable. +I demonstrate how to configure the HTTP request block, including the URL, method, and custom body. I also show you how to test the request and save the newly created employee ID. Finally, I explain how to implement the find employee by ID endpoint and map the employee name to a variable. @@ -92,6 +74,21 @@ Possibilities are endless when it comes to API calls, you can litteraly call any Feel free to ask the [community](https://typebot.io/discord) for help if you struggle setting up a Webhook block. +## Call a Webhook URL + +Your 3rd party service (Make.com, Zapier, etc) is giving you a Webhook URL. + +You only have to paste this URL in the Webhook block and click on "Test the request". By default the 3rd party service will receive a snapshot of what the bot could send. + + + Simple Webhook POST + + +You can also decide to customize the request sent to the 3rd party service. + ## Timeout By default, the Webhook block will wait 10 seconds for the 3rd party service to respond. If it doesn't respond in time, the block will fail. You can customize this timeout value in the "Advanced params" section of your Webhook block settings. diff --git a/apps/docs/openapi/builder.json b/apps/docs/openapi/builder.json index 12d376ea6..045c4ed62 100644 --- a/apps/docs/openapi/builder.json +++ b/apps/docs/openapi/builder.json @@ -1977,7 +1977,8 @@ "type": "string", "enum": [ "Webhook" - ] + ], + "description": "Legacy name for HTTP Request block" }, "options": { "type": "object", @@ -6372,7 +6373,8 @@ "type": "string", "enum": [ "Webhook" - ] + ], + "description": "Legacy name for HTTP Request block" }, "options": { "type": "object", @@ -9818,7 +9820,8 @@ "type": "string", "enum": [ "Webhook" - ] + ], + "description": "Legacy name for HTTP Request block" }, "options": { "type": "object", @@ -18269,7 +18272,8 @@ "type": "string", "enum": [ "Webhook" - ] + ], + "description": "Legacy name for HTTP Request block" }, "options": { "type": "object", @@ -21840,7 +21844,8 @@ "type": "string", "enum": [ "Webhook" - ] + ], + "description": "Legacy name for HTTP Request block" }, "options": { "type": "object", @@ -24660,7 +24665,8 @@ "type": "string", "enum": [ "Webhook" - ] + ], + "description": "Legacy name for HTTP Request block" }, "options": { "type": "object", diff --git a/apps/docs/openapi/viewer.json b/apps/docs/openapi/viewer.json index 64c8fcc4e..2adb8c6a4 100644 --- a/apps/docs/openapi/viewer.json +++ b/apps/docs/openapi/viewer.json @@ -5044,7 +5044,8 @@ "type": "string", "enum": [ "Webhook" - ] + ], + "description": "Legacy name for HTTP Request block" }, "options": { "type": "object", @@ -8791,7 +8792,8 @@ "type": "string", "enum": [ "Webhook" - ] + ], + "description": "Legacy name for HTTP Request block" }, "options": { "type": "object", diff --git a/apps/viewer/src/pages/api/typebots/[typebotId]/blocks/[blockId]/executeWebhook.ts b/apps/viewer/src/pages/api/typebots/[typebotId]/blocks/[blockId]/executeWebhook.ts index 7e001b601..090616f55 100644 --- a/apps/viewer/src/pages/api/typebots/[typebotId]/blocks/[blockId]/executeWebhook.ts +++ b/apps/viewer/src/pages/api/typebots/[typebotId]/blocks/[blockId]/executeWebhook.ts @@ -3,8 +3,8 @@ import { ResultValues, Typebot, Variable, - Webhook, - WebhookResponse, + HttpRequest, + HttpResponse, Block, } from '@typebot.io/schemas' import { NextApiRequest, NextApiResponse } from 'next' @@ -58,7 +58,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { const typebot = (await prisma.typebot.findUnique({ where: { id: typebotId }, include: { webhooks: true }, - })) as unknown as (Typebot & { webhooks: Webhook[] }) | null + })) as unknown as (Typebot & { webhooks: HttpRequest[] }) | null if (!typebot) return notFound(res) const block = typebot.groups .flatMap((g) => g.blocks) @@ -106,7 +106,7 @@ export const executeWebhook = isCustomBody, timeout, }: { - webhook: Webhook + webhook: HttpRequest variables: Variable[] groupId: string resultValues?: ResultValues @@ -114,7 +114,7 @@ export const executeWebhook = parentTypebotIds: string[] isCustomBody?: boolean timeout?: number - }): Promise => { + }): Promise => { if (!webhook.url) return { statusCode: 400, diff --git a/apps/viewer/src/pages/api/typebots/[typebotId]/webhookBlocks.ts b/apps/viewer/src/pages/api/typebots/[typebotId]/webhookBlocks.ts index 41571a432..7d1402c65 100644 --- a/apps/viewer/src/pages/api/typebots/[typebotId]/webhookBlocks.ts +++ b/apps/viewer/src/pages/api/typebots/[typebotId]/webhookBlocks.ts @@ -1,6 +1,6 @@ import { authenticateUser } from '@/helpers/authenticateUser' import prisma from '@typebot.io/lib/prisma' -import { Group, WebhookBlock } from '@typebot.io/schemas' +import { Group, HttpRequestBlock } from '@typebot.io/schemas' import { NextApiRequest, NextApiResponse } from 'next' import { isWebhookBlock } from '@typebot.io/lib' import { methodNotAllowed } from '@typebot.io/lib/api' @@ -22,7 +22,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { >((emptyWebhookBlocks, group) => { const blocks = group.blocks.filter((block) => isWebhookBlock(block) - ) as WebhookBlock[] + ) as HttpRequestBlock[] return [ ...emptyWebhookBlocks, ...blocks.map((b) => ({ diff --git a/packages/bot-engine/blocks/integrations/webhook/executeWebhookBlock.ts b/packages/bot-engine/blocks/integrations/webhook/executeWebhookBlock.ts index e5be0ab8f..71dc7f668 100644 --- a/packages/bot-engine/blocks/integrations/webhook/executeWebhookBlock.ts +++ b/packages/bot-engine/blocks/integrations/webhook/executeWebhookBlock.ts @@ -1,15 +1,15 @@ import { - WebhookBlock, + HttpRequestBlock, ZapierBlock, MakeComBlock, PabblyConnectBlock, SessionState, - Webhook, + HttpRequest, Variable, - WebhookResponse, + HttpResponse, KeyValue, ChatLog, - ExecutableWebhook, + ExecutableHttpRequest, AnswerInSessionState, } from '@typebot.io/schemas' import { stringify } from 'qs' @@ -28,7 +28,7 @@ import { import { env } from '@typebot.io/env' import { parseAnswers } from '@typebot.io/lib/results/parseAnswers' -type ParsedWebhook = ExecutableWebhook & { +type ParsedWebhook = ExecutableHttpRequest & { basicAuth: { username?: string; password?: string } isJson: boolean } @@ -48,7 +48,7 @@ type Params = { disableRequestTimeout?: boolean; timeout?: number } export const executeWebhookBlock = async ( state: SessionState, - block: WebhookBlock | ZapierBlock | MakeComBlock | PabblyConnectBlock, + block: HttpRequestBlock | ZapierBlock | MakeComBlock | PabblyConnectBlock, params: Params = {} ): Promise => { const logs: ChatLog[] = [] @@ -57,7 +57,7 @@ export const executeWebhookBlock = async ( ('webhookId' in block ? ((await prisma.webhook.findUnique({ where: { id: block.webhookId }, - })) as Webhook | null) + })) as HttpRequest | null) : null) if (!webhook) return { outgoingEdgeId: block.outgoingEdgeId } const parsedWebhook = await parseWebhookAttributes(state)({ @@ -110,7 +110,7 @@ const parseWebhookAttributes = webhook, isCustomBody, }: { - webhook: Webhook + webhook: HttpRequest isCustomBody?: boolean }): Promise => { if (!webhook.url) return @@ -136,7 +136,7 @@ const parseWebhookAttributes = const headers = convertKeyValueTableToObject( webhook.headers, typebot.variables - ) as ExecutableWebhook['headers'] | undefined + ) as ExecutableHttpRequest['headers'] | undefined const queryParams = stringify( convertKeyValueTableToObject(webhook.queryParams, typebot.variables) ) @@ -172,7 +172,7 @@ export const executeWebhook = async ( webhook: ParsedWebhook, params: Params = {} ): Promise<{ - response: WebhookResponse + response: HttpResponse logs?: ChatLog[] startTimeShouldBeUpdated?: boolean }> => { diff --git a/packages/bot-engine/blocks/integrations/webhook/resumeWebhookExecution.ts b/packages/bot-engine/blocks/integrations/webhook/resumeWebhookExecution.ts index 5acf19125..b850eba84 100644 --- a/packages/bot-engine/blocks/integrations/webhook/resumeWebhookExecution.ts +++ b/packages/bot-engine/blocks/integrations/webhook/resumeWebhookExecution.ts @@ -4,7 +4,7 @@ import { PabblyConnectBlock, ChatLog, VariableWithUnknowValue, - WebhookBlock, + HttpRequestBlock, ZapierBlock, } from '@typebot.io/schemas' import { SessionState } from '@typebot.io/schemas/features/chat/sessionState' @@ -14,7 +14,7 @@ import { updateVariablesInSession } from '@typebot.io/variables/updateVariablesI type Props = { state: SessionState - block: WebhookBlock | ZapierBlock | MakeComBlock | PabblyConnectBlock + block: HttpRequestBlock | ZapierBlock | MakeComBlock | PabblyConnectBlock logs?: ChatLog[] response: { statusCode: number diff --git a/packages/deprecated/bot-engine/src/features/blocks/integrations/webhook/utils/executeWebhookBlock.ts b/packages/deprecated/bot-engine/src/features/blocks/integrations/webhook/utils/executeWebhookBlock.ts index 271991ec8..b8b2af4c9 100644 --- a/packages/deprecated/bot-engine/src/features/blocks/integrations/webhook/utils/executeWebhookBlock.ts +++ b/packages/deprecated/bot-engine/src/features/blocks/integrations/webhook/utils/executeWebhookBlock.ts @@ -1,7 +1,7 @@ import { parseVariables } from '@/features/variables' import { IntegrationState } from '@/types' import { - WebhookBlock, + HttpRequestBlock, ZapierBlock, MakeComBlock, PabblyConnectBlock, @@ -11,7 +11,7 @@ import { stringify } from 'qs' import { sendRequest, byId } from '@typebot.io/lib' export const executeWebhook = async ( - block: WebhookBlock | ZapierBlock | MakeComBlock | PabblyConnectBlock, + block: HttpRequestBlock | ZapierBlock | MakeComBlock | PabblyConnectBlock, { blockId, variables, diff --git a/packages/embeds/js/src/features/blocks/integrations/webhook/executeWebhook.ts b/packages/embeds/js/src/features/blocks/integrations/webhook/executeWebhook.ts index 700e19b6c..292b7b518 100644 --- a/packages/embeds/js/src/features/blocks/integrations/webhook/executeWebhook.ts +++ b/packages/embeds/js/src/features/blocks/integrations/webhook/executeWebhook.ts @@ -1,7 +1,7 @@ -import { ExecutableWebhook } from '@typebot.io/schemas' +import { ExecutableHttpRequest } from '@typebot.io/schemas' export const executeWebhook = async ( - webhookToExecute: ExecutableWebhook + webhookToExecute: ExecutableHttpRequest ): Promise => { const { url, method, body, headers } = webhookToExecute try { diff --git a/packages/lib/migrations/migrateTypebotFromV3ToV4.ts b/packages/lib/migrations/migrateTypebotFromV3ToV4.ts index e475d2d1e..ad75ae0ee 100644 --- a/packages/lib/migrations/migrateTypebotFromV3ToV4.ts +++ b/packages/lib/migrations/migrateTypebotFromV3ToV4.ts @@ -1,10 +1,9 @@ import { Webhook as WebhookFromDb } from '@typebot.io/prisma' import { - Block, BlockV5, PublicTypebotV5, TypebotV5, - Webhook, + HttpRequest, } from '@typebot.io/schemas' import { isWebhookBlock, isDefined } from '../utils' import prisma from '../prisma' @@ -54,9 +53,11 @@ const migrateWebhookBlock = ? { id: webhook.id, url: webhook.url ?? undefined, - method: (webhook.method as Webhook['method']) ?? HttpMethod.POST, - headers: (webhook.headers as Webhook['headers']) ?? [], - queryParams: (webhook.queryParams as Webhook['headers']) ?? [], + method: + (webhook.method as HttpRequest['method']) ?? HttpMethod.POST, + headers: (webhook.headers as HttpRequest['headers']) ?? [], + queryParams: + (webhook.queryParams as HttpRequest['headers']) ?? [], body: webhook.body ?? undefined, } : { diff --git a/packages/lib/playwright/databaseActions.ts b/packages/lib/playwright/databaseActions.ts index 4f433756e..8ea590912 100644 --- a/packages/lib/playwright/databaseActions.ts +++ b/packages/lib/playwright/databaseActions.ts @@ -7,7 +7,7 @@ import { WorkspaceRole, } from '@typebot.io/prisma' import { createId } from '@paralleldrive/cuid2' -import { Typebot, TypebotV6, Webhook } from '@typebot.io/schemas' +import { Typebot, TypebotV6, HttpRequest } from '@typebot.io/schemas' import { readFileSync } from 'fs' import { proWorkspaceId, userId } from './databaseSetup' import { @@ -154,7 +154,7 @@ export const updateUser = (data: Partial) => export const createWebhook = async ( typebotId: string, - webhookProps?: Partial + webhookProps?: Partial ) => { try { await prisma.webhook.delete({ where: { id: 'webhook1' } }) diff --git a/packages/lib/utils.ts b/packages/lib/utils.ts index 2f10ea4df..57da0d088 100644 --- a/packages/lib/utils.ts +++ b/packages/lib/utils.ts @@ -8,7 +8,7 @@ import type { Block, TextInputBlock, TextBubbleBlock, - WebhookBlock, + HttpRequestBlock, ImageBubbleBlock, VideoBubbleBlock, BlockWithOptionsType, @@ -117,7 +117,7 @@ export const isIntegrationBlock = (block: Block): block is IntegrationBlock => ) as any[] ).includes(block.type) -export const isWebhookBlock = (block: Block): block is WebhookBlock => +export const isWebhookBlock = (block: Block): block is HttpRequestBlock => [ IntegrationBlockType.WEBHOOK, IntegrationBlockType.PABBLY_CONNECT, diff --git a/packages/schemas/features/blocks/integrations/makeCom/schema.ts b/packages/schemas/features/blocks/integrations/makeCom/schema.ts index 969499096..8d3fa3c8c 100644 --- a/packages/schemas/features/blocks/integrations/makeCom/schema.ts +++ b/packages/schemas/features/blocks/integrations/makeCom/schema.ts @@ -1,14 +1,14 @@ import { z } from '../../../../zod' import { IntegrationBlockType } from '../constants' -import { webhookBlockSchemas } from '../webhook' +import { httpBlockSchemas } from '../webhook' export const makeComBlockSchemas = { - v5: webhookBlockSchemas.v5.merge( + v5: httpBlockSchemas.v5.merge( z.object({ type: z.enum([IntegrationBlockType.MAKE_COM]), }) ), - v6: webhookBlockSchemas.v6.merge( + v6: httpBlockSchemas.v6.merge( z.object({ type: z.enum([IntegrationBlockType.MAKE_COM]), }) diff --git a/packages/schemas/features/blocks/integrations/pabblyConnect/schema.ts b/packages/schemas/features/blocks/integrations/pabblyConnect/schema.ts index 695c0cf46..c76724e7a 100644 --- a/packages/schemas/features/blocks/integrations/pabblyConnect/schema.ts +++ b/packages/schemas/features/blocks/integrations/pabblyConnect/schema.ts @@ -1,14 +1,14 @@ import { z } from '../../../../zod' import { IntegrationBlockType } from '../constants' -import { webhookBlockSchemas } from '../webhook' +import { httpBlockSchemas } from '../webhook' export const pabblyConnectBlockSchemas = { - v5: webhookBlockSchemas.v5.merge( + v5: httpBlockSchemas.v5.merge( z.object({ type: z.enum([IntegrationBlockType.PABBLY_CONNECT]), }) ), - v6: webhookBlockSchemas.v6.merge( + v6: httpBlockSchemas.v6.merge( z.object({ type: z.enum([IntegrationBlockType.PABBLY_CONNECT]), }) diff --git a/packages/schemas/features/blocks/integrations/schema.ts b/packages/schemas/features/blocks/integrations/schema.ts index 3d3581833..cd4aba8a3 100644 --- a/packages/schemas/features/blocks/integrations/schema.ts +++ b/packages/schemas/features/blocks/integrations/schema.ts @@ -7,7 +7,7 @@ import { pixelBlockSchema } from './pixel/schema' import { sendEmailBlockSchema } from './sendEmail' import { zemanticAiBlockSchema } from './zemanticAi' import { zapierBlockSchemas } from './zapier' -import { webhookBlockSchemas } from './webhook' +import { httpBlockSchemas } from './webhook' import { makeComBlockSchemas } from './makeCom' import { pabblyConnectBlockSchemas } from './pabblyConnect' @@ -20,7 +20,7 @@ export const integrationBlockSchemas = { openAIBlockSchema, pabblyConnectBlockSchemas.v5, sendEmailBlockSchema, - webhookBlockSchemas.v5, + httpBlockSchemas.v5, zapierBlockSchemas.v5, pixelBlockSchema, zemanticAiBlockSchema, @@ -33,7 +33,7 @@ export const integrationBlockSchemas = { openAIBlockSchema, pabblyConnectBlockSchemas.v6, sendEmailBlockSchema, - webhookBlockSchemas.v6, + httpBlockSchemas.v6, zapierBlockSchemas.v6, pixelBlockSchema, zemanticAiBlockSchema, diff --git a/packages/schemas/features/blocks/integrations/webhook/constants.ts b/packages/schemas/features/blocks/integrations/webhook/constants.ts index 8bc208c17..3fe8a269b 100644 --- a/packages/schemas/features/blocks/integrations/webhook/constants.ts +++ b/packages/schemas/features/blocks/integrations/webhook/constants.ts @@ -1,4 +1,4 @@ -import { WebhookBlockV6 } from './schema' +import { HttpRequestBlockV6 } from './schema' export enum HttpMethod { POST = 'POST', @@ -20,7 +20,7 @@ export const defaultWebhookBlockOptions = { isAdvancedConfig: false, isCustomBody: false, isExecutedOnClient: false, -} as const satisfies WebhookBlockV6['options'] +} as const satisfies HttpRequestBlockV6['options'] export const defaultTimeout = 10 export const maxTimeout = 120 diff --git a/packages/schemas/features/blocks/integrations/webhook/schema.ts b/packages/schemas/features/blocks/integrations/webhook/schema.ts index d4c473693..f38365937 100644 --- a/packages/schemas/features/blocks/integrations/webhook/schema.ts +++ b/packages/schemas/features/blocks/integrations/webhook/schema.ts @@ -21,7 +21,7 @@ const keyValueSchema = z.object({ value: z.string().optional(), }) -export const webhookV5Schema = z.object({ +export const httpRequestV5Schema = z.object({ id: z.string(), queryParams: keyValueSchema.array().optional(), headers: keyValueSchema.array().optional(), @@ -30,61 +30,63 @@ export const webhookV5Schema = z.object({ body: z.string().optional(), }) -const webhookSchemas = { - v5: webhookV5Schema, - v6: webhookV5Schema.omit({ +const httpRequestSchemas = { + v5: httpRequestV5Schema, + v6: httpRequestV5Schema.omit({ id: true, }), } -const webhookSchema = z.union([webhookSchemas.v5, webhookSchemas.v6]) +const httpRequestSchema = z.union([ + httpRequestSchemas.v5, + httpRequestSchemas.v6, +]) -export const webhookOptionsV5Schema = z.object({ +export const httpRequestOptionsV5Schema = z.object({ variablesForTest: z.array(variableForTestSchema).optional(), responseVariableMapping: z.array(responseVariableMappingSchema).optional(), isAdvancedConfig: z.boolean().optional(), isCustomBody: z.boolean().optional(), isExecutedOnClient: z.boolean().optional(), - webhook: webhookSchemas.v5.optional(), + webhook: httpRequestSchemas.v5.optional(), timeout: z.number().min(1).max(maxTimeout).optional(), }) -const webhookOptionsSchemas = { - v5: webhookOptionsV5Schema, - v6: webhookOptionsV5Schema.merge( +const httpRequestOptionsSchemas = { + v5: httpRequestOptionsV5Schema, + v6: httpRequestOptionsV5Schema.merge( z.object({ - webhook: webhookSchemas.v6.optional(), + webhook: httpRequestSchemas.v6.optional(), }) ), } -const webhookBlockV5Schema = blockBaseSchema.merge( +const httpBlockV5Schema = blockBaseSchema.merge( z.object({ - type: z.enum([IntegrationBlockType.WEBHOOK]), - options: webhookOptionsSchemas.v5.optional(), + type: z + .enum([IntegrationBlockType.WEBHOOK]) + .describe('Legacy name for HTTP Request block'), + options: httpRequestOptionsSchemas.v5.optional(), webhookId: z.string().optional(), }) ) -export const webhookBlockSchemas = { - v5: webhookBlockV5Schema, - v6: webhookBlockV5Schema +export const httpBlockSchemas = { + v5: httpBlockV5Schema, + v6: httpBlockV5Schema .omit({ webhookId: true, }) .merge( z.object({ - options: webhookOptionsSchemas.v6.optional(), + options: httpRequestOptionsSchemas.v6.optional(), }) ), } -const webhookBlockSchema = z.union([ - webhookBlockSchemas.v5, - webhookBlockSchemas.v6, -]) +const httpBlockSchema = z.union([httpBlockSchemas.v5, httpBlockSchemas.v6]) -export const executableWebhookSchema = z.object({ +export const executableHttpRequestSchema = z.object({ url: z.string(), headers: z.record(z.string()).optional(), body: z.unknown().optional(), @@ -93,16 +95,16 @@ export const executableWebhookSchema = z.object({ export type KeyValue = { id: string; key?: string; value?: string } -export type WebhookResponse = { +export type HttpResponse = { statusCode: number data?: unknown } -export type ExecutableWebhook = z.infer +export type ExecutableHttpRequest = z.infer -export type Webhook = z.infer -export type WebhookBlock = z.infer -export type WebhookBlockV6 = z.infer +export type HttpRequest = z.infer +export type HttpRequestBlock = z.infer +export type HttpRequestBlockV6 = z.infer export type ResponseVariableMapping = z.infer< typeof responseVariableMappingSchema > diff --git a/packages/schemas/features/blocks/integrations/zapier/schema.ts b/packages/schemas/features/blocks/integrations/zapier/schema.ts index 61d14de13..1b4c70817 100644 --- a/packages/schemas/features/blocks/integrations/zapier/schema.ts +++ b/packages/schemas/features/blocks/integrations/zapier/schema.ts @@ -1,14 +1,14 @@ import { z } from '../../../../zod' import { IntegrationBlockType } from '../constants' -import { webhookBlockSchemas } from '../webhook' +import { httpBlockSchemas } from '../webhook' export const zapierBlockSchemas = { - v5: webhookBlockSchemas.v5.merge( + v5: httpBlockSchemas.v5.merge( z.object({ type: z.enum([IntegrationBlockType.ZAPIER]), }) ), - v6: webhookBlockSchemas.v6.merge( + v6: httpBlockSchemas.v6.merge( z.object({ type: z.enum([IntegrationBlockType.ZAPIER]), }) diff --git a/packages/schemas/features/chat/clientSideAction.ts b/packages/schemas/features/chat/clientSideAction.ts index 0abb5d337..0964816c4 100644 --- a/packages/schemas/features/chat/clientSideAction.ts +++ b/packages/schemas/features/chat/clientSideAction.ts @@ -3,7 +3,7 @@ import { extendZodWithOpenApi } from 'zod-openapi' import { listVariableValue } from '../typebot/variable' import { googleAnalyticsOptionsSchema, - executableWebhookSchema, + executableHttpRequestSchema, pixelOptionsSchema, redirectOptionsSchema, } from '../blocks' @@ -120,7 +120,7 @@ export const clientSideActionSchema = z.discriminatedUnion('type', [ z .object({ type: z.literal('webhookToExecute'), - webhookToExecute: executableWebhookSchema, + webhookToExecute: executableHttpRequestSchema, }) .merge(clientSideActionBaseSchema) .openapi({