2
0

Auto continue bot on whatsApp if starting block is input (#849)

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

**New Features:**
- Added WhatsApp integration feature to the Pro plan.

**Refactor:**
- Introduced the ability to exclude specific plans from being displayed
in the Change Plan Modal.
- Renamed the function `isProPlan` to `hasProPerks`, enhancing code
readability and maintainability.
- Updated the `EmbedButton` component to handle a new `lockTagPlan`
property and use the `modal` function instead of the `Modal` component.

**Chore:**
- Removed the `whatsAppPhoneNumberId` field from the `Typebot` model
across various files, simplifying the data structure of the model.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Baptiste Arnaud
2023-09-25 17:20:42 +02:00
committed by GitHub
parent 459fc4debc
commit b81fcf0167
30 changed files with 224 additions and 140 deletions

View File

@ -20,7 +20,6 @@ import { validateUrl } from './blocks/inputs/url/validateUrl'
import { resumeChatCompletion } from './blocks/integrations/openai/resumeChatCompletion'
import { resumeWebhookExecution } from './blocks/integrations/webhook/resumeWebhookExecution'
import { upsertAnswer } from './queries/upsertAnswer'
import { startBotFlow } from './startBotFlow'
import { parseButtonsReply } from './blocks/inputs/buttons/parseButtonsReply'
import { ParsedReply } from './types'
import { validateNumber } from './blocks/inputs/number/validateNumber'

View File

@ -75,7 +75,7 @@ export const resumeWhatsAppFlow = async ({
? await continueBotFlow(sessionState)(messageContent)
: workspaceId
? await startWhatsAppSession({
message: receivedMessage,
incomingMessage: messageContent,
sessionId,
workspaceId,
credentials: { ...credentials, id: credentialsId as string },

View File

@ -13,11 +13,14 @@ import {
WhatsAppIncomingMessage,
defaultSessionExpiryTimeout,
} from '@typebot.io/schemas/features/whatsapp'
import { isNotDefined } from '@typebot.io/lib/utils'
import { isInputBlock, isNotDefined } from '@typebot.io/lib/utils'
import { startSession } from '../startSession'
import { getNextGroup } from '../getNextGroup'
import { continueBotFlow } from '../continueBotFlow'
import { upsertResult } from '../queries/upsertResult'
type Props = {
message: WhatsAppIncomingMessage
incomingMessage?: string
sessionId: string
workspaceId?: string
credentials: WhatsAppCredentials['data'] & Pick<WhatsAppCredentials, 'id'>
@ -25,7 +28,7 @@ type Props = {
}
export const startWhatsAppSession = async ({
message,
incomingMessage,
workspaceId,
credentials,
contact,
@ -63,20 +66,41 @@ export const startWhatsAppSession = async ({
(publicTypebot) =>
publicTypebot.settings.whatsApp?.startCondition &&
messageMatchStartCondition(
getIncomingMessageText(message),
incomingMessage ?? '',
publicTypebot.settings.whatsApp?.startCondition
)
) ?? botsWithWhatsAppEnabled[0]
if (isNotDefined(publicTypebot)) return
const session = await startSession({
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
@ -166,21 +190,3 @@ const matchComparison = (
}
}
}
const getIncomingMessageText = (message: WhatsAppIncomingMessage): string => {
switch (message.type) {
case 'text':
return message.text.body
case 'button':
return message.button.text
case 'interactive': {
return message.interactive.button_reply.title
}
case 'video':
case 'document':
case 'audio':
case 'image': {
return ''
}
}
}