@botonic/plugin-flow-builder 0.57.0-rslib-esm.1 → 0.57.0-rslib-esm.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/content-fields/flow-ai-agent-base.js +6 -0
- package/lib/content-fields/flow-ai-agent-base.js.map +1 -1
- package/lib/content-fields/flow-whatsapp-request-contact-info.d.ts +2 -1
- package/lib/content-fields/flow-whatsapp-request-contact-info.js +10 -0
- package/lib/content-fields/flow-whatsapp-request-contact-info.js.map +1 -1
- package/lib/utils/hubtype-assistant-content.d.ts +1 -0
- package/lib/utils/hubtype-assistant-content.js +13 -0
- package/lib/utils/hubtype-assistant-content.js.map +1 -1
- package/package.json +3 -3
- package/src/content-fields/flow-ai-agent-base.tsx +11 -0
- package/src/content-fields/flow-whatsapp-request-contact-info.tsx +17 -1
- package/src/utils/hubtype-assistant-content.ts +14 -0
|
@@ -6,6 +6,9 @@ import { HubtypeAssistantContent } from "../utils/hubtype-assistant-content.js";
|
|
|
6
6
|
import { ContentFieldsBase } from "./content-fields-base.js";
|
|
7
7
|
import { FlowCarousel } from "./flow-carousel.js";
|
|
8
8
|
import { FlowText } from "./flow-text.js";
|
|
9
|
+
import { FlowWhatsappRequestContactInfoNode } from "./flow-whatsapp-request-contact-info.js";
|
|
10
|
+
|
|
11
|
+
|
|
9
12
|
|
|
10
13
|
|
|
11
14
|
|
|
@@ -51,6 +54,9 @@ class FlowAiAgentBase extends ContentFieldsBase {
|
|
|
51
54
|
if (message.type === OutputMessageType.Carousel) {
|
|
52
55
|
this.jsxElements.push(FlowCarousel.fromAIAgent(this.id, message, botContext));
|
|
53
56
|
}
|
|
57
|
+
if (message.type === OutputMessageType.RequestContactInfo) {
|
|
58
|
+
this.jsxElements.push(FlowWhatsappRequestContactInfoNode.fromAIAgent(this.id, message, botContext));
|
|
59
|
+
}
|
|
54
60
|
if (message.type === FlowBuilderOutputMessageType.FlowBuilderContent) {
|
|
55
61
|
const flowContents = await this.getFlowContentsByContentId(botContext, message.contentId);
|
|
56
62
|
for (const content of flowContents){
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-fields/flow-ai-agent-base.js","sources":["../../src/content-fields/flow-ai-agent-base.tsx"],"sourcesContent":["import {\n type AgenticOutputMessage,\n type BotContext,\n type GuardrailRule,\n type HubtypeAssistantMessage,\n type InferenceResponse,\n OutputMessageType,\n VerbosityLevel,\n} from '@botonic/core'\nimport {\n type FlowBuilderContentMessage,\n FlowBuilderOutputMessageType,\n} from '../structured-output/flow-builder-content'\nimport { getFlowBuilderPlugin } from '../utils/get-flow-builder-plugin'\nimport { HubtypeAssistantContent } from '../utils/hubtype-assistant-content'\nimport { ContentFieldsBase } from './content-fields-base'\nimport { FlowCarousel } from './flow-carousel'\nimport { FlowText } from './flow-text'\nimport type { HtInputGuardrailRule, HtNodeWithContent } from './hubtype-fields'\nimport type { FlowContent } from './index'\n\nexport abstract class FlowAiAgentBase extends ContentFieldsBase {\n public name: string = ''\n public instructions: string = ''\n public model: string = ''\n public verbosity: VerbosityLevel = VerbosityLevel.Medium\n public inputGuardrailRules: HtInputGuardrailRule[] = []\n\n public aiAgentResponse?: InferenceResponse<FlowBuilderContentMessage>\n public messages: AgenticOutputMessage<FlowBuilderContentMessage>[] = []\n public jsxElements: JSX.Element[] = []\n\n abstract getAIAgentResponse(\n botContext: BotContext,\n previousContents?: FlowContent[]\n ): Promise<InferenceResponse<FlowBuilderContentMessage> | undefined>\n\n abstract trackAiAgentResponse(botContext: BotContext): Promise<void>\n\n async resolveAIAgentResponse(\n botContext: BotContext,\n previousContents?: FlowContent[]\n ): Promise<InferenceResponse<FlowBuilderContentMessage> | undefined> {\n const aiAgentResponse = await this.getAIAgentResponse(\n botContext,\n previousContents\n )\n\n if (aiAgentResponse) {\n this.aiAgentResponse = aiAgentResponse\n await this.trackAiAgentResponse(botContext)\n this.messages = aiAgentResponse.messages\n }\n\n return aiAgentResponse\n }\n\n async trackFlow(_botContext: BotContext): Promise<void> {\n return\n }\n\n async getFlowContentsByContentId(\n botContext: BotContext,\n contentId: string\n ): Promise<FlowContent[]> {\n const flowBuilderPlugin = getFlowBuilderPlugin(botContext.plugins)\n const cmsApi = flowBuilderPlugin.cmsApi\n const node = cmsApi.getNodeByContentID(contentId)\n const flowContents = await flowBuilderPlugin.getContentsByNode(\n node as HtNodeWithContent\n )\n\n return flowContents\n }\n\n async messagesToBotonicJSXElements(botContext: BotContext): Promise<void> {\n for (const message of this.messages) {\n if (\n message.type === OutputMessageType.Text ||\n message.type === OutputMessageType.TextWithButtons ||\n message.type === OutputMessageType.BotExecutor\n ) {\n this.jsxElements.push(FlowText.fromAIAgent(this.id, message))\n }\n\n if (message.type === OutputMessageType.Carousel) {\n this.jsxElements.push(\n FlowCarousel.fromAIAgent(this.id, message, botContext)\n )\n }\n\n if (message.type === FlowBuilderOutputMessageType.FlowBuilderContent) {\n const flowContents = await this.getFlowContentsByContentId(\n botContext,\n message.contentId\n )\n for (const content of flowContents) {\n await content.processContent(botContext)\n this.jsxElements.push(content.toBotonic(botContext))\n }\n }\n }\n return\n }\n\n async processContent(\n botContext: BotContext,\n previousContents?: FlowContent[]\n ): Promise<void> {\n if (this.messages.length === 0) {\n await this.resolveAIAgentResponse(botContext, previousContents)\n }\n if (this.jsxElements.length === 0) {\n await this.filterContent(botContext, this as unknown as FlowContent)\n await this.messagesToBotonicJSXElements(botContext)\n }\n return\n }\n\n toBotonic(): JSX.Element {\n return <>{this.jsxElements}</>\n }\n\n protected getPreviousHubtypeContents(\n previousContents?: FlowContent[]\n ): HubtypeAssistantMessage[] {\n return (\n previousContents?.map(content => {\n return {\n role: 'assistant',\n content: HubtypeAssistantContent.adapt(content),\n }\n }) || []\n )\n }\n\n protected getActiveInputGuardrailRules(\n inputGuardrailRules: HtInputGuardrailRule[]\n ): GuardrailRule[] {\n return (\n inputGuardrailRules\n ?.filter(rule => rule.is_active)\n ?.map(rule => ({\n name: rule.name,\n description: rule.description,\n })) || []\n )\n }\n}\n"],"names":["OutputMessageType","VerbosityLevel","FlowBuilderOutputMessageType","getFlowBuilderPlugin","HubtypeAssistantContent","ContentFieldsBase","FlowCarousel","FlowText","FlowAiAgentBase","botContext","previousContents","aiAgentResponse","_botContext","contentId","flowBuilderPlugin","cmsApi","node","flowContents","message","content","inputGuardrailRules","rule"],"mappings":"
|
|
1
|
+
{"version":3,"file":"content-fields/flow-ai-agent-base.js","sources":["../../src/content-fields/flow-ai-agent-base.tsx"],"sourcesContent":["import {\n type AgenticOutputMessage,\n type BotContext,\n type GuardrailRule,\n type HubtypeAssistantMessage,\n type InferenceResponse,\n OutputMessageType,\n VerbosityLevel,\n} from '@botonic/core'\nimport {\n type FlowBuilderContentMessage,\n FlowBuilderOutputMessageType,\n} from '../structured-output/flow-builder-content'\nimport { getFlowBuilderPlugin } from '../utils/get-flow-builder-plugin'\nimport { HubtypeAssistantContent } from '../utils/hubtype-assistant-content'\nimport { ContentFieldsBase } from './content-fields-base'\nimport { FlowCarousel } from './flow-carousel'\nimport { FlowText } from './flow-text'\nimport { FlowWhatsappRequestContactInfoNode } from './flow-whatsapp-request-contact-info'\nimport type { HtInputGuardrailRule, HtNodeWithContent } from './hubtype-fields'\nimport type { FlowContent } from './index'\n\nexport abstract class FlowAiAgentBase extends ContentFieldsBase {\n public name: string = ''\n public instructions: string = ''\n public model: string = ''\n public verbosity: VerbosityLevel = VerbosityLevel.Medium\n public inputGuardrailRules: HtInputGuardrailRule[] = []\n\n public aiAgentResponse?: InferenceResponse<FlowBuilderContentMessage>\n public messages: AgenticOutputMessage<FlowBuilderContentMessage>[] = []\n public jsxElements: JSX.Element[] = []\n\n abstract getAIAgentResponse(\n botContext: BotContext,\n previousContents?: FlowContent[]\n ): Promise<InferenceResponse<FlowBuilderContentMessage> | undefined>\n\n abstract trackAiAgentResponse(botContext: BotContext): Promise<void>\n\n async resolveAIAgentResponse(\n botContext: BotContext,\n previousContents?: FlowContent[]\n ): Promise<InferenceResponse<FlowBuilderContentMessage> | undefined> {\n const aiAgentResponse = await this.getAIAgentResponse(\n botContext,\n previousContents\n )\n\n if (aiAgentResponse) {\n this.aiAgentResponse = aiAgentResponse\n await this.trackAiAgentResponse(botContext)\n this.messages = aiAgentResponse.messages\n }\n\n return aiAgentResponse\n }\n\n async trackFlow(_botContext: BotContext): Promise<void> {\n return\n }\n\n async getFlowContentsByContentId(\n botContext: BotContext,\n contentId: string\n ): Promise<FlowContent[]> {\n const flowBuilderPlugin = getFlowBuilderPlugin(botContext.plugins)\n const cmsApi = flowBuilderPlugin.cmsApi\n const node = cmsApi.getNodeByContentID(contentId)\n const flowContents = await flowBuilderPlugin.getContentsByNode(\n node as HtNodeWithContent\n )\n\n return flowContents\n }\n\n async messagesToBotonicJSXElements(botContext: BotContext): Promise<void> {\n for (const message of this.messages) {\n if (\n message.type === OutputMessageType.Text ||\n message.type === OutputMessageType.TextWithButtons ||\n message.type === OutputMessageType.BotExecutor\n ) {\n this.jsxElements.push(FlowText.fromAIAgent(this.id, message))\n }\n\n if (message.type === OutputMessageType.Carousel) {\n this.jsxElements.push(\n FlowCarousel.fromAIAgent(this.id, message, botContext)\n )\n }\n\n if (message.type === OutputMessageType.RequestContactInfo) {\n this.jsxElements.push(\n FlowWhatsappRequestContactInfoNode.fromAIAgent(\n this.id,\n message,\n botContext\n )\n )\n }\n\n if (message.type === FlowBuilderOutputMessageType.FlowBuilderContent) {\n const flowContents = await this.getFlowContentsByContentId(\n botContext,\n message.contentId\n )\n for (const content of flowContents) {\n await content.processContent(botContext)\n this.jsxElements.push(content.toBotonic(botContext))\n }\n }\n }\n return\n }\n\n async processContent(\n botContext: BotContext,\n previousContents?: FlowContent[]\n ): Promise<void> {\n if (this.messages.length === 0) {\n await this.resolveAIAgentResponse(botContext, previousContents)\n }\n if (this.jsxElements.length === 0) {\n await this.filterContent(botContext, this as unknown as FlowContent)\n await this.messagesToBotonicJSXElements(botContext)\n }\n return\n }\n\n toBotonic(): JSX.Element {\n return <>{this.jsxElements}</>\n }\n\n protected getPreviousHubtypeContents(\n previousContents?: FlowContent[]\n ): HubtypeAssistantMessage[] {\n return (\n previousContents?.map(content => {\n return {\n role: 'assistant',\n content: HubtypeAssistantContent.adapt(content),\n }\n }) || []\n )\n }\n\n protected getActiveInputGuardrailRules(\n inputGuardrailRules: HtInputGuardrailRule[]\n ): GuardrailRule[] {\n return (\n inputGuardrailRules\n ?.filter(rule => rule.is_active)\n ?.map(rule => ({\n name: rule.name,\n description: rule.description,\n })) || []\n )\n }\n}\n"],"names":["OutputMessageType","VerbosityLevel","FlowBuilderOutputMessageType","getFlowBuilderPlugin","HubtypeAssistantContent","ContentFieldsBase","FlowCarousel","FlowText","FlowWhatsappRequestContactInfoNode","FlowAiAgentBase","botContext","previousContents","aiAgentResponse","_botContext","contentId","flowBuilderPlugin","cmsApi","node","flowContents","message","content","inputGuardrailRules","rule"],"mappings":"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"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { type BotContext } from '@botonic/core';
|
|
1
|
+
import { type BotContext, type RequestContactInfoMessage } from '@botonic/core';
|
|
2
2
|
import { ContentFieldsBase } from './content-fields-base.js';
|
|
3
3
|
import type { HtWhatsappRequestContactInfoNode } from './hubtype-fields/index.js';
|
|
4
4
|
export declare class FlowWhatsappRequestContactInfoNode extends ContentFieldsBase {
|
|
5
5
|
text: string;
|
|
6
6
|
static fromHubtypeCMS(component: HtWhatsappRequestContactInfoNode, locale: string): FlowWhatsappRequestContactInfoNode;
|
|
7
|
+
static fromAIAgent(id: string, message: RequestContactInfoMessage, botContext: BotContext): JSX.Element;
|
|
7
8
|
trackFlow(botContext: BotContext): Promise<void>;
|
|
8
9
|
processContent(botContext: BotContext): Promise<void>;
|
|
9
10
|
toBotonic(botContext: BotContext): JSX.Element;
|
|
@@ -22,6 +22,16 @@ class FlowWhatsappRequestContactInfoNode extends ContentFieldsBase {
|
|
|
22
22
|
requestContactInfo.followUp = component.follow_up;
|
|
23
23
|
return requestContactInfo;
|
|
24
24
|
}
|
|
25
|
+
static fromAIAgent(id, message, botContext) {
|
|
26
|
+
if (!isWhatsapp(botContext.session)) {
|
|
27
|
+
return /*#__PURE__*/ jsx(Text, {
|
|
28
|
+
children: message.content.text
|
|
29
|
+
}, id);
|
|
30
|
+
}
|
|
31
|
+
return /*#__PURE__*/ jsx(WhatsappRequestContactInfo, {
|
|
32
|
+
body: message.content.text
|
|
33
|
+
}, id);
|
|
34
|
+
}
|
|
25
35
|
async trackFlow(botContext) {
|
|
26
36
|
await trackOneContent(botContext, this);
|
|
27
37
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-fields/flow-whatsapp-request-contact-info.js","sources":["../../src/content-fields/flow-whatsapp-request-contact-info.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"content-fields/flow-whatsapp-request-contact-info.js","sources":["../../src/content-fields/flow-whatsapp-request-contact-info.tsx"],"sourcesContent":["import {\n type BotContext,\n isWhatsapp,\n type RequestContactInfoMessage,\n} from '@botonic/core'\nimport { Text, WhatsappRequestContactInfo } from '@botonic/react'\n\nimport { trackOneContent } from '../tracking'\nimport { ContentFieldsBase } from './content-fields-base'\nimport type { HtWhatsappRequestContactInfoNode } from './hubtype-fields'\n\nexport class FlowWhatsappRequestContactInfoNode extends ContentFieldsBase {\n public text = ''\n\n static fromHubtypeCMS(\n component: HtWhatsappRequestContactInfoNode,\n locale: string\n ): FlowWhatsappRequestContactInfoNode {\n const requestContactInfo = new FlowWhatsappRequestContactInfoNode(\n component.id\n )\n requestContactInfo.code = component.code\n requestContactInfo.text =\n FlowWhatsappRequestContactInfoNode.getTextByLocale(\n locale,\n component.content.text\n )\n requestContactInfo.followUp = component.follow_up\n\n return requestContactInfo\n }\n\n static fromAIAgent(\n id: string,\n message: RequestContactInfoMessage,\n botContext: BotContext\n ): JSX.Element {\n if (!isWhatsapp(botContext.session)) {\n return <Text key={id}>{message.content.text}</Text>\n }\n\n return <WhatsappRequestContactInfo key={id} body={message.content.text} />\n }\n\n async trackFlow(botContext: BotContext): Promise<void> {\n await trackOneContent(botContext, this)\n }\n\n async processContent(botContext: BotContext): Promise<void> {\n await this.filterContent(botContext, this)\n await this.trackFlow(botContext)\n return\n }\n\n toBotonic(botContext: BotContext): JSX.Element {\n const replacedText = this.replaceVariables(this.text, botContext)\n\n if (!isWhatsapp(botContext.session)) {\n return <Text>{replacedText}</Text>\n }\n\n return <WhatsappRequestContactInfo key={this.id} body={replacedText} />\n }\n}\n"],"names":["isWhatsapp","Text","WhatsappRequestContactInfo","trackOneContent","ContentFieldsBase","FlowWhatsappRequestContactInfoNode","component","locale","requestContactInfo","id","message","botContext","replacedText"],"mappings":";;;;;;;;;;;;AAIsB;AAC2C;AAEpB;AACY;AAGlD,MAAMK,kCAAkCA,SAASD,iBAAiBA;IAGvE,OAAO,eACLE,SAA2C,EAC3CC,MAAc,EACsB;QACpC,MAAMC,qBAAqB,IAAIH,kCAAkCA,CAC/DC,UAAU,EAAE;QAEdE,mBAAmB,IAAI,GAAGF,UAAU,IAAI;QACxCE,mBAAmB,IAAI,GACrBH,kCAAkCA,CAAC,eAAe,CAChDE,QACAD,UAAU,OAAO,CAAC,IAAI;QAE1BE,mBAAmB,QAAQ,GAAGF,UAAU,SAAS;QAEjD,OAAOE;IACT;IAEA,OAAO,YACLC,EAAU,EACVC,OAAkC,EAClCC,UAAsB,EACT;QACb,IAAI,CAACX,UAAUA,CAACW,WAAW,OAAO,GAAG;YACnC,qBAAO,IAACV,IAAIA;0BAAWS,QAAQ,OAAO,CAAC,IAAI;eAAzBD;QACpB;QAEA,qBAAO,IAACP,0BAA0BA;YAAU,MAAMQ,QAAQ,OAAO,CAAC,IAAI;WAA9BD;IAC1C;IAEA,MAAM,UAAUE,UAAsB,EAAiB;QACrD,MAAMR,eAAeA,CAACQ,YAAY,IAAI;IACxC;IAEA,MAAM,eAAeA,UAAsB,EAAiB;QAC1D,MAAM,IAAI,CAAC,aAAa,CAACA,YAAY,IAAI;QACzC,MAAM,IAAI,CAAC,SAAS,CAACA;QACrB;IACF;IAEA,UAAUA,UAAsB,EAAe;QAC7C,MAAMC,eAAe,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAED;QAEtD,IAAI,CAACX,UAAUA,CAACW,WAAW,OAAO,GAAG;YACnC,qBAAO,IAACV,IAAIA;0BAAEW;;QAChB;QAEA,qBAAO,IAACV,0BAA0BA;YAAe,MAAMU;WAAf,IAAI,CAAC,EAAE;IACjD;;QAnDK,qBACE,OAAO;;AAmDhB"}
|
|
@@ -4,6 +4,7 @@ import { FlowImage } from "../content-fields/flow-image.js";
|
|
|
4
4
|
import { FlowText } from "../content-fields/flow-text.js";
|
|
5
5
|
import { FlowVideo } from "../content-fields/flow-video.js";
|
|
6
6
|
import { FlowWhatsappCtaUrlButtonNode } from "../content-fields/flow-whatsapp-cta-url-button.js";
|
|
7
|
+
import { FlowWhatsappRequestContactInfoNode } from "../content-fields/flow-whatsapp-request-contact-info.js";
|
|
7
8
|
import { FlowWhatsappTemplate } from "../content-fields/flow-whatsapp-template.js";
|
|
8
9
|
import { HtButtonStyle } from "../content-fields/hubtype-fields/index.js";
|
|
9
10
|
import { FlowWhatsappButtonList } from "../content-fields/whatsapp-button-list/flow-whatsapp-button-list.js";
|
|
@@ -25,6 +26,8 @@ import { FlowWhatsappButtonList } from "../content-fields/whatsapp-button-list/f
|
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
|
|
29
|
+
|
|
30
|
+
|
|
28
31
|
|
|
29
32
|
// biome-ignore lint/complexity/noStaticOnlyClass: namespace-like adapter with private static helpers
|
|
30
33
|
class HubtypeAssistantContent {
|
|
@@ -50,6 +53,9 @@ class HubtypeAssistantContent {
|
|
|
50
53
|
if (content instanceof FlowWhatsappTemplate) {
|
|
51
54
|
return HubtypeAssistantContent.formatWhatsappTemplateContent(content);
|
|
52
55
|
}
|
|
56
|
+
if (content instanceof FlowWhatsappRequestContactInfoNode) {
|
|
57
|
+
return HubtypeAssistantContent.formatRequestContactInfoContent(content);
|
|
58
|
+
}
|
|
53
59
|
return '';
|
|
54
60
|
}
|
|
55
61
|
static quickReplyLabel(button) {
|
|
@@ -180,6 +186,13 @@ class HubtypeAssistantContent {
|
|
|
180
186
|
const { name, language } = template.htWhatsappTemplate;
|
|
181
187
|
return `WhatsApp Template: ${name} (${language})`;
|
|
182
188
|
}
|
|
189
|
+
static formatRequestContactInfoContent(requestContactInfo) {
|
|
190
|
+
const body = requestContactInfo.text?.trim() ?? '';
|
|
191
|
+
if (!body) {
|
|
192
|
+
return '[WhatsApp Request Contact Info]';
|
|
193
|
+
}
|
|
194
|
+
return requestContactInfo.text;
|
|
195
|
+
}
|
|
183
196
|
}
|
|
184
197
|
|
|
185
198
|
export { HubtypeAssistantContent };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils/hubtype-assistant-content.js","sources":["../../src/utils/hubtype-assistant-content.ts"],"sourcesContent":["import { WhatsappCTAUrlHeaderType } from '@botonic/react'\nimport type { FlowContent } from '../content-fields'\nimport type { FlowButton } from '../content-fields/flow-button'\nimport { FlowCarousel } from '../content-fields/flow-carousel'\nimport { FlowImage } from '../content-fields/flow-image'\nimport { FlowText } from '../content-fields/flow-text'\nimport { FlowVideo } from '../content-fields/flow-video'\nimport { FlowWhatsappCtaUrlButtonNode } from '../content-fields/flow-whatsapp-cta-url-button'\nimport { FlowWhatsappTemplate } from '../content-fields/flow-whatsapp-template'\nimport { HtButtonStyle } from '../content-fields/hubtype-fields'\nimport { FlowWhatsappButtonList } from '../content-fields/whatsapp-button-list/flow-whatsapp-button-list'\n\n// biome-ignore lint/complexity/noStaticOnlyClass: namespace-like adapter with private static helpers\nexport class HubtypeAssistantContent {\n static adapt(content: FlowContent): string {\n if (content instanceof FlowText) {\n return HubtypeAssistantContent.formatFlowTextContent(content)\n }\n if (content instanceof FlowCarousel) {\n return HubtypeAssistantContent.formatCarouselContent(content)\n }\n if (content instanceof FlowImage) {\n return content.src ? `[Image]\\n${content.src}` : '[Image]'\n }\n if (content instanceof FlowVideo) {\n return content.src ? `[Video]\\n${content.src}` : '[Video]'\n }\n if (content instanceof FlowWhatsappButtonList) {\n return HubtypeAssistantContent.formatWhatsappButtonListContent(content)\n }\n if (content instanceof FlowWhatsappCtaUrlButtonNode) {\n return HubtypeAssistantContent.formatWhatsappCtaContent(content)\n }\n if (content instanceof FlowWhatsappTemplate) {\n return HubtypeAssistantContent.formatWhatsappTemplateContent(content)\n }\n return ''\n }\n\n private static quickReplyLabel(button: FlowButton): string {\n const buttonText = button.text?.trim()\n if (buttonText) {\n return buttonText\n }\n\n return button.payload || 'Option'\n }\n\n private static persistentButtonLabel(button: FlowButton): string {\n return button.text?.trim() || 'Button'\n }\n\n private static carouselButtonLabel(button: FlowButton): string {\n return button.text?.trim() || 'Action'\n }\n\n private static formatFlowTextContent(text: FlowText): string {\n const body = text.text?.trim() ?? ''\n const buttons = text.buttons\n\n if (!body && buttons.length === 0) {\n return ''\n }\n\n if (buttons.length === 0) {\n return text.text\n }\n\n const isQuickReply = text.buttonStyle === HtButtonStyle.QUICK_REPLY\n const blockTitle = isQuickReply ? 'Quick replies:' : 'Buttons:'\n const lines = buttons.map((button, i) => {\n const label = isQuickReply\n ? HubtypeAssistantContent.quickReplyLabel(button)\n : HubtypeAssistantContent.persistentButtonLabel(button)\n return ` [${i + 1}] ${label}`\n })\n\n const block = [blockTitle, ...lines].join('\\n')\n if (!body) {\n return block\n }\n\n return `${body}\\n\\n${block}`\n }\n\n private static formatCarouselContent(carousel: FlowCarousel): string {\n const elements = carousel.elements\n const n = elements.length\n const mainText = (carousel.whatsappText ?? '').trim()\n\n if (n === 0) {\n return mainText\n }\n\n let header: string\n if (!mainText) {\n header = `Carousel displayed with ${n} items:`\n } else if (mainText.endsWith(':')) {\n header = mainText\n } else {\n header = `${mainText}\\nCarousel with ${n} items:`\n }\n\n const itemLines = elements.map((element, index) => {\n const title = element.title?.trim() || 'Item'\n const subtitle = element.subtitle?.trim()\n const subtitlePart = subtitle ? ` - ${subtitle}` : ''\n const btnLabels: string[] = []\n if (element.button) {\n btnLabels.push(\n HubtypeAssistantContent.carouselButtonLabel(element.button)\n )\n }\n const btnPart = btnLabels.length > 0 ? ` [${btnLabels.join(', ')}]` : ''\n\n return ` ${index + 1}. \"${title}\"${subtitlePart}${btnPart}`\n })\n\n return [header, ...itemLines].join('\\n')\n }\n\n private static formatWhatsappButtonListContent(\n list: FlowWhatsappButtonList\n ): string {\n const body = list.text?.trim() ?? ''\n const hasSections = list.sections.some(s => s.rows.length > 0)\n\n if (!body && !hasSections) {\n return '[WhatsApp Button List]'\n }\n\n const parts: string[] = []\n if (body) {\n parts.push(body)\n }\n\n if (hasSections) {\n const sectionBlocks = list.sections.map(section => {\n const rowLines = section.rows.map(row => {\n const rowTitle = row.title?.trim() ?? ''\n const rowDescription = row.description?.trim() ?? ''\n if (!rowTitle && !rowDescription) {\n return ' - '\n }\n if (!rowTitle) {\n return ` - ${rowDescription}`\n }\n if (!rowDescription) {\n return ` - ${rowTitle}`\n }\n return ` - ${rowTitle}: ${rowDescription}`\n })\n const rowsText = rowLines.join('\\n')\n\n const sectionTitle = section.title?.trim()\n if (sectionTitle) {\n return `${sectionTitle}:\\n${rowsText}`\n }\n\n return rowsText\n })\n parts.push(sectionBlocks.join('\\n'))\n }\n\n return parts.join('\\n\\n')\n }\n\n private static formatWhatsappCtaContent(\n cta: FlowWhatsappCtaUrlButtonNode\n ): string {\n const hasStructuredData =\n (cta.headerType === WhatsappCTAUrlHeaderType.Text &&\n !!cta.header?.trim()) ||\n cta.text?.trim() ||\n cta.footer?.trim() ||\n cta.displayText?.trim() ||\n cta.url\n\n if (!hasStructuredData) {\n return cta.text?.trim() || '[WhatsApp CTA Button]'\n }\n\n const lines: string[] = []\n if (\n cta.headerType === WhatsappCTAUrlHeaderType.Text &&\n cta.header?.trim()\n ) {\n lines.push(cta.header.trim())\n }\n if (cta.text?.trim()) {\n lines.push(cta.text.trim())\n }\n if (cta.footer?.trim()) {\n lines.push(cta.footer.trim())\n }\n const ctaLine = `[${cta.displayText || ''}]${cta.url ? ` (${cta.url})` : ''}`\n lines.push(ctaLine)\n\n return lines.join('\\n')\n }\n\n private static formatWhatsappTemplateContent(\n template: FlowWhatsappTemplate\n ): string {\n const { name, language } = template.htWhatsappTemplate\n return `WhatsApp Template: ${name} (${language})`\n }\n}\n"],"names":["WhatsappCTAUrlHeaderType","FlowCarousel","FlowImage","FlowText","FlowVideo","FlowWhatsappCtaUrlButtonNode","FlowWhatsappTemplate","HtButtonStyle","FlowWhatsappButtonList","HubtypeAssistantContent","content","button","buttonText","text","body","buttons","isQuickReply","blockTitle","lines","i","label","block","carousel","elements","n","mainText","header","itemLines","element","index","title","subtitle","subtitlePart","btnLabels","btnPart","list","hasSections","s","parts","sectionBlocks","section","rowLines","row","rowTitle","rowDescription","rowsText","sectionTitle","cta","hasStructuredData","ctaLine","template","name","language"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils/hubtype-assistant-content.js","sources":["../../src/utils/hubtype-assistant-content.ts"],"sourcesContent":["import { WhatsappCTAUrlHeaderType } from '@botonic/react'\nimport type { FlowContent } from '../content-fields'\nimport type { FlowButton } from '../content-fields/flow-button'\nimport { FlowCarousel } from '../content-fields/flow-carousel'\nimport { FlowImage } from '../content-fields/flow-image'\nimport { FlowText } from '../content-fields/flow-text'\nimport { FlowVideo } from '../content-fields/flow-video'\nimport { FlowWhatsappCtaUrlButtonNode } from '../content-fields/flow-whatsapp-cta-url-button'\nimport { FlowWhatsappRequestContactInfoNode } from '../content-fields/flow-whatsapp-request-contact-info'\nimport { FlowWhatsappTemplate } from '../content-fields/flow-whatsapp-template'\nimport { HtButtonStyle } from '../content-fields/hubtype-fields'\nimport { FlowWhatsappButtonList } from '../content-fields/whatsapp-button-list/flow-whatsapp-button-list'\n\n// biome-ignore lint/complexity/noStaticOnlyClass: namespace-like adapter with private static helpers\nexport class HubtypeAssistantContent {\n static adapt(content: FlowContent): string {\n if (content instanceof FlowText) {\n return HubtypeAssistantContent.formatFlowTextContent(content)\n }\n if (content instanceof FlowCarousel) {\n return HubtypeAssistantContent.formatCarouselContent(content)\n }\n if (content instanceof FlowImage) {\n return content.src ? `[Image]\\n${content.src}` : '[Image]'\n }\n if (content instanceof FlowVideo) {\n return content.src ? `[Video]\\n${content.src}` : '[Video]'\n }\n if (content instanceof FlowWhatsappButtonList) {\n return HubtypeAssistantContent.formatWhatsappButtonListContent(content)\n }\n if (content instanceof FlowWhatsappCtaUrlButtonNode) {\n return HubtypeAssistantContent.formatWhatsappCtaContent(content)\n }\n if (content instanceof FlowWhatsappTemplate) {\n return HubtypeAssistantContent.formatWhatsappTemplateContent(content)\n }\n if (content instanceof FlowWhatsappRequestContactInfoNode) {\n return HubtypeAssistantContent.formatRequestContactInfoContent(content)\n }\n return ''\n }\n\n private static quickReplyLabel(button: FlowButton): string {\n const buttonText = button.text?.trim()\n if (buttonText) {\n return buttonText\n }\n\n return button.payload || 'Option'\n }\n\n private static persistentButtonLabel(button: FlowButton): string {\n return button.text?.trim() || 'Button'\n }\n\n private static carouselButtonLabel(button: FlowButton): string {\n return button.text?.trim() || 'Action'\n }\n\n private static formatFlowTextContent(text: FlowText): string {\n const body = text.text?.trim() ?? ''\n const buttons = text.buttons\n\n if (!body && buttons.length === 0) {\n return ''\n }\n\n if (buttons.length === 0) {\n return text.text\n }\n\n const isQuickReply = text.buttonStyle === HtButtonStyle.QUICK_REPLY\n const blockTitle = isQuickReply ? 'Quick replies:' : 'Buttons:'\n const lines = buttons.map((button, i) => {\n const label = isQuickReply\n ? HubtypeAssistantContent.quickReplyLabel(button)\n : HubtypeAssistantContent.persistentButtonLabel(button)\n return ` [${i + 1}] ${label}`\n })\n\n const block = [blockTitle, ...lines].join('\\n')\n if (!body) {\n return block\n }\n\n return `${body}\\n\\n${block}`\n }\n\n private static formatCarouselContent(carousel: FlowCarousel): string {\n const elements = carousel.elements\n const n = elements.length\n const mainText = (carousel.whatsappText ?? '').trim()\n\n if (n === 0) {\n return mainText\n }\n\n let header: string\n if (!mainText) {\n header = `Carousel displayed with ${n} items:`\n } else if (mainText.endsWith(':')) {\n header = mainText\n } else {\n header = `${mainText}\\nCarousel with ${n} items:`\n }\n\n const itemLines = elements.map((element, index) => {\n const title = element.title?.trim() || 'Item'\n const subtitle = element.subtitle?.trim()\n const subtitlePart = subtitle ? ` - ${subtitle}` : ''\n const btnLabels: string[] = []\n if (element.button) {\n btnLabels.push(\n HubtypeAssistantContent.carouselButtonLabel(element.button)\n )\n }\n const btnPart = btnLabels.length > 0 ? ` [${btnLabels.join(', ')}]` : ''\n\n return ` ${index + 1}. \"${title}\"${subtitlePart}${btnPart}`\n })\n\n return [header, ...itemLines].join('\\n')\n }\n\n private static formatWhatsappButtonListContent(\n list: FlowWhatsappButtonList\n ): string {\n const body = list.text?.trim() ?? ''\n const hasSections = list.sections.some(s => s.rows.length > 0)\n\n if (!body && !hasSections) {\n return '[WhatsApp Button List]'\n }\n\n const parts: string[] = []\n if (body) {\n parts.push(body)\n }\n\n if (hasSections) {\n const sectionBlocks = list.sections.map(section => {\n const rowLines = section.rows.map(row => {\n const rowTitle = row.title?.trim() ?? ''\n const rowDescription = row.description?.trim() ?? ''\n if (!rowTitle && !rowDescription) {\n return ' - '\n }\n if (!rowTitle) {\n return ` - ${rowDescription}`\n }\n if (!rowDescription) {\n return ` - ${rowTitle}`\n }\n return ` - ${rowTitle}: ${rowDescription}`\n })\n const rowsText = rowLines.join('\\n')\n\n const sectionTitle = section.title?.trim()\n if (sectionTitle) {\n return `${sectionTitle}:\\n${rowsText}`\n }\n\n return rowsText\n })\n parts.push(sectionBlocks.join('\\n'))\n }\n\n return parts.join('\\n\\n')\n }\n\n private static formatWhatsappCtaContent(\n cta: FlowWhatsappCtaUrlButtonNode\n ): string {\n const hasStructuredData =\n (cta.headerType === WhatsappCTAUrlHeaderType.Text &&\n !!cta.header?.trim()) ||\n cta.text?.trim() ||\n cta.footer?.trim() ||\n cta.displayText?.trim() ||\n cta.url\n\n if (!hasStructuredData) {\n return cta.text?.trim() || '[WhatsApp CTA Button]'\n }\n\n const lines: string[] = []\n if (\n cta.headerType === WhatsappCTAUrlHeaderType.Text &&\n cta.header?.trim()\n ) {\n lines.push(cta.header.trim())\n }\n if (cta.text?.trim()) {\n lines.push(cta.text.trim())\n }\n if (cta.footer?.trim()) {\n lines.push(cta.footer.trim())\n }\n const ctaLine = `[${cta.displayText || ''}]${cta.url ? ` (${cta.url})` : ''}`\n lines.push(ctaLine)\n\n return lines.join('\\n')\n }\n\n private static formatWhatsappTemplateContent(\n template: FlowWhatsappTemplate\n ): string {\n const { name, language } = template.htWhatsappTemplate\n return `WhatsApp Template: ${name} (${language})`\n }\n\n private static formatRequestContactInfoContent(\n requestContactInfo: FlowWhatsappRequestContactInfoNode\n ): string {\n const body = requestContactInfo.text?.trim() ?? ''\n if (!body) {\n return '[WhatsApp Request Contact Info]'\n }\n return requestContactInfo.text\n }\n}\n"],"names":["WhatsappCTAUrlHeaderType","FlowCarousel","FlowImage","FlowText","FlowVideo","FlowWhatsappCtaUrlButtonNode","FlowWhatsappRequestContactInfoNode","FlowWhatsappTemplate","HtButtonStyle","FlowWhatsappButtonList","HubtypeAssistantContent","content","button","buttonText","text","body","buttons","isQuickReply","blockTitle","lines","i","label","block","carousel","elements","n","mainText","header","itemLines","element","index","title","subtitle","subtitlePart","btnLabels","btnPart","list","hasSections","s","parts","sectionBlocks","section","rowLines","row","rowTitle","rowDescription","rowsText","sectionTitle","cta","hasStructuredData","ctaLine","template","name","language","requestContactInfo"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@botonic/plugin-flow-builder",
|
|
4
|
-
"version": "0.57.0-rslib-esm.
|
|
4
|
+
"version": "0.57.0-rslib-esm.2",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"module": "./lib/index.js",
|
|
7
7
|
"description": "Use Flow Builder to show your contents",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "rslib build --no-env",
|
|
10
10
|
"build:watch": "rslib build --watch --no-env",
|
|
11
|
-
"test": "
|
|
11
|
+
"test": "vitest run --coverage",
|
|
12
12
|
"cloc": "../../scripts/qa/cloc-package.sh .",
|
|
13
13
|
"prepublishOnly": "npm run build && npm run test && npm run lint",
|
|
14
14
|
"lint": "biome check --write src/ tests/",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"format": "biome format --write src/ tests/"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@botonic/react": "0.57.0-rslib-esm.
|
|
19
|
+
"@botonic/react": "0.57.0-rslib-esm.2",
|
|
20
20
|
"axios": "^1.18.1",
|
|
21
21
|
"uuid": "^10.0.0"
|
|
22
22
|
},
|
|
@@ -16,6 +16,7 @@ import { HubtypeAssistantContent } from '../utils/hubtype-assistant-content'
|
|
|
16
16
|
import { ContentFieldsBase } from './content-fields-base'
|
|
17
17
|
import { FlowCarousel } from './flow-carousel'
|
|
18
18
|
import { FlowText } from './flow-text'
|
|
19
|
+
import { FlowWhatsappRequestContactInfoNode } from './flow-whatsapp-request-contact-info'
|
|
19
20
|
import type { HtInputGuardrailRule, HtNodeWithContent } from './hubtype-fields'
|
|
20
21
|
import type { FlowContent } from './index'
|
|
21
22
|
|
|
@@ -89,6 +90,16 @@ export abstract class FlowAiAgentBase extends ContentFieldsBase {
|
|
|
89
90
|
)
|
|
90
91
|
}
|
|
91
92
|
|
|
93
|
+
if (message.type === OutputMessageType.RequestContactInfo) {
|
|
94
|
+
this.jsxElements.push(
|
|
95
|
+
FlowWhatsappRequestContactInfoNode.fromAIAgent(
|
|
96
|
+
this.id,
|
|
97
|
+
message,
|
|
98
|
+
botContext
|
|
99
|
+
)
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
92
103
|
if (message.type === FlowBuilderOutputMessageType.FlowBuilderContent) {
|
|
93
104
|
const flowContents = await this.getFlowContentsByContentId(
|
|
94
105
|
botContext,
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type BotContext,
|
|
3
|
+
isWhatsapp,
|
|
4
|
+
type RequestContactInfoMessage,
|
|
5
|
+
} from '@botonic/core'
|
|
2
6
|
import { Text, WhatsappRequestContactInfo } from '@botonic/react'
|
|
3
7
|
|
|
4
8
|
import { trackOneContent } from '../tracking'
|
|
@@ -26,6 +30,18 @@ export class FlowWhatsappRequestContactInfoNode extends ContentFieldsBase {
|
|
|
26
30
|
return requestContactInfo
|
|
27
31
|
}
|
|
28
32
|
|
|
33
|
+
static fromAIAgent(
|
|
34
|
+
id: string,
|
|
35
|
+
message: RequestContactInfoMessage,
|
|
36
|
+
botContext: BotContext
|
|
37
|
+
): JSX.Element {
|
|
38
|
+
if (!isWhatsapp(botContext.session)) {
|
|
39
|
+
return <Text key={id}>{message.content.text}</Text>
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return <WhatsappRequestContactInfo key={id} body={message.content.text} />
|
|
43
|
+
}
|
|
44
|
+
|
|
29
45
|
async trackFlow(botContext: BotContext): Promise<void> {
|
|
30
46
|
await trackOneContent(botContext, this)
|
|
31
47
|
}
|
|
@@ -6,6 +6,7 @@ import { FlowImage } from '../content-fields/flow-image'
|
|
|
6
6
|
import { FlowText } from '../content-fields/flow-text'
|
|
7
7
|
import { FlowVideo } from '../content-fields/flow-video'
|
|
8
8
|
import { FlowWhatsappCtaUrlButtonNode } from '../content-fields/flow-whatsapp-cta-url-button'
|
|
9
|
+
import { FlowWhatsappRequestContactInfoNode } from '../content-fields/flow-whatsapp-request-contact-info'
|
|
9
10
|
import { FlowWhatsappTemplate } from '../content-fields/flow-whatsapp-template'
|
|
10
11
|
import { HtButtonStyle } from '../content-fields/hubtype-fields'
|
|
11
12
|
import { FlowWhatsappButtonList } from '../content-fields/whatsapp-button-list/flow-whatsapp-button-list'
|
|
@@ -34,6 +35,9 @@ export class HubtypeAssistantContent {
|
|
|
34
35
|
if (content instanceof FlowWhatsappTemplate) {
|
|
35
36
|
return HubtypeAssistantContent.formatWhatsappTemplateContent(content)
|
|
36
37
|
}
|
|
38
|
+
if (content instanceof FlowWhatsappRequestContactInfoNode) {
|
|
39
|
+
return HubtypeAssistantContent.formatRequestContactInfoContent(content)
|
|
40
|
+
}
|
|
37
41
|
return ''
|
|
38
42
|
}
|
|
39
43
|
|
|
@@ -205,4 +209,14 @@ export class HubtypeAssistantContent {
|
|
|
205
209
|
const { name, language } = template.htWhatsappTemplate
|
|
206
210
|
return `WhatsApp Template: ${name} (${language})`
|
|
207
211
|
}
|
|
212
|
+
|
|
213
|
+
private static formatRequestContactInfoContent(
|
|
214
|
+
requestContactInfo: FlowWhatsappRequestContactInfoNode
|
|
215
|
+
): string {
|
|
216
|
+
const body = requestContactInfo.text?.trim() ?? ''
|
|
217
|
+
if (!body) {
|
|
218
|
+
return '[WhatsApp Request Contact Info]'
|
|
219
|
+
}
|
|
220
|
+
return requestContactInfo.text
|
|
221
|
+
}
|
|
208
222
|
}
|