(whatsapp) Add custom session expiration (#842)

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

- New Feature: Introduced session expiry timeout for WhatsApp
integration, allowing users to set the duration after which a session
expires.
- New Feature: Added an option to enable/disable the start bot condition
in WhatsApp integration settings.
- Refactor: Enhanced error handling by throwing specific errors when
necessary conditions are not met.
- Refactor: Improved UI components like `NumberInput` and
`SwitchWithLabel` for better usability.
- Bug Fix: Fixed issues related to session resumption and message
sending in expired sessions. Now, if a session is expired, a new one
will be started instead of attempting to resume the old one.
- Chore: Updated various schemas to reflect changes in session
management and WhatsApp settings.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Baptiste Arnaud
2023-09-22 17:12:15 +02:00
committed by GitHub
parent 4cfb45e2a3
commit 4f953ac272
11 changed files with 175 additions and 62 deletions

View File

@@ -1,5 +1,5 @@
import { TextInput, NumberInput } from '@/components/inputs'
import { HStack, Stack, Text } from '@chakra-ui/react'
import { Stack, Text } from '@chakra-ui/react'
import { EmbedBubbleContent } from '@typebot.io/schemas'
import { sanitizeUrl } from '@typebot.io/lib'
import { useScopedI18n } from '@/locales'
@@ -34,14 +34,13 @@ export const EmbedUploadContent = ({ content, onSubmit }: Props) => {
</Text>
</Stack>
<HStack>
<NumberInput
label="Height:"
defaultValue={content?.height}
onValueChange={handleHeightChange}
/>
<Text>{scopedT('numberInput.unit')}</Text>
</HStack>
<NumberInput
label="Height:"
defaultValue={content?.height}
onValueChange={handleHeightChange}
suffix={scopedT('numberInput.unit')}
width="150px"
/>
</Stack>
)
}

View File

@@ -35,6 +35,10 @@ import { Comparison, LogicalOperator } from '@typebot.io/schemas'
import { DropdownList } from '@/components/DropdownList'
import { WhatsAppComparisonItem } from './WhatsAppComparisonItem'
import { AlertInfo } from '@/components/AlertInfo'
import { NumberInput } from '@/components/inputs'
import { defaultSessionExpiryTimeout } from '@typebot.io/schemas/features/whatsapp'
import { SwitchWithRelatedSettings } from '@/components/SwitchWithRelatedSettings'
import { isDefined } from '@typebot.io/lib/utils'
export const WhatsAppModal = ({ isOpen, onClose }: ModalProps): JSX.Element => {
const { typebot, updateTypebot, isPublished } = useTypebot()
@@ -122,6 +126,46 @@ export const WhatsAppModal = ({ isOpen, onClose }: ModalProps): JSX.Element => {
})
}
const updateIsStartConditionEnabled = (isEnabled: boolean) => {
if (!typebot) return
updateTypebot({
updates: {
settings: {
...typebot.settings,
whatsApp: {
...typebot.settings.whatsApp,
startCondition: !isEnabled
? undefined
: {
comparisons: [],
logicalOperator: LogicalOperator.AND,
},
},
},
},
})
}
const updateSessionExpiryTimeout = (sessionExpiryTimeout?: number) => {
if (
!typebot ||
(sessionExpiryTimeout &&
(sessionExpiryTimeout <= 0 || sessionExpiryTimeout > 48))
)
return
updateTypebot({
updates: {
settings: {
...typebot.settings,
whatsApp: {
...typebot.settings.whatsApp,
sessionExpiryTimeout,
},
},
},
})
}
return (
<Modal isOpen={isOpen} onClose={onClose} size="xl">
<ModalOverlay />
@@ -166,33 +210,58 @@ export const WhatsAppModal = ({ isOpen, onClose }: ModalProps): JSX.Element => {
<Accordion allowToggle>
<AccordionItem>
<AccordionButton justifyContent="space-between">
Start flow only if
Configure integration
<AccordionIcon />
</AccordionButton>
<AccordionPanel as={Stack} spacing="4" pt="4">
<TableList<Comparison>
initialItems={
whatsAppSettings?.startCondition?.comparisons ?? []
}
onItemsChange={updateStartConditionComparisons}
Item={WhatsAppComparisonItem}
ComponentBetweenItems={() => (
<Flex justify="center">
<DropdownList
currentItem={
whatsAppSettings?.startCondition
?.logicalOperator
}
onItemSelect={
updateStartConditionLogicalOperator
}
items={Object.values(LogicalOperator)}
size="sm"
/>
</Flex>
<HStack>
<NumberInput
max={48}
min={0}
width="100px"
label="Session expire timeout:"
defaultValue={
whatsAppSettings?.sessionExpiryTimeout
}
placeholder={defaultSessionExpiryTimeout.toString()}
moreInfoTooltip="A number between 0 and 48 that represents the time in hours after which the session will expire if the user does not interact with the bot. The conversation restarts if the user sends a message after that expiration time."
onValueChange={updateSessionExpiryTimeout}
withVariableButton={false}
suffix="hours"
/>
</HStack>
<SwitchWithRelatedSettings
label={'Start bot condition'}
initialValue={isDefined(
whatsAppSettings?.startCondition
)}
addLabel="Add a comparison"
/>
onCheckChange={updateIsStartConditionEnabled}
>
<TableList<Comparison>
initialItems={
whatsAppSettings?.startCondition?.comparisons ??
[]
}
onItemsChange={updateStartConditionComparisons}
Item={WhatsAppComparisonItem}
ComponentBetweenItems={() => (
<Flex justify="center">
<DropdownList
currentItem={
whatsAppSettings?.startCondition
?.logicalOperator
}
onItemSelect={
updateStartConditionLogicalOperator
}
items={Object.values(LogicalOperator)}
size="sm"
/>
</Flex>
)}
addLabel="Add a comparison"
/>
</SwitchWithRelatedSettings>
</AccordionPanel>
</AccordionItem>
</Accordion>