feat(integration): ✨ Add webhooks
This commit is contained in:
@ -44,7 +44,7 @@ export default [
|
||||
],
|
||||
},
|
||||
{
|
||||
input: 'dist/esm/types/index.d.ts',
|
||||
input: 'dist/esm/types/src/index.d.ts',
|
||||
output: [{ file: 'dist/index.d.ts', format: 'esm' }],
|
||||
plugins: [dts()],
|
||||
external: [/\.css$/],
|
||||
|
@ -55,6 +55,7 @@ export const ChatBlock = ({
|
||||
}
|
||||
if (isIntegrationStep(currentStep)) {
|
||||
const nextEdgeId = await executeIntegration(
|
||||
typebot.typebotId,
|
||||
currentStep,
|
||||
typebot.variables,
|
||||
updateVariableValue
|
||||
|
@ -1,3 +1,3 @@
|
||||
export * from './components/TypebotViewer'
|
||||
|
||||
export { parseVariables } from './services/variable'
|
||||
export * from 'util'
|
||||
|
@ -10,13 +10,18 @@ import {
|
||||
Cell,
|
||||
GoogleSheetsGetOptions,
|
||||
GoogleAnalyticsStep,
|
||||
Webhook,
|
||||
WebhookStep,
|
||||
} from 'models'
|
||||
import { stringify } from 'qs'
|
||||
import { sendRequest } from 'utils'
|
||||
import { sendGaEvent } from '../../lib/gtag'
|
||||
import { parseVariables, parseVariablesInObject } from './variable'
|
||||
|
||||
const safeEval = eval
|
||||
|
||||
export const executeIntegration = (
|
||||
typebotId: string,
|
||||
step: IntegrationStep,
|
||||
variables: Table<Variable>,
|
||||
updateVariableValue: (variableId: string, value: string) => void
|
||||
@ -26,6 +31,8 @@ export const executeIntegration = (
|
||||
return executeGoogleSheetIntegration(step, variables, updateVariableValue)
|
||||
case IntegrationStepType.GOOGLE_ANALYTICS:
|
||||
return executeGoogleAnalyticsIntegration(step, variables)
|
||||
case IntegrationStepType.WEBHOOK:
|
||||
return executeWebhook(typebotId, step, variables, updateVariableValue)
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,3 +149,26 @@ const parseCellValues = (
|
||||
[cell.column]: parseVariables({ text: cell.value, variables }),
|
||||
}
|
||||
}, {})
|
||||
|
||||
const executeWebhook = async (
|
||||
typebotId: string,
|
||||
step: WebhookStep,
|
||||
variables: Table<Variable>,
|
||||
updateVariableValue: (variableId: string, value: string) => void
|
||||
) => {
|
||||
if (!step.options?.webhookId) return step.edgeId
|
||||
const { data, error } = await sendRequest({
|
||||
url: `http://localhost:3000/api/typebots/${typebotId}/webhooks/${step.options?.webhookId}/execute`,
|
||||
method: 'POST',
|
||||
body: {
|
||||
variables,
|
||||
},
|
||||
})
|
||||
console.error(error)
|
||||
step.options.responseVariableMapping?.allIds.forEach((varMappingId) => {
|
||||
const varMapping = step.options?.responseVariableMapping?.byId[varMappingId]
|
||||
if (!varMapping?.bodyPath || !varMapping.variableId) return
|
||||
const value = safeEval(`(${JSON.stringify(data)}).${varMapping?.bodyPath}`)
|
||||
updateVariableValue(varMapping.variableId, value)
|
||||
})
|
||||
}
|
||||
|
@ -5,12 +5,12 @@
|
||||
"main": "./index.tsx",
|
||||
"types": "./index.tsx",
|
||||
"devDependencies": {
|
||||
"prisma": "^3.7.0",
|
||||
"prisma": "^3.8.1",
|
||||
"ts-node": "^10.4.0",
|
||||
"typescript": "^4.5.4"
|
||||
"typescript": "^4.5.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@prisma/client": "^3.7.0"
|
||||
"@prisma/client": "^3.8.1"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "yarn prisma db push && BROWSER=none yarn prisma studio",
|
||||
|
@ -110,6 +110,7 @@ model Typebot {
|
||||
steps Json
|
||||
choiceItems Json
|
||||
variables Json
|
||||
webhooks Json
|
||||
edges Json
|
||||
theme Json
|
||||
settings Json
|
||||
|
@ -1,15 +1,20 @@
|
||||
import { StepBase } from '.'
|
||||
import { Table } from '../..'
|
||||
|
||||
export type IntegrationStep = GoogleSheetsStep | GoogleAnalyticsStep
|
||||
export type IntegrationStep =
|
||||
| GoogleSheetsStep
|
||||
| GoogleAnalyticsStep
|
||||
| WebhookStep
|
||||
|
||||
export type IntegrationStepOptions =
|
||||
| GoogleSheetsOptions
|
||||
| GoogleAnalyticsOptions
|
||||
| WebhookOptions
|
||||
|
||||
export enum IntegrationStepType {
|
||||
GOOGLE_SHEETS = 'Google Sheets',
|
||||
GOOGLE_ANALYTICS = 'Google Analytics',
|
||||
WEBHOOK = 'Webhook',
|
||||
}
|
||||
|
||||
export type GoogleSheetsStep = StepBase & {
|
||||
@ -22,6 +27,11 @@ export type GoogleAnalyticsStep = StepBase & {
|
||||
options?: GoogleAnalyticsOptions
|
||||
}
|
||||
|
||||
export type WebhookStep = StepBase & {
|
||||
type: IntegrationStepType.WEBHOOK
|
||||
options?: WebhookOptions
|
||||
}
|
||||
|
||||
export type GoogleAnalyticsOptions = {
|
||||
trackingId?: string
|
||||
category?: string
|
||||
@ -66,3 +76,40 @@ export type GoogleSheetsUpdateRowOptions = GoogleSheetsOptionsBase & {
|
||||
referenceCell?: Cell
|
||||
cellsToUpsert?: Table<Cell>
|
||||
}
|
||||
|
||||
export type ResponseVariableMapping = { bodyPath?: string; variableId?: string }
|
||||
|
||||
export type WebhookOptions = {
|
||||
webhookId?: string
|
||||
variablesForTest?: Table<VariableForTest>
|
||||
responseVariableMapping?: Table<ResponseVariableMapping>
|
||||
}
|
||||
|
||||
export enum HttpMethod {
|
||||
POST = 'POST',
|
||||
GET = 'GET',
|
||||
PUT = 'PUT',
|
||||
DELETE = 'DELETE',
|
||||
PATCH = 'PATCH',
|
||||
HEAD = 'HEAD',
|
||||
CONNECT = 'CONNECT',
|
||||
OPTIONS = 'OPTIONS',
|
||||
TRACE = 'TRACE',
|
||||
}
|
||||
|
||||
export type KeyValue = { key?: string; value?: string }
|
||||
export type VariableForTest = { variableId?: string; value?: string }
|
||||
|
||||
export type Webhook = {
|
||||
id: string
|
||||
url?: string
|
||||
method?: HttpMethod
|
||||
queryParams?: Table<KeyValue>
|
||||
headers?: Table<KeyValue>
|
||||
body?: string
|
||||
}
|
||||
|
||||
export type WebhookResponse = {
|
||||
statusCode: number
|
||||
data?: unknown
|
||||
}
|
||||
|
@ -5,16 +5,24 @@ import { Settings } from './settings'
|
||||
import { Step } from './steps/steps'
|
||||
import { Theme } from './theme'
|
||||
import { Variable } from './variable'
|
||||
import { Webhook } from '.'
|
||||
|
||||
export type Typebot = Omit<
|
||||
TypebotFromPrisma,
|
||||
'blocks' | 'theme' | 'settings' | 'steps' | 'choiceItems' | 'variables'
|
||||
| 'blocks'
|
||||
| 'theme'
|
||||
| 'settings'
|
||||
| 'steps'
|
||||
| 'choiceItems'
|
||||
| 'variables'
|
||||
| 'webhooks'
|
||||
> & {
|
||||
blocks: Table<Block>
|
||||
steps: Table<Step>
|
||||
choiceItems: Table<ChoiceItem>
|
||||
variables: Table<Variable>
|
||||
edges: Table<Edge>
|
||||
webhooks: Table<Webhook>
|
||||
theme: Theme
|
||||
settings: Settings
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import {
|
||||
Table,
|
||||
TextInputStep,
|
||||
TextBubbleStep,
|
||||
WebhookStep,
|
||||
} from 'models'
|
||||
|
||||
export const sendRequest = async <ResponseData>({
|
||||
@ -74,3 +75,6 @@ export const isConditionStep = (step: Step): step is ConditionStep =>
|
||||
|
||||
export const isIntegrationStep = (step: Step): step is IntegrationStep =>
|
||||
(Object.values(IntegrationStepType) as string[]).includes(step.type)
|
||||
|
||||
export const isWebhookStep = (step: Step): step is WebhookStep =>
|
||||
step.type === IntegrationStepType.WEBHOOK
|
||||
|
Reference in New Issue
Block a user