diff --git a/apps/viewer/src/features/blocks/integrations/sendEmail/executeSendEmailBlock.tsx b/apps/viewer/src/features/blocks/integrations/sendEmail/executeSendEmailBlock.tsx index 966d555ba25..53cb5a85e61 100644 --- a/apps/viewer/src/features/blocks/integrations/sendEmail/executeSendEmailBlock.tsx +++ b/apps/viewer/src/features/blocks/integrations/sendEmail/executeSendEmailBlock.tsx @@ -41,9 +41,14 @@ export const executeSendEmailBlock = async ( ], } - const body = - findUniqueVariableValue(typebot.variables)(options.body)?.toString() ?? - parseVariables(typebot.variables, { escapeHtml: true })(options.body ?? '') + const bodyUniqueVariable = findUniqueVariableValue(typebot.variables)( + options.body + ) + const body = bodyUniqueVariable + ? stringifyUniqueVariableValueAsHtml(bodyUniqueVariable) + : parseVariables(typebot.variables, { isInsideHtml: true })( + options.body ?? '' + ) try { const sendEmailLogs = await sendEmail({ @@ -258,3 +263,11 @@ const getFileUrls = if (typeof fileUrls === 'string') return fileUrls return fileUrls.filter(isDefined) } + +const stringifyUniqueVariableValueAsHtml = ( + value: Variable['value'] +): string => { + if (!value) return '' + if (typeof value === 'string') return value.replace(/\n/g, '
') + return value.map(stringifyUniqueVariableValueAsHtml).join('
') +} diff --git a/apps/viewer/src/features/blocks/integrations/webhook/executeWebhookBlock.ts b/apps/viewer/src/features/blocks/integrations/webhook/executeWebhookBlock.ts index cc67f282d81..d7b82603064 100644 --- a/apps/viewer/src/features/blocks/integrations/webhook/executeWebhookBlock.ts +++ b/apps/viewer/src/features/blocks/integrations/webhook/executeWebhookBlock.ts @@ -128,7 +128,7 @@ const parseWebhookAttributes = bodyContent && webhook.method !== HttpMethod.GET ? safeJsonParse( parseVariables(typebot.variables, { - escapeForJson: !checkIfBodyIsAVariable(bodyContent), + isInsideJson: !checkIfBodyIsAVariable(bodyContent), })(bodyContent) ) : { data: undefined, isJson: false } diff --git a/apps/viewer/src/features/variables/parseVariables.ts b/apps/viewer/src/features/variables/parseVariables.ts index 964780a6469..612ec89e352 100644 --- a/apps/viewer/src/features/variables/parseVariables.ts +++ b/apps/viewer/src/features/variables/parseVariables.ts @@ -4,16 +4,16 @@ import { safeStringify } from '@typebot.io/lib/safeStringify' export type ParseVariablesOptions = { fieldToParse?: 'value' | 'id' - escapeForJson?: boolean + isInsideJson?: boolean takeLatestIfList?: boolean - escapeHtml?: boolean + isInsideHtml?: boolean } export const defaultParseVariablesOptions: ParseVariablesOptions = { fieldToParse: 'value', - escapeForJson: false, + isInsideJson: false, takeLatestIfList: false, - escapeHtml: false, + isInsideHtml: false, } export const parseVariables = @@ -39,13 +39,8 @@ export const parseVariables = if (!variable) return dollarSign + '' if (options.fieldToParse === 'id') return dollarSign + variable.id const { value } = variable - if (options.escapeForJson) - return ( - dollarSign + - (typeof value === 'string' - ? jsonParse(value) - : JSON.stringify(value)) - ) + if (options.isInsideJson) + return dollarSign + parseVariableValueInJson(value) const parsedValue = dollarSign + safeStringify( @@ -54,15 +49,22 @@ export const parseVariables = : value ) if (!parsedValue) return dollarSign + '' - if (options.escapeHtml) - return parsedValue.replace(//g, '>') + if (options.isInsideHtml) return parseVariableValueInHtml(parsedValue) return parsedValue } ) } -const jsonParse = (str: string) => - str - .replace(/\n/g, `\\n`) - .replace(/"/g, `\\"`) - .replace(/\\[^n"]/g, `\\\\ `) +const parseVariableValueInJson = (value: VariableWithValue['value']) => { + const stringifiedValue = JSON.stringify(value) + if (typeof value === 'string') return stringifiedValue.slice(1, -1) + return stringifiedValue +} + +const parseVariableValueInHtml = ( + value: VariableWithValue['value'] +): string => { + if (typeof value === 'string') + return value.replace(//g, '>') + return JSON.stringify(value).replace(//g, '>') +} 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 0879edabddb..2087298d0b6 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 @@ -149,7 +149,7 @@ export const executeWebhook = bodyContent && webhook.method !== HttpMethod.GET ? safeJsonParse( parseVariables(variables, { - escapeForJson: !checkIfBodyIsAVariable(bodyContent), + isInsideJson: !checkIfBodyIsAVariable(bodyContent), })(bodyContent) ) : { data: undefined, isJson: false } diff --git a/packages/emails/src/emails/DefaultBotNotificationEmail.tsx b/packages/emails/src/emails/DefaultBotNotificationEmail.tsx index 3a7fe0e4ecc..852568ba7fb 100644 --- a/packages/emails/src/emails/DefaultBotNotificationEmail.tsx +++ b/packages/emails/src/emails/DefaultBotNotificationEmail.tsx @@ -32,6 +32,13 @@ export const DefaultBotNotificationEmail = ({ {key}:{' '} {isEmail ? ( {answers[key]} + ) : answers[key].includes('\n') ? ( + answers[key].split('\n').map((line) => ( + <> + {line} +
+ + )) ) : ( answers[key] )}