2
0

(chatwoot) Add result URL custom attribute

This commit is contained in:
Baptiste Arnaud
2023-04-25 08:15:53 +02:00
parent 3529da210c
commit c09a84034e
5 changed files with 66 additions and 29 deletions

View File

@@ -1,12 +1,14 @@
import { Stack } from '@chakra-ui/react'
import React, { useState } from 'react'
import React, { useEffect, useState } from 'react'
import { LogsModal } from './LogsModal'
import { useTypebot } from '@/features/editor/providers/TypebotProvider'
import { useResults } from '../ResultsProvider'
import { ResultModal } from './ResultModal'
import { ResultsTable } from './table/ResultsTable'
import { useRouter } from 'next/router'
export const ResultsTableContainer = () => {
const { query } = useRouter()
const {
flatResults: results,
fetchNextPage,
@@ -34,6 +36,10 @@ export const ResultsTableContainer = () => {
setExpandedResultId(results[index].id)
}
useEffect(() => {
if (query.id) setExpandedResultId(query.id as string)
}, [query.id])
return (
<Stack pb="28" px={['4', '0']} spacing="4" maxW="1600px" w="full">
{publishedTypebot && (

View File

@@ -31,3 +31,16 @@ To find your website token, head over to Chatwoot in your Inbox settings:
You can prefill user information by adding collected variables to the "Set user details" inputs.
For example, if you set the "Email" input to "john@gmail.com" then Chatwoot will automatically associate this email to the current user.
## Custom attributes
You can add these custom attributes that Typebot will automatically fill in for you:
### Result URL
You can link the current result URL to the Chatwoot conversation by creating this custom attribute:
<img
src="/img/blocks/integrations/chatwoot/custom-attribute.png"
alt="Chatwoot custom attribute"
/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

View File

@@ -2,32 +2,47 @@ import { ExecuteIntegrationResponse } from '@/features/chat/types'
import { extractVariablesFromText } from '@/features/variables/extractVariablesFromText'
import { parseGuessedValueType } from '@/features/variables/parseGuessedValueType'
import { parseVariables } from '@/features/variables/parseVariables'
import { isDefined } from '@typebot.io/lib'
import {
ChatwootBlock,
ChatwootOptions,
SessionState,
} from '@typebot.io/schemas'
const parseSetUserCode = (user: ChatwootOptions['user']) => `
window.$chatwoot.setUser("${user?.id ?? ''}", {
email: ${user?.email ? `"${user.email}"` : 'undefined'},
name: ${user?.name ? `"${user.name}"` : 'undefined'},
avatar_url: ${user?.avatarUrl ? `"${user.avatarUrl}"` : 'undefined'},
phone_number: ${user?.phoneNumber ? `"${user.phoneNumber}"` : 'undefined'},
});
const parseSetUserCode = (user: ChatwootOptions['user'], resultId: string) =>
user?.email || user?.id
? `
window.$chatwoot.setUser(${user?.id ?? `"${resultId}"`}, {
email: ${user?.email ? user.email : 'undefined'},
name: ${user?.name ? user.name : 'undefined'},
avatar_url: ${user?.avatarUrl ? user.avatarUrl : 'undefined'},
phone_number: ${user?.phoneNumber ? user.phoneNumber : 'undefined'},
});`
: ''
`
const parseChatwootOpenCode = ({
baseUrl,
websiteToken,
user,
}: ChatwootOptions) => `
if (window.$chatwoot) {
if(${Boolean(user)}) {
${parseSetUserCode(user)}
}
resultId,
typebotId,
}: ChatwootOptions & { typebotId: string; resultId: string }) => {
const openChatwoot = `${parseSetUserCode(user, resultId)}
window.$chatwoot.setCustomAttributes({
typebot_result_url: "${
process.env.NEXTAUTH_URL
}/typebots/${typebotId}/results?id=${resultId}",
});
window.$chatwoot.toggle("open");
} else {
`
return `
window.addEventListener("chatwoot:error", function (error) {
console.log(error);
});
if (window.$chatwoot) {${openChatwoot}}
else {
(function (d, t) {
var BASE_URL = "${baseUrl}";
var g = d.createElement(t),
@@ -41,15 +56,11 @@ if (window.$chatwoot) {
websiteToken: "${websiteToken}",
baseUrl: BASE_URL,
});
window.addEventListener("chatwoot:ready", function () {
if(${Boolean(user?.id || user?.email)}) {
${parseSetUserCode(user)}
}
window.$chatwoot.toggle("open");
});
window.addEventListener("chatwoot:ready", function () {${openChatwoot}});
};
})(document, "script");
}`
}
const chatwootCloseCode = `
if (window.$chatwoot) {
@@ -59,17 +70,20 @@ if (window.$chatwoot) {
`
export const executeChatwootBlock = (
{ typebot: { variables }, result }: SessionState,
{ typebot, result }: SessionState,
block: ChatwootBlock,
lastBubbleBlockId?: string
): ExecuteIntegrationResponse => {
const isPreview = !result.id
const chatwootCode =
block.options.task === 'Close widget'
? chatwootCloseCode
: isPreview
? ''
: parseChatwootOpenCode(block.options)
: isDefined(result.id)
? parseChatwootOpenCode({
...block.options,
typebotId: typebot.id,
resultId: result.id,
})
: ''
return {
outgoingEdgeId: block.outgoingEdgeId,
clientSideActions: [
@@ -77,10 +91,10 @@ export const executeChatwootBlock = (
lastBubbleBlockId,
chatwoot: {
scriptToExecute: {
content: parseVariables(variables, { fieldToParse: 'id' })(
content: parseVariables(typebot.variables, { fieldToParse: 'id' })(
chatwootCode
),
args: extractVariablesFromText(variables)(chatwootCode).map(
args: extractVariablesFromText(typebot.variables)(chatwootCode).map(
(variable) => ({
id: variable.id,
value: parseGuessedValueType(variable.value),

View File

@@ -9,7 +9,11 @@ export const extractVariablesFromText =
const variable = variables.find(
(variable) => variable.name === variableName
)
if (!variable) return acc
if (
!variable ||
acc.find((accVariable) => accVariable.id === variable.id)
)
return acc
return [...acc, variable]
}, [])
}