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]
)}