fix(webhooks): improve body parsing
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
import prisma from 'libs/prisma'
|
import prisma from 'libs/prisma'
|
||||||
import {
|
import {
|
||||||
defaultWebhookAttributes,
|
defaultWebhookAttributes,
|
||||||
HttpMethod,
|
|
||||||
KeyValue,
|
KeyValue,
|
||||||
PublicTypebot,
|
PublicTypebot,
|
||||||
ResultValues,
|
ResultValues,
|
||||||
@@ -84,7 +83,7 @@ const prepareWebhookAttributes = (
|
|||||||
return webhook
|
return webhook
|
||||||
}
|
}
|
||||||
|
|
||||||
const bodyIsSingleVariable = (body: string) => /{{.+}}/.test(body)
|
const checkIfBodyIsAVariable = (body: string) => /^{{.+}}$/.test(body)
|
||||||
|
|
||||||
export const executeWebhook =
|
export const executeWebhook =
|
||||||
(typebot: Typebot) =>
|
(typebot: Typebot) =>
|
||||||
@@ -124,17 +123,21 @@ export const executeWebhook =
|
|||||||
)
|
)
|
||||||
const contentType = headers ? headers['Content-Type'] : undefined
|
const contentType = headers ? headers['Content-Type'] : undefined
|
||||||
const linkedTypebots = await getLinkedTypebots(typebot)
|
const linkedTypebots = await getLinkedTypebots(typebot)
|
||||||
const body =
|
const bodyContent = await getBodyContent(
|
||||||
webhook.method !== HttpMethod.GET
|
typebot,
|
||||||
? await getBodyContent(
|
linkedTypebots
|
||||||
typebot,
|
)({
|
||||||
linkedTypebots
|
body: webhook.body,
|
||||||
)({
|
resultValues,
|
||||||
body: webhook.body,
|
groupId,
|
||||||
resultValues,
|
})
|
||||||
groupId,
|
const { data: body, isJson } = bodyContent
|
||||||
})
|
? safeJsonParse(
|
||||||
: undefined
|
parseVariables(variables, {
|
||||||
|
escapeForJson: !checkIfBodyIsAVariable(bodyContent),
|
||||||
|
})(bodyContent)
|
||||||
|
)
|
||||||
|
: { data: undefined, isJson: false }
|
||||||
const request = {
|
const request = {
|
||||||
url: parseVariables(variables)(
|
url: parseVariables(variables)(
|
||||||
webhook.url + (queryParams !== '' ? `?${queryParams}` : '')
|
webhook.url + (queryParams !== '' ? `?${queryParams}` : '')
|
||||||
@@ -143,38 +146,28 @@ export const executeWebhook =
|
|||||||
headers,
|
headers,
|
||||||
...basicAuth,
|
...basicAuth,
|
||||||
json:
|
json:
|
||||||
contentType !== 'x-www-form-urlencoded' && body
|
contentType !== 'x-www-form-urlencoded' && body && isJson
|
||||||
? safeJsonParse(
|
? body
|
||||||
parseVariables(variables, {
|
|
||||||
escapeForJson: !bodyIsSingleVariable(body),
|
|
||||||
})(body)
|
|
||||||
)
|
|
||||||
: undefined,
|
|
||||||
form:
|
|
||||||
contentType === 'x-www-form-urlencoded' && body
|
|
||||||
? safeJsonParse(
|
|
||||||
parseVariables(variables, {
|
|
||||||
escapeForJson: !bodyIsSingleVariable(body),
|
|
||||||
})(body)
|
|
||||||
)
|
|
||||||
: undefined,
|
: undefined,
|
||||||
|
form: contentType === 'x-www-form-urlencoded' && body ? body : undefined,
|
||||||
|
body: body && !isJson ? body : undefined,
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const response = await got(request.url, omit(request, 'url'))
|
const response = await got(request.url, omit(request, 'url'))
|
||||||
await saveSuccessLog(resultId, 'Webhook successfuly executed.', {
|
await saveSuccessLog(resultId, 'Webhook successfuly executed.', {
|
||||||
statusCode: response.statusCode,
|
statusCode: response.statusCode,
|
||||||
request,
|
request,
|
||||||
response: parseBody(response.body),
|
response: safeJsonParse(response.body).data,
|
||||||
})
|
})
|
||||||
return {
|
return {
|
||||||
statusCode: response.statusCode,
|
statusCode: response.statusCode,
|
||||||
data: parseBody(response.body),
|
data: safeJsonParse(response.body).data,
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof HTTPError) {
|
if (error instanceof HTTPError) {
|
||||||
const response = {
|
const response = {
|
||||||
statusCode: error.response.statusCode,
|
statusCode: error.response.statusCode,
|
||||||
data: parseBody(error.response.body as string),
|
data: safeJsonParse(error.response.body as string).data,
|
||||||
}
|
}
|
||||||
await saveErrorLog(resultId, 'Webhook returned an error', {
|
await saveErrorLog(resultId, 'Webhook returned an error', {
|
||||||
request,
|
request,
|
||||||
@@ -228,14 +221,6 @@ const getBodyContent =
|
|||||||
: body
|
: body
|
||||||
}
|
}
|
||||||
|
|
||||||
const parseBody = (body: string) => {
|
|
||||||
try {
|
|
||||||
return JSON.parse(body)
|
|
||||||
} catch (err) {
|
|
||||||
return body
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const convertKeyValueTableToObject = (
|
const convertKeyValueTableToObject = (
|
||||||
keyValues: KeyValue[] | undefined,
|
keyValues: KeyValue[] | undefined,
|
||||||
variables: Variable[]
|
variables: Variable[]
|
||||||
@@ -251,11 +236,11 @@ const convertKeyValueTableToObject = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const safeJsonParse = (json: string): any => {
|
const safeJsonParse = (json: string): { data: any; isJson: boolean } => {
|
||||||
try {
|
try {
|
||||||
return JSON.parse(json)
|
return { data: JSON.parse(json), isJson: true }
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return json
|
return { data: json, isJson: false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user