2
0

(setVariable) Add "Environment name" value in Set variable block (#850)

Closes #848
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
### Summary by CodeRabbit

- New Feature: Added "Environment name" as a new value type in the
SetVariable function, allowing users to distinguish between 'web' and
'whatsapp' environments.
- Refactor: Simplified session state handling in `resumeWhatsAppFlow.ts`
for improved code clarity.
- Refactor: Updated `startWhatsAppSession.ts` to include an initial
session state with WhatsApp contact and expiry timeout, enhancing
session management.
- Bug Fix: Improved null handling in `executeSetVariable.ts` for
'Contact name' and 'Phone number', preventing potential issues with
falsy values.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Baptiste Arnaud
2023-09-26 09:50:20 +02:00
committed by GitHub
parent 7b3cbdb8e8
commit 1ca742fc0b
9 changed files with 69 additions and 48 deletions

View File

@ -62,6 +62,7 @@ const Expression = ({
case 'Tomorrow':
case 'User ID':
case 'Moment of the day':
case 'Environment name':
case 'Yesterday': {
return (
<Text as="span">

View File

@ -158,6 +158,17 @@ const SetVariableValue = ({
</Alert>
)
}
case 'Environment name': {
return (
<Alert fontSize="sm">
<AlertIcon />
<Text>
Will return either <Tag size="sm">web</Tag> or{' '}
<Tag size="sm">whatsapp</Tag>.
</Text>
</Alert>
)
}
case 'Contact name':
case 'Phone number':
case 'Random ID':

View File

@ -1979,6 +1979,7 @@
"enum": [
"Custom",
"Empty",
"Environment name",
"User ID",
"Now",
"Today",
@ -6367,6 +6368,7 @@
"enum": [
"Custom",
"Empty",
"Environment name",
"User ID",
"Now",
"Today",
@ -10396,6 +10398,7 @@
"enum": [
"Custom",
"Empty",
"Environment name",
"User ID",
"Now",
"Today",
@ -14565,6 +14568,7 @@
"enum": [
"Custom",
"Empty",
"Environment name",
"User ID",
"Now",
"Today",
@ -18614,6 +18618,7 @@
"enum": [
"Custom",
"Empty",
"Environment name",
"User ID",
"Now",
"Today",
@ -22718,6 +22723,7 @@
"enum": [
"Custom",
"Empty",
"Environment name",
"User ID",
"Now",
"Today",
@ -26885,6 +26891,7 @@
"enum": [
"Custom",
"Empty",
"Environment name",
"User ID",
"Now",
"Today",

View File

@ -1574,6 +1574,7 @@
"enum": [
"Custom",
"Empty",
"Environment name",
"User ID",
"Now",
"Today",

View File

@ -77,9 +77,11 @@ const getExpressionToEvaluate =
(options: SetVariableBlock['options']): string | null => {
switch (options.type) {
case 'Contact name':
return state.whatsApp?.contact.name ?? ''
case 'Phone number':
return `"${state.whatsApp?.contact.phoneNumber}"` ?? ''
return state.whatsApp?.contact.name ?? null
case 'Phone number': {
const phoneNumber = state.whatsApp?.contact.phoneNumber
return phoneNumber ? `"${state.whatsApp?.contact.phoneNumber}"` : null
}
case 'Now':
case 'Today':
return 'new Date().toISOString()'
@ -112,6 +114,9 @@ const getExpressionToEvaluate =
if(now.getHours() >= 18) return 'evening'
if(now.getHours() >= 22 || now.getHours() < 6) return 'night'`
}
case 'Environment name': {
return state.whatsApp ? 'whatsapp' : 'web'
}
case 'Custom':
case undefined: {
return options.expressionToEvaluate ?? null

View File

@ -30,11 +30,13 @@ import { injectVariablesFromExistingResult } from './variables/injectVariablesFr
type Props = {
startParams: StartParams
userId: string | undefined
initialSessionState?: Pick<SessionState, 'whatsApp' | 'expiryTimeout'>
}
export const startSession = async ({
startParams,
userId,
initialSessionState,
}: Props): Promise<ChatReply & { newSessionState: SessionState }> => {
if (!startParams)
throw new TRPCError({
@ -108,6 +110,7 @@ export const startSession = async ({
dynamicTheme: parseDynamicThemeInState(typebot.theme),
isStreamEnabled: startParams.isStreamEnabled,
typingEmulation: typebot.settings.typingEmulation,
...initialSessionState,
}
if (startParams.isOnlyRegistering) {

View File

@ -46,16 +46,6 @@ export const resumeWhatsAppFlow = async ({
typebotId: typebot?.id,
})
const sessionState =
isPreview && session?.state
? ({
...session?.state,
whatsApp: {
contact,
},
} satisfies SessionState)
: session?.state
const credentials = await getCredentials({ credentialsId, isPreview })
if (!credentials) {
@ -71,8 +61,8 @@ export const resumeWhatsAppFlow = async ({
session?.updatedAt.getTime() + session.state.expiryTimeout < Date.now()
const resumeResponse =
sessionState && !isSessionExpired
? await continueBotFlow(sessionState)(messageContent)
session && !isSessionExpired
? await continueBotFlow(session.state)(messageContent)
: workspaceId
? await startWhatsAppSession({
incomingMessage: messageContent,

View File

@ -10,7 +10,6 @@ import {
} from '@typebot.io/schemas'
import {
WhatsAppCredentials,
WhatsAppIncomingMessage,
defaultSessionExpiryTimeout,
} from '@typebot.io/schemas/features/whatsapp'
import { isInputBlock, isNotDefined } from '@typebot.io/lib/utils'
@ -73,47 +72,50 @@ export const startWhatsAppSession = async ({
if (isNotDefined(publicTypebot)) return
let session = await startSession({
startParams: {
typebot: publicTypebot.typebot.publicId as string,
},
userId: undefined,
})
// If first block is an input block, we can directly continue the bot flow
const firstEdgeId =
session.newSessionState.typebotsQueue[0].typebot.groups[0].blocks[0]
.outgoingEdgeId
const nextGroup = await getNextGroup(session.newSessionState)(firstEdgeId)
const firstBlock = nextGroup.group?.blocks.at(0)
if (firstBlock && isInputBlock(firstBlock)) {
const resultId = session.newSessionState.typebotsQueue[0].resultId
if (resultId)
await upsertResult({
hasStarted: true,
isCompleted: false,
resultId,
typebot: session.newSessionState.typebotsQueue[0].typebot,
})
session = await continueBotFlow({
...session.newSessionState,
currentBlock: { groupId: firstBlock.groupId, blockId: firstBlock.id },
})(incomingMessage)
}
const sessionExpiryTimeoutHours =
publicTypebot.settings.whatsApp?.sessionExpiryTimeout ??
defaultSessionExpiryTimeout
return {
...session,
newSessionState: {
...session.newSessionState,
const session = await startSession({
startParams: {
typebot: publicTypebot.typebot.publicId as string,
},
userId: undefined,
initialSessionState: {
whatsApp: {
contact,
},
expiryTimeout: sessionExpiryTimeoutHours * 60 * 60 * 1000,
},
})
let newSessionState: SessionState = session.newSessionState
// If first block is an input block, we can directly continue the bot flow
const firstEdgeId =
newSessionState.typebotsQueue[0].typebot.groups[0].blocks[0].outgoingEdgeId
const nextGroup = await getNextGroup(newSessionState)(firstEdgeId)
const firstBlock = nextGroup.group?.blocks.at(0)
if (firstBlock && isInputBlock(firstBlock)) {
const resultId = newSessionState.typebotsQueue[0].resultId
if (resultId)
await upsertResult({
hasStarted: true,
isCompleted: false,
resultId,
typebot: newSessionState.typebotsQueue[0].typebot,
})
newSessionState = (
await continueBotFlow({
...newSessionState,
currentBlock: { groupId: firstBlock.groupId, blockId: firstBlock.id },
})(incomingMessage)
).newSessionState
}
return {
...session,
newSessionState,
}
}

View File

@ -5,6 +5,7 @@ import { LogicBlockType } from './enums'
export const valueTypes = [
'Custom',
'Empty',
'Environment name',
'User ID',
'Now',
'Today',