UNPKG

@botonic/plugin-flow-builder

Version:

Use Flow Builder to show your contents

128 lines (105 loc) 3.9 kB
import { FlowBuilderApi } from '../api' import { MAIN_FLOW_NAME } from '../constants' import { FlowBotAction, FlowContent } from '../content-fields' import BotonicPluginFlowBuilder from '../index' import { inputHasTextData } from '../utils' import { getContentsByAiAgent } from './ai-agent' import { FlowBuilderContext } from './index' import { getContentsByKnowledgeBase } from './knowledge-bases' import { getContentsByPayload } from './payload' export async function getContentsByFirstInteraction( context: FlowBuilderContext ): Promise<FlowContent[]> { const { contentID, flowBuilderPlugin, request } = context /* * If the contentID is provided, the firstInteractionContents are obtained even if they are not used * because when obtain this firstInteractionContents is when the session.flow_thread_id is updated. * This is needed for example when send a WhatsApp campaign is sent, * the bot not receives the message because this message is sent directly by the backend * we expect the bot to respond only with the contents of the contentID and not with the firstInteractionContents. */ const firstInteractionContents = await flowBuilderPlugin.getStartContents() if (contentID) { try { const contentsByContentID = await flowBuilderPlugin.getContentsByContentID(contentID) if (contentsByContentID.length > 0) { return contentsByContentID } } catch (error) { console.warn( `The contentID ${contentID} is not found. Returning the firstInteractionContents` ) } } /* If the first interaction has a FlowBotAction, it should be the last content * and avoid to render the match with keywords,intents or knowledge base */ if (firstInteractionContents.at(-1) instanceof FlowBotAction) { return firstInteractionContents } if (request.input.nluResolution || inputHasTextData(request.input)) { const contentsByUserInput = await getContentsByUserInput(context) return [...firstInteractionContents, ...contentsByUserInput] } return firstInteractionContents } async function getContentsByUserInput( context: FlowBuilderContext ): Promise<FlowContent[]> { const { cmsApi, flowBuilderPlugin, request, resolvedLocale } = context const payloadByNlu = request.input.nluResolution?.payload if (payloadByNlu) { request.input.payload = payloadByNlu const conversationStartId = getConversationStartId(cmsApi) if (request.input.payload === conversationStartId) { return [] } const contentsByKeywordsOrIntents = await getContentsByPayload({ cmsApi, flowBuilderPlugin, request, resolvedLocale, }) const hasRepeatedContent = await checkRepeatedContents( flowBuilderPlugin, contentsByKeywordsOrIntents ) if (hasRepeatedContent) { return [] } if (contentsByKeywordsOrIntents.length > 0) { return contentsByKeywordsOrIntents } } const contentsByKnowledgeBase = await getContentsByKnowledgeBase({ cmsApi, flowBuilderPlugin, request, resolvedLocale, }) if (contentsByKnowledgeBase.length > 0) { return contentsByKnowledgeBase } const contentsByAiAgent = await getContentsByAiAgent(context) return contentsByAiAgent } function getConversationStartId(cmsApi: FlowBuilderApi) { const conversationStartId = cmsApi.flow.flows.find( flow => flow.name === MAIN_FLOW_NAME )?.start_node_id return conversationStartId } async function checkRepeatedContents( flowBuilderPlugin: BotonicPluginFlowBuilder, contentsByKeywordsOrIntents: FlowContent[] ) { const startContents = await flowBuilderPlugin.getStartContents() const contentIds = new Set( contentsByKeywordsOrIntents.map(content => content.id) ) const hasRepeatedContent = startContents.some(content => contentIds.has(content.id) ) return hasRepeatedContent }