2
0

fix(webhooks): improve body parsing

This commit is contained in:
Baptiste Arnaud
2022-08-29 07:50:51 +02:00
parent 02bb7f5ea7
commit 43891b06aa

View File

@@ -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 }
} }
} }