@botonic/plugin-flow-builder 0.22.0-alpha.2 → 0.22.0
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/cjs/action.js +14 -12
- package/lib/cjs/action.js.map +1 -1
- package/lib/cjs/api.d.ts +19 -0
- package/lib/cjs/api.js +108 -0
- package/lib/cjs/api.js.map +1 -0
- package/lib/cjs/content-fields/content-fields-base.d.ts +4 -4
- package/lib/cjs/content-fields/content-fields-base.js.map +1 -1
- package/lib/cjs/content-fields/flow-button.d.ts +6 -3
- package/lib/cjs/content-fields/flow-button.js +28 -21
- package/lib/cjs/content-fields/flow-button.js.map +1 -1
- package/lib/cjs/content-fields/flow-carousel.d.ts +3 -2
- package/lib/cjs/content-fields/flow-carousel.js +3 -10
- package/lib/cjs/content-fields/flow-carousel.js.map +1 -1
- package/lib/cjs/content-fields/flow-element.d.ts +6 -3
- package/lib/cjs/content-fields/flow-element.js +16 -5
- package/lib/cjs/content-fields/flow-element.js.map +1 -1
- package/lib/cjs/content-fields/flow-image.d.ts +2 -2
- package/lib/cjs/content-fields/flow-image.js.map +1 -1
- package/lib/cjs/content-fields/flow-text.d.ts +4 -3
- package/lib/cjs/content-fields/flow-text.js +9 -9
- package/lib/cjs/content-fields/flow-text.js.map +1 -1
- package/lib/cjs/content-fields/flow-video.d.ts +2 -2
- package/lib/cjs/content-fields/flow-video.js +0 -1
- package/lib/cjs/content-fields/flow-video.js.map +1 -1
- package/lib/cjs/content-fields/hubtype-fields/button.d.ts +9 -0
- package/lib/cjs/content-fields/hubtype-fields/button.js +3 -0
- package/lib/cjs/content-fields/hubtype-fields/button.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/carousel.d.ts +16 -0
- package/lib/cjs/content-fields/hubtype-fields/carousel.js +3 -0
- package/lib/cjs/content-fields/hubtype-fields/carousel.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/common.d.ts +55 -0
- package/lib/cjs/content-fields/hubtype-fields/common.js +3 -0
- package/lib/cjs/content-fields/hubtype-fields/common.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/fallback.d.ts +9 -0
- package/lib/cjs/content-fields/hubtype-fields/fallback.js +3 -0
- package/lib/cjs/content-fields/hubtype-fields/fallback.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/function.d.ts +28 -0
- package/lib/cjs/content-fields/hubtype-fields/function.js +10 -0
- package/lib/cjs/content-fields/hubtype-fields/function.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/handoff.d.ts +10 -0
- package/lib/cjs/content-fields/hubtype-fields/handoff.js +3 -0
- package/lib/cjs/content-fields/hubtype-fields/handoff.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/image.d.ts +8 -0
- package/lib/cjs/content-fields/{types.js → hubtype-fields/image.js} +1 -1
- package/lib/cjs/content-fields/hubtype-fields/image.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/index.d.ts +17 -0
- package/lib/cjs/content-fields/hubtype-fields/index.js +21 -0
- package/lib/cjs/content-fields/hubtype-fields/index.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/intent.d.ts +10 -0
- package/lib/cjs/content-fields/hubtype-fields/intent.js +3 -0
- package/lib/cjs/content-fields/hubtype-fields/intent.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/keyword.d.ts +9 -0
- package/lib/cjs/content-fields/hubtype-fields/keyword.js +3 -0
- package/lib/cjs/content-fields/hubtype-fields/keyword.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/node-types.d.ts +23 -0
- package/lib/cjs/content-fields/hubtype-fields/node-types.js +31 -0
- package/lib/cjs/content-fields/hubtype-fields/node-types.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/nodes.d.ts +16 -0
- package/lib/cjs/content-fields/hubtype-fields/nodes.js +3 -0
- package/lib/cjs/content-fields/hubtype-fields/nodes.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/payload.d.ts +8 -0
- package/lib/cjs/content-fields/hubtype-fields/payload.js +3 -0
- package/lib/cjs/content-fields/hubtype-fields/payload.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/start.d.ts +7 -0
- package/lib/cjs/content-fields/hubtype-fields/start.js +3 -0
- package/lib/cjs/content-fields/hubtype-fields/start.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/text.d.ts +11 -0
- package/lib/cjs/content-fields/hubtype-fields/text.js +3 -0
- package/lib/cjs/content-fields/hubtype-fields/text.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/url.d.ts +8 -0
- package/lib/cjs/content-fields/hubtype-fields/url.js +3 -0
- package/lib/cjs/content-fields/hubtype-fields/url.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/video.d.ts +8 -0
- package/lib/cjs/content-fields/hubtype-fields/video.js +3 -0
- package/lib/cjs/content-fields/hubtype-fields/video.js.map +1 -0
- package/lib/cjs/content-fields/hubtype-fields/whatsapp-button-list.d.ts +21 -0
- package/lib/cjs/content-fields/hubtype-fields/whatsapp-button-list.js +3 -0
- package/lib/cjs/content-fields/hubtype-fields/whatsapp-button-list.js.map +1 -0
- package/lib/cjs/content-fields/index.d.ts +7 -5
- package/lib/cjs/content-fields/index.js +11 -9
- package/lib/cjs/content-fields/index.js.map +1 -1
- package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list-row.d.ts +10 -0
- package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list-row.js +32 -0
- package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list-row.js.map +1 -0
- package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list-section.d.ts +10 -0
- package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list-section.js +29 -0
- package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list-section.js.map +1 -0
- package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list.d.ts +12 -0
- package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list.js +33 -0
- package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list.js.map +1 -0
- package/lib/cjs/functions/conditional-queue-status.js +1 -3
- package/lib/cjs/functions/conditional-queue-status.js.map +1 -1
- package/lib/cjs/handoff.d.ts +2 -2
- package/lib/cjs/handoff.js +13 -7
- package/lib/cjs/handoff.js.map +1 -1
- package/lib/cjs/helpers.d.ts +2 -1
- package/lib/cjs/helpers.js +5 -13
- package/lib/cjs/helpers.js.map +1 -1
- package/lib/cjs/index.d.ts +8 -21
- package/lib/cjs/index.js +34 -150
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/types.d.ts +6 -2
- package/lib/cjs/types.js.map +1 -1
- package/lib/esm/action.js +14 -12
- package/lib/esm/action.js.map +1 -1
- package/lib/esm/api.d.ts +19 -0
- package/lib/esm/api.js +103 -0
- package/lib/esm/api.js.map +1 -0
- package/lib/esm/content-fields/content-fields-base.d.ts +4 -4
- package/lib/esm/content-fields/content-fields-base.js.map +1 -1
- package/lib/esm/content-fields/flow-button.d.ts +6 -3
- package/lib/esm/content-fields/flow-button.js +28 -21
- package/lib/esm/content-fields/flow-button.js.map +1 -1
- package/lib/esm/content-fields/flow-carousel.d.ts +3 -2
- package/lib/esm/content-fields/flow-carousel.js +4 -11
- package/lib/esm/content-fields/flow-carousel.js.map +1 -1
- package/lib/esm/content-fields/flow-element.d.ts +6 -3
- package/lib/esm/content-fields/flow-element.js +15 -5
- package/lib/esm/content-fields/flow-element.js.map +1 -1
- package/lib/esm/content-fields/flow-image.d.ts +2 -2
- package/lib/esm/content-fields/flow-image.js.map +1 -1
- package/lib/esm/content-fields/flow-text.d.ts +4 -3
- package/lib/esm/content-fields/flow-text.js +9 -9
- package/lib/esm/content-fields/flow-text.js.map +1 -1
- package/lib/esm/content-fields/flow-video.d.ts +2 -2
- package/lib/esm/content-fields/flow-video.js +0 -1
- package/lib/esm/content-fields/flow-video.js.map +1 -1
- package/lib/esm/content-fields/hubtype-fields/button.d.ts +9 -0
- package/lib/esm/content-fields/hubtype-fields/button.js +2 -0
- package/lib/esm/content-fields/hubtype-fields/button.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/carousel.d.ts +16 -0
- package/lib/esm/content-fields/hubtype-fields/carousel.js +2 -0
- package/lib/esm/content-fields/hubtype-fields/carousel.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/common.d.ts +55 -0
- package/lib/esm/content-fields/hubtype-fields/common.js +2 -0
- package/lib/esm/content-fields/hubtype-fields/common.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/fallback.d.ts +9 -0
- package/lib/esm/content-fields/hubtype-fields/fallback.js +2 -0
- package/lib/esm/content-fields/hubtype-fields/fallback.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/function.d.ts +28 -0
- package/lib/esm/content-fields/hubtype-fields/function.js +7 -0
- package/lib/esm/content-fields/hubtype-fields/function.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/handoff.d.ts +10 -0
- package/lib/esm/content-fields/hubtype-fields/handoff.js +2 -0
- package/lib/esm/content-fields/hubtype-fields/handoff.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/image.d.ts +8 -0
- package/lib/esm/content-fields/hubtype-fields/image.js +2 -0
- package/lib/esm/content-fields/hubtype-fields/image.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/index.d.ts +17 -0
- package/lib/esm/content-fields/hubtype-fields/index.js +18 -0
- package/lib/esm/content-fields/hubtype-fields/index.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/intent.d.ts +10 -0
- package/lib/esm/content-fields/hubtype-fields/intent.js +2 -0
- package/lib/esm/content-fields/hubtype-fields/intent.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/keyword.d.ts +9 -0
- package/lib/esm/content-fields/hubtype-fields/keyword.js +2 -0
- package/lib/esm/content-fields/hubtype-fields/keyword.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/node-types.d.ts +23 -0
- package/lib/esm/content-fields/hubtype-fields/node-types.js +28 -0
- package/lib/esm/content-fields/hubtype-fields/node-types.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/nodes.d.ts +16 -0
- package/lib/esm/content-fields/hubtype-fields/nodes.js +2 -0
- package/lib/esm/content-fields/hubtype-fields/nodes.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/payload.d.ts +8 -0
- package/lib/esm/content-fields/hubtype-fields/payload.js +2 -0
- package/lib/esm/content-fields/hubtype-fields/payload.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/start.d.ts +7 -0
- package/lib/esm/content-fields/hubtype-fields/start.js +2 -0
- package/lib/esm/content-fields/hubtype-fields/start.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/text.d.ts +11 -0
- package/lib/esm/content-fields/hubtype-fields/text.js +2 -0
- package/lib/esm/content-fields/hubtype-fields/text.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/url.d.ts +8 -0
- package/lib/esm/content-fields/hubtype-fields/url.js +2 -0
- package/lib/esm/content-fields/hubtype-fields/url.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/video.d.ts +8 -0
- package/lib/esm/content-fields/hubtype-fields/video.js +2 -0
- package/lib/esm/content-fields/hubtype-fields/video.js.map +1 -0
- package/lib/esm/content-fields/hubtype-fields/whatsapp-button-list.d.ts +21 -0
- package/lib/esm/content-fields/hubtype-fields/whatsapp-button-list.js +2 -0
- package/lib/esm/content-fields/hubtype-fields/whatsapp-button-list.js.map +1 -0
- package/lib/esm/content-fields/index.d.ts +7 -5
- package/lib/esm/content-fields/index.js +6 -4
- package/lib/esm/content-fields/index.js.map +1 -1
- package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list-row.d.ts +10 -0
- package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list-row.js +28 -0
- package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list-row.js.map +1 -0
- package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list-section.d.ts +10 -0
- package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list-section.js +25 -0
- package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list-section.js.map +1 -0
- package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list.d.ts +12 -0
- package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list.js +28 -0
- package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list.js.map +1 -0
- package/lib/esm/functions/conditional-queue-status.js +1 -3
- package/lib/esm/functions/conditional-queue-status.js.map +1 -1
- package/lib/esm/handoff.d.ts +2 -2
- package/lib/esm/handoff.js +13 -7
- package/lib/esm/handoff.js.map +1 -1
- package/lib/esm/helpers.d.ts +2 -1
- package/lib/esm/helpers.js +3 -11
- package/lib/esm/helpers.js.map +1 -1
- package/lib/esm/index.d.ts +8 -21
- package/lib/esm/index.js +36 -152
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/types.d.ts +6 -2
- package/lib/esm/types.js.map +1 -1
- package/package.json +4 -5
- package/src/action.tsx +19 -12
- package/src/api.ts +162 -0
- package/src/content-fields/content-fields-base.ts +7 -7
- package/src/content-fields/flow-button.tsx +40 -19
- package/src/content-fields/flow-carousel.tsx +10 -18
- package/src/content-fields/flow-element.tsx +26 -9
- package/src/content-fields/flow-image.tsx +2 -2
- package/src/content-fields/flow-text.tsx +15 -12
- package/src/content-fields/flow-video.tsx +2 -3
- package/src/content-fields/hubtype-fields/button.ts +15 -0
- package/src/content-fields/hubtype-fields/carousel.ts +18 -0
- package/src/content-fields/hubtype-fields/common.ts +65 -0
- package/src/content-fields/hubtype-fields/fallback.ts +10 -0
- package/src/content-fields/hubtype-fields/function.ts +33 -0
- package/src/content-fields/hubtype-fields/handoff.ts +11 -0
- package/src/content-fields/hubtype-fields/image.ts +9 -0
- package/src/content-fields/hubtype-fields/index.ts +17 -0
- package/src/content-fields/hubtype-fields/intent.ts +11 -0
- package/src/content-fields/hubtype-fields/keyword.ts +10 -0
- package/src/content-fields/hubtype-fields/node-types.ts +26 -0
- package/src/content-fields/hubtype-fields/nodes.ts +32 -0
- package/src/content-fields/hubtype-fields/payload.ts +9 -0
- package/src/content-fields/hubtype-fields/start.ts +8 -0
- package/src/content-fields/hubtype-fields/text.ts +12 -0
- package/src/content-fields/hubtype-fields/url.ts +9 -0
- package/src/content-fields/hubtype-fields/video.ts +9 -0
- package/src/content-fields/hubtype-fields/whatsapp-button-list.ts +25 -0
- package/src/content-fields/index.ts +14 -5
- package/src/content-fields/whatsapp-button-list/flow-whatsapp-button-list-row.tsx +33 -0
- package/src/content-fields/whatsapp-button-list/flow-whatsapp-button-list-section.tsx +35 -0
- package/src/content-fields/whatsapp-button-list/flow-whatsapp-button-list.tsx +46 -0
- package/src/functions/conditional-queue-status.ts +1 -3
- package/src/handoff.ts +16 -10
- package/src/helpers.ts +8 -19
- package/src/index.ts +47 -196
- package/src/types.ts +8 -2
- package/lib/cjs/content-fields/types.d.ts +0 -5
- package/lib/cjs/content-fields/types.js.map +0 -1
- package/lib/cjs/flow-builder-models.d.ts +0 -197
- package/lib/cjs/flow-builder-models.js +0 -24
- package/lib/cjs/flow-builder-models.js.map +0 -1
- package/lib/esm/content-fields/types.d.ts +0 -5
- package/lib/esm/content-fields/types.js +0 -2
- package/lib/esm/content-fields/types.js.map +0 -1
- package/lib/esm/flow-builder-models.d.ts +0 -197
- package/lib/esm/flow-builder-models.js +0 -21
- package/lib/esm/flow-builder-models.js.map +0 -1
- package/src/content-fields/types.ts +0 -6
- package/src/flow-builder-models.ts +0 -249
package/lib/esm/helpers.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { HtNodeWithContentType, } from './content-fields/hubtype-fields';
|
|
1
2
|
const FLOW_BUILDER_PLUGIN_NAME = 'BotonicPluginFlowBuilder';
|
|
2
3
|
export function getFlowBuilderPlugin(plugins) {
|
|
3
4
|
const flowBuilderPlugin = Object.values(plugins).find(
|
|
@@ -7,16 +8,7 @@ export function getFlowBuilderPlugin(plugins) {
|
|
|
7
8
|
throw new Error(`You must include '@botonic/plugin-flow-builder' in your plugins file.`);
|
|
8
9
|
return flowBuilderPlugin;
|
|
9
10
|
}
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
for (const i in hubtypeContent.content[contentKey]) {
|
|
13
|
-
const button = hubtypeContent.content[contentKey][i].button;
|
|
14
|
-
if (button === null || button === void 0 ? void 0 : button.url) {
|
|
15
|
-
for (const j in button.url) {
|
|
16
|
-
button.url[j] = Object.assign(Object.assign({}, button.url[j]), (await getContentFn(button.url[j].id)));
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
11
|
+
export function isHandoffNode(node) {
|
|
12
|
+
return node.type === HtNodeWithContentType.HANDOFF;
|
|
21
13
|
}
|
|
22
14
|
//# sourceMappingURL=helpers.js.map
|
package/lib/esm/helpers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,qBAAqB,GACtB,MAAM,iCAAiC,CAAA;AAGxC,MAAM,wBAAwB,GAAG,0BAA0B,CAAA;AAE3D,MAAM,UAAU,oBAAoB,CAAC,OAEpC;IACC,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI;IACnD,aAAa;IACb,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAC7B,CAAA;IAC7B,IAAI,CAAC,iBAAiB;QACpB,MAAM,IAAI,KAAK,CACb,uEAAuE,CACxE,CAAA;IACH,OAAO,iBAAiB,CAAA;AAC1B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAuB;IACnD,OAAO,IAAI,CAAC,IAAI,KAAK,qBAAqB,CAAC,OAAO,CAAA;AACpD,CAAC"}
|
package/lib/esm/index.d.ts
CHANGED
|
@@ -1,38 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Plugin, PluginPostRequest, PluginPreRequest, Session } from '@botonic/core';
|
|
2
2
|
import { ActionRequest } from '@botonic/react';
|
|
3
|
+
import { FlowBuilderApi } from './api';
|
|
3
4
|
import { FlowContent } from './content-fields';
|
|
4
|
-
import {
|
|
5
|
+
import { HtFunctionNode, HtHandoffNode, HtNodeWithContent } from './content-fields/hubtype-fields';
|
|
5
6
|
import { BotonicPluginFlowBuilderOptions } from './types';
|
|
6
7
|
export default class BotonicPluginFlowBuilder implements Plugin {
|
|
7
8
|
readonly options: BotonicPluginFlowBuilderOptions;
|
|
8
|
-
|
|
9
|
-
private flow;
|
|
9
|
+
cmsApi: FlowBuilderApi;
|
|
10
10
|
private functions;
|
|
11
11
|
private currentRequest;
|
|
12
12
|
private getAccessToken;
|
|
13
13
|
getLocale: (session: Session) => string;
|
|
14
14
|
trackEvent?: (request: ActionRequest, eventName: string, args?: Record<string, any>) => Promise<void>;
|
|
15
15
|
constructor(options: BotonicPluginFlowBuilderOptions);
|
|
16
|
-
readFlowContent(session: Session): Promise<FlowBuilderData>;
|
|
17
16
|
pre(request: PluginPreRequest): Promise<void>;
|
|
18
17
|
post(_request: PluginPostRequest): Promise<void>;
|
|
19
|
-
getContent(
|
|
20
|
-
getContentByCode(code: string): Promise<NodeComponent>;
|
|
21
|
-
getHandoffContent(handoffTargetId: string | undefined): Promise<HandoffNode | undefined>;
|
|
22
|
-
getFlowContent(hubtypeContent: NodeComponent, locale: string): FlowContent | undefined;
|
|
23
|
-
getStartId(): Promise<string>;
|
|
24
|
-
getFallbackId(alternate: boolean): Promise<string>;
|
|
25
|
-
getContents(id: string, locale: string, prevContents?: FlowContent[]): Promise<{
|
|
18
|
+
getContent(nodeOrId: HtNodeWithContent | string, locale: string, prevContents?: FlowContent[]): Promise<{
|
|
26
19
|
contents: FlowContent[];
|
|
27
|
-
handoffNode
|
|
20
|
+
handoffNode?: HtHandoffNode;
|
|
28
21
|
}>;
|
|
29
|
-
private
|
|
30
|
-
|
|
31
|
-
hasIntent(node: IntentNode, intent: string, locale: string): boolean;
|
|
32
|
-
hasMetConfidenceThreshold(node: IntentNode, predictedConfidence: number): boolean;
|
|
33
|
-
getPayloadByKeyword(input: Input, locale: string): Promise<string | undefined>;
|
|
34
|
-
matchKeywords(node: KeywordNode, input: string, locale: string): boolean;
|
|
35
|
-
containsAnyKeywords(input: string, keywords: string[]): boolean;
|
|
36
|
-
callFunction(functionNode: FunctionNode, locale: string): Promise<string>;
|
|
22
|
+
private getFlowContent;
|
|
23
|
+
callFunction(functionNode: HtFunctionNode, locale: string): Promise<string>;
|
|
37
24
|
}
|
|
38
25
|
export * from './action';
|
package/lib/esm/index.js
CHANGED
|
@@ -1,178 +1,62 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { FlowCarousel, FlowImage, FlowText, FlowVideo, } from './content-fields';
|
|
3
|
-
import {
|
|
1
|
+
import { FlowBuilderApi } from './api';
|
|
2
|
+
import { FlowCarousel, FlowImage, FlowText, FlowVideo, FlowWhatsappButtonList, } from './content-fields';
|
|
3
|
+
import { HtNodeWithContentType, } from './content-fields/hubtype-fields';
|
|
4
4
|
import { DEFAULT_FUNCTIONS } from './functions';
|
|
5
|
-
import {
|
|
5
|
+
import { isHandoffNode } from './helpers';
|
|
6
6
|
import { resolveGetAccessToken } from './utils';
|
|
7
7
|
export default class BotonicPluginFlowBuilder {
|
|
8
8
|
constructor(options) {
|
|
9
9
|
this.options = options;
|
|
10
|
+
this.cmsApi = new FlowBuilderApi({
|
|
11
|
+
url: options.flowUrl,
|
|
12
|
+
flow: options.flow,
|
|
13
|
+
});
|
|
10
14
|
this.getLocale = options.getLocale;
|
|
11
15
|
this.getAccessToken = resolveGetAccessToken(options);
|
|
12
16
|
this.trackEvent = options.trackEvent;
|
|
13
|
-
this.flowUrl = options.flowUrl;
|
|
14
|
-
if (options.flow)
|
|
15
|
-
this.flow = options.flow;
|
|
16
17
|
const customFunctions = options.customFunctions || {};
|
|
17
18
|
this.functions = Object.assign(Object.assign({}, DEFAULT_FUNCTIONS), customFunctions);
|
|
18
19
|
}
|
|
19
|
-
async readFlowContent(session) {
|
|
20
|
-
const { data } = await axios.get(this.flowUrl, {
|
|
21
|
-
headers: { Authorization: `Bearer ${this.getAccessToken(session)}` },
|
|
22
|
-
});
|
|
23
|
-
return data;
|
|
24
|
-
}
|
|
25
20
|
async pre(request) {
|
|
26
21
|
this.currentRequest = request;
|
|
27
|
-
|
|
22
|
+
await this.cmsApi.init(this.getAccessToken(request.session));
|
|
28
23
|
}
|
|
29
24
|
async post(_request) { }
|
|
30
|
-
async getContent(
|
|
31
|
-
const flow = await this.flow;
|
|
32
|
-
const content = flow.nodes.find(node => node.id === id);
|
|
33
|
-
if (!content)
|
|
34
|
-
throw Error(`Node with id: '${id}' not found`);
|
|
35
|
-
return content;
|
|
36
|
-
}
|
|
37
|
-
async getContentByCode(code) {
|
|
38
|
-
const flow = await this.flow;
|
|
39
|
-
const content = flow.nodes.find(node => {
|
|
40
|
-
if ('code' in node)
|
|
41
|
-
return node.code === code;
|
|
42
|
-
return undefined;
|
|
43
|
-
});
|
|
44
|
-
if (!content)
|
|
45
|
-
throw Error(`Node with code: '${code}' not found`);
|
|
46
|
-
return content;
|
|
47
|
-
}
|
|
48
|
-
async getHandoffContent(handoffTargetId) {
|
|
49
|
-
if (!handoffTargetId)
|
|
50
|
-
return undefined;
|
|
51
|
-
return (await this.getContent(handoffTargetId));
|
|
52
|
-
}
|
|
53
|
-
getFlowContent(hubtypeContent, locale) {
|
|
54
|
-
switch (hubtypeContent.type) {
|
|
55
|
-
case NodeType.TEXT:
|
|
56
|
-
return FlowText.fromHubtypeCMS(hubtypeContent, locale);
|
|
57
|
-
case NodeType.IMAGE:
|
|
58
|
-
return FlowImage.fromHubtypeCMS(hubtypeContent, locale);
|
|
59
|
-
case NodeType.CAROUSEL:
|
|
60
|
-
return FlowCarousel.fromHubtypeCMS(hubtypeContent, locale);
|
|
61
|
-
case NodeType.VIDEO:
|
|
62
|
-
return FlowVideo.fromHubtypeCMS(hubtypeContent, locale);
|
|
63
|
-
default:
|
|
64
|
-
return undefined;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
async getStartId() {
|
|
68
|
-
const flow = await this.flow;
|
|
69
|
-
const startNode = flow.nodes.find(node => node.type === NodeType.START_UP);
|
|
70
|
-
if (!startNode)
|
|
71
|
-
throw new Error('start-up id must be defined');
|
|
72
|
-
return startNode.target.id;
|
|
73
|
-
}
|
|
74
|
-
async getFallbackId(alternate) {
|
|
75
|
-
const flow = await this.flow;
|
|
76
|
-
const fallbackNode = flow.nodes.find(node => node.type === NodeType.FALLBACK);
|
|
77
|
-
if (!fallbackNode)
|
|
78
|
-
throw new Error('fallback node must be defined');
|
|
79
|
-
const fallbackFirstMessage = fallbackNode.content.first_message;
|
|
80
|
-
const fallbackSecondMessage = fallbackNode.content.second_message;
|
|
81
|
-
if (!fallbackSecondMessage)
|
|
82
|
-
return fallbackFirstMessage.id;
|
|
83
|
-
return alternate ? fallbackFirstMessage.id : fallbackSecondMessage.id;
|
|
84
|
-
}
|
|
85
|
-
async getContents(id, locale, prevContents) {
|
|
25
|
+
async getContent(nodeOrId, locale, prevContents) {
|
|
86
26
|
const contents = prevContents || [];
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
await
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const targetId = await this.callFunction(hubtypeContent, locale);
|
|
96
|
-
return this.getContents(targetId, locale, contents);
|
|
27
|
+
let node = nodeOrId;
|
|
28
|
+
if (typeof nodeOrId === 'string') {
|
|
29
|
+
node = this.cmsApi.getNode(nodeOrId);
|
|
30
|
+
}
|
|
31
|
+
const content = await this.getFlowContent(node, locale);
|
|
32
|
+
if (node.type === HtNodeWithContentType.FUNCTION) {
|
|
33
|
+
const targetId = await this.callFunction(node, locale);
|
|
34
|
+
return this.getContent(targetId, locale, contents);
|
|
97
35
|
}
|
|
98
36
|
else {
|
|
99
37
|
if (content)
|
|
100
38
|
contents.push(content);
|
|
101
39
|
// TODO: prevent infinite recursive calls
|
|
102
|
-
if (
|
|
103
|
-
return this.
|
|
40
|
+
if (node.follow_up)
|
|
41
|
+
return this.getContent(node.follow_up.id, locale, contents);
|
|
104
42
|
}
|
|
105
|
-
|
|
106
|
-
// return this.getContents(function result_mapping target, locale, contents)
|
|
107
|
-
return { contents, handoffNode: isHandoff && hubtypeContent };
|
|
43
|
+
return { contents, handoffNode: isHandoffNode(node) ? node : undefined };
|
|
108
44
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
try {
|
|
124
|
-
const flow = await this.flow;
|
|
125
|
-
const intents = flow.nodes.filter(node => node.type === NodeType.INTENT);
|
|
126
|
-
const inputIntent = input.intent;
|
|
127
|
-
const inputConfidence = input.confidence;
|
|
128
|
-
if (inputIntent) {
|
|
129
|
-
const matchedIntentNode = intents.find(node => inputIntent &&
|
|
130
|
-
this.hasIntent(node, inputIntent, locale) &&
|
|
131
|
-
inputConfidence &&
|
|
132
|
-
this.hasMetConfidenceThreshold(node, inputConfidence));
|
|
133
|
-
return (_a = matchedIntentNode === null || matchedIntentNode === void 0 ? void 0 : matchedIntentNode.target) === null || _a === void 0 ? void 0 : _a.id;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
catch (error) {
|
|
137
|
-
console.error('Error getting payload by input: ', error);
|
|
138
|
-
}
|
|
139
|
-
return undefined;
|
|
140
|
-
}
|
|
141
|
-
hasIntent(node, intent, locale) {
|
|
142
|
-
return node.content.intents.some(i => i.locale === locale && i.values.includes(intent));
|
|
143
|
-
}
|
|
144
|
-
hasMetConfidenceThreshold(node, predictedConfidence) {
|
|
145
|
-
const nodeConfidence = node.content.confidence / 100;
|
|
146
|
-
return predictedConfidence >= nodeConfidence;
|
|
147
|
-
}
|
|
148
|
-
async getPayloadByKeyword(input, locale) {
|
|
149
|
-
var _a;
|
|
150
|
-
try {
|
|
151
|
-
const flow = await this.flow;
|
|
152
|
-
const keywordNodes = flow.nodes.filter(node => node.type == NodeType.KEYWORD);
|
|
153
|
-
const matchedKeywordNodes = keywordNodes.filter(node =>
|
|
154
|
-
//@ts-ignore
|
|
155
|
-
this.matchKeywords(node, input.data, locale));
|
|
156
|
-
if (matchedKeywordNodes.length > 0) {
|
|
157
|
-
return (_a = matchedKeywordNodes[0].target) === null || _a === void 0 ? void 0 : _a.id;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
catch (error) {
|
|
161
|
-
console.error('Error getting payload by input: ', error);
|
|
162
|
-
}
|
|
163
|
-
return undefined;
|
|
164
|
-
}
|
|
165
|
-
matchKeywords(node, input, locale) {
|
|
166
|
-
const result = node.content.keywords.find(i => i.locale === locale && this.containsAnyKeywords(input, i.values));
|
|
167
|
-
return Boolean(result);
|
|
168
|
-
}
|
|
169
|
-
containsAnyKeywords(input, keywords) {
|
|
170
|
-
for (let i = 0; i < keywords.length; i++) {
|
|
171
|
-
if (input.includes(keywords[i])) {
|
|
172
|
-
return true;
|
|
173
|
-
}
|
|
45
|
+
getFlowContent(hubtypeContent, locale) {
|
|
46
|
+
switch (hubtypeContent.type) {
|
|
47
|
+
case HtNodeWithContentType.TEXT:
|
|
48
|
+
return FlowText.fromHubtypeCMS(hubtypeContent, locale, this.cmsApi);
|
|
49
|
+
case HtNodeWithContentType.IMAGE:
|
|
50
|
+
return FlowImage.fromHubtypeCMS(hubtypeContent, locale);
|
|
51
|
+
case HtNodeWithContentType.CAROUSEL:
|
|
52
|
+
return FlowCarousel.fromHubtypeCMS(hubtypeContent, locale, this.cmsApi);
|
|
53
|
+
case HtNodeWithContentType.VIDEO:
|
|
54
|
+
return FlowVideo.fromHubtypeCMS(hubtypeContent, locale);
|
|
55
|
+
case HtNodeWithContentType.WHATSAPP_BUTTON_LIST:
|
|
56
|
+
return FlowWhatsappButtonList.fromHubtypeCMS(hubtypeContent, locale);
|
|
57
|
+
default:
|
|
58
|
+
return undefined;
|
|
174
59
|
}
|
|
175
|
-
return false;
|
|
176
60
|
}
|
|
177
61
|
async callFunction(functionNode, locale) {
|
|
178
62
|
var _a;
|
|
@@ -186,7 +70,7 @@ export default class BotonicPluginFlowBuilder {
|
|
|
186
70
|
const functionResult = await this.functions[functionNode.content.action](args);
|
|
187
71
|
// TODO define result_mapping per locale??
|
|
188
72
|
const result = functionNode.content.result_mapping.find(r => r.result === functionResult);
|
|
189
|
-
if (!result) {
|
|
73
|
+
if (!(result === null || result === void 0 ? void 0 : result.target)) {
|
|
190
74
|
throw new Error(`No result found for result_mapping for node with id: ${functionNodeId}`);
|
|
191
75
|
}
|
|
192
76
|
return result.target.id;
|
package/lib/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/esm/types.d.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { Session } from '@botonic/core';
|
|
2
2
|
import { ActionRequest } from '@botonic/react';
|
|
3
|
-
import {
|
|
3
|
+
import { HtFlowBuilderData } from './content-fields/hubtype-fields';
|
|
4
4
|
export interface BotonicPluginFlowBuilderOptions {
|
|
5
5
|
flowUrl: string;
|
|
6
|
-
flow?:
|
|
6
|
+
flow?: HtFlowBuilderData;
|
|
7
7
|
customFunctions?: Record<any, any>;
|
|
8
8
|
getLocale: (session: Session) => string;
|
|
9
9
|
getAccessToken: () => string;
|
|
10
10
|
trackEvent?: (request: ActionRequest, eventName: string, args?: Record<string, any>) => Promise<void>;
|
|
11
11
|
}
|
|
12
|
+
export interface FlowBuilderApiOptions {
|
|
13
|
+
url: string;
|
|
14
|
+
flow?: HtFlowBuilderData;
|
|
15
|
+
}
|
|
12
16
|
export declare enum ProcessEnvNodeEnvs {
|
|
13
17
|
PRODUCTION = "production",
|
|
14
18
|
DEVELOPMENT = "development"
|
package/lib/esm/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAwBA,MAAM,CAAN,IAAY,kBAGX;AAHD,WAAY,kBAAkB;IAC5B,+CAAyB,CAAA;IACzB,iDAA2B,CAAA;AAC7B,CAAC,EAHW,kBAAkB,KAAlB,kBAAkB,QAG7B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@botonic/plugin-flow-builder",
|
|
3
|
-
"version": "0.22.0
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"main": "./lib/cjs/index.js",
|
|
5
5
|
"module": "./lib/esm/index.js",
|
|
6
6
|
"description": "Use Flow Builder to show your contents",
|
|
@@ -31,8 +31,7 @@
|
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/minipass": "^3.3.5",
|
|
33
33
|
"@types/node": "^18.16.0",
|
|
34
|
-
"@types/react": "^
|
|
35
|
-
"typescript": "^5.0.4"
|
|
34
|
+
"@types/react": "^16.14.43"
|
|
36
35
|
},
|
|
37
36
|
"keywords": [
|
|
38
37
|
"bot-framework",
|
|
@@ -48,7 +47,7 @@
|
|
|
48
47
|
},
|
|
49
48
|
"dependencies": {
|
|
50
49
|
"@babel/runtime": "^7.21.0",
|
|
51
|
-
"
|
|
52
|
-
"
|
|
50
|
+
"@botonic/react": "^0.22.0",
|
|
51
|
+
"axios": "^1.3.6"
|
|
53
52
|
}
|
|
54
53
|
}
|
package/src/action.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import { ActionRequest, Multichannel, RequestContext } from '@botonic/react'
|
|
|
2
2
|
import React from 'react'
|
|
3
3
|
|
|
4
4
|
import { FlowContent } from './content-fields'
|
|
5
|
+
import { HtNodeWithContent } from './content-fields/hubtype-fields'
|
|
5
6
|
import { doHandoff } from './handoff'
|
|
6
7
|
import { getFlowBuilderPlugin } from './helpers'
|
|
7
8
|
|
|
@@ -18,31 +19,37 @@ export class FlowBuilderAction extends React.Component<FlowBuilderActionProps> {
|
|
|
18
19
|
const flowBuilderPlugin = getFlowBuilderPlugin(request.plugins)
|
|
19
20
|
const locale = flowBuilderPlugin.getLocale(request.session)
|
|
20
21
|
const payload = request.input.payload
|
|
21
|
-
let
|
|
22
|
+
let targetNode: HtNodeWithContent | string | undefined = payload
|
|
23
|
+
|
|
22
24
|
if (!payload && request.session.is_first_interaction) {
|
|
23
|
-
|
|
25
|
+
targetNode = flowBuilderPlugin.cmsApi.getStartNode()
|
|
24
26
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
|
|
28
|
+
if (!payload && request.input.data) {
|
|
29
|
+
const intentNode = flowBuilderPlugin.cmsApi.getNodeByIntent(
|
|
27
30
|
request.input,
|
|
28
31
|
locale
|
|
29
32
|
)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
request.input,
|
|
33
|
+
const keywordNode = flowBuilderPlugin.cmsApi.getNodeByKeyword(
|
|
34
|
+
request.input.data,
|
|
33
35
|
locale
|
|
34
36
|
)
|
|
35
|
-
if (
|
|
37
|
+
if (intentNode) {
|
|
38
|
+
targetNode = intentNode
|
|
39
|
+
} else if (keywordNode) {
|
|
40
|
+
targetNode = keywordNode
|
|
41
|
+
}
|
|
36
42
|
}
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
|
|
44
|
+
if (!targetNode) {
|
|
45
|
+
targetNode = flowBuilderPlugin.cmsApi.getFallbackNode(
|
|
39
46
|
alternateFallbackMessage
|
|
40
47
|
)
|
|
41
48
|
alternateFallbackMessage = !alternateFallbackMessage
|
|
42
49
|
}
|
|
43
50
|
|
|
44
|
-
const { contents, handoffNode } = await flowBuilderPlugin.
|
|
45
|
-
|
|
51
|
+
const { contents, handoffNode } = await flowBuilderPlugin.getContent(
|
|
52
|
+
targetNode,
|
|
46
53
|
locale
|
|
47
54
|
)
|
|
48
55
|
|
package/src/api.ts
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { Input } from '@botonic/core'
|
|
2
|
+
import axios from 'axios/index'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
HtFallbackNode,
|
|
6
|
+
HtFlowBuilderData,
|
|
7
|
+
HtIntentNode,
|
|
8
|
+
HtKeywordNode,
|
|
9
|
+
HtNodeComponent,
|
|
10
|
+
HtNodeStartType,
|
|
11
|
+
HtNodeWithContent,
|
|
12
|
+
HtNodeWithContentType,
|
|
13
|
+
HtStartNode,
|
|
14
|
+
} from './content-fields/hubtype-fields'
|
|
15
|
+
import { FlowBuilderApiOptions } from './types'
|
|
16
|
+
|
|
17
|
+
export class FlowBuilderApi {
|
|
18
|
+
private readonly url: string
|
|
19
|
+
public flow: HtFlowBuilderData
|
|
20
|
+
|
|
21
|
+
constructor(options: FlowBuilderApiOptions) {
|
|
22
|
+
this.url = options.url
|
|
23
|
+
if (options.flow) {
|
|
24
|
+
this.flow = options.flow
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async init(token: string) {
|
|
29
|
+
const { data } = await axios.get(this.url, {
|
|
30
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
31
|
+
})
|
|
32
|
+
this.flow = data
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
getNode<T extends HtNodeComponent>(id: string): T {
|
|
36
|
+
const node = this.flow.nodes.find(node => node.id === id)
|
|
37
|
+
if (!node) throw Error(`Node with id: '${id}' not found`)
|
|
38
|
+
return node as T
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
getNodeByCode(code: string): HtNodeComponent {
|
|
42
|
+
const content = this.flow.nodes.find(node =>
|
|
43
|
+
'code' in node ? node.code === code : false
|
|
44
|
+
)
|
|
45
|
+
if (!content) throw Error(`Node with code: '${code}' not found`)
|
|
46
|
+
return content
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
getStartNode(): HtNodeWithContent {
|
|
50
|
+
const startUpNode = this.flow.nodes.find(
|
|
51
|
+
node => node.type === HtNodeStartType.STARTUP
|
|
52
|
+
) as HtStartNode | undefined
|
|
53
|
+
if (!startUpNode) throw new Error('Start-up id must be defined')
|
|
54
|
+
return this.getNode(startUpNode.target.id)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
getFallbackNode(alternate: boolean): HtNodeWithContent {
|
|
58
|
+
const fallbackNode = this.flow.nodes.find(
|
|
59
|
+
node => node.type === HtNodeWithContentType.FALLBACK
|
|
60
|
+
) as HtFallbackNode | undefined
|
|
61
|
+
if (!fallbackNode) {
|
|
62
|
+
throw new Error('Fallback node must be defined')
|
|
63
|
+
}
|
|
64
|
+
const fallbackFirstMessage = fallbackNode.content.first_message
|
|
65
|
+
if (!fallbackFirstMessage) {
|
|
66
|
+
throw new Error('Fallback 1st message must be defined')
|
|
67
|
+
}
|
|
68
|
+
const fallbackSecondMessage = fallbackNode.content.second_message
|
|
69
|
+
if (!fallbackSecondMessage) {
|
|
70
|
+
return this.getNode(fallbackFirstMessage.id)
|
|
71
|
+
}
|
|
72
|
+
return alternate
|
|
73
|
+
? this.getNode(fallbackFirstMessage.id)
|
|
74
|
+
: this.getNode(fallbackSecondMessage.id)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
getNodeByIntent(input: Input, locale: string): HtNodeWithContent | undefined {
|
|
78
|
+
try {
|
|
79
|
+
const intents = this.flow.nodes.filter(
|
|
80
|
+
node => node.type === HtNodeWithContentType.INTENT
|
|
81
|
+
) as HtIntentNode[]
|
|
82
|
+
const inputIntent = input.intent
|
|
83
|
+
const inputConfidence = input.confidence
|
|
84
|
+
if (inputIntent) {
|
|
85
|
+
const matchedIntentNode = intents.find(
|
|
86
|
+
node =>
|
|
87
|
+
inputIntent &&
|
|
88
|
+
this.hasIntent(node, inputIntent, locale) &&
|
|
89
|
+
inputConfidence &&
|
|
90
|
+
this.hasMetConfidenceThreshold(node, inputConfidence)
|
|
91
|
+
)
|
|
92
|
+
return (
|
|
93
|
+
matchedIntentNode?.target &&
|
|
94
|
+
this.getNode<HtNodeWithContent>(matchedIntentNode?.target.id)
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
} catch (error) {
|
|
98
|
+
console.error(`Error getting node by intent '${input.intent}': `, error)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return undefined
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private hasIntent(
|
|
105
|
+
node: HtIntentNode,
|
|
106
|
+
intent: string,
|
|
107
|
+
locale: string
|
|
108
|
+
): boolean {
|
|
109
|
+
return node.content.intents.some(
|
|
110
|
+
i => i.locale === locale && i.values.includes(intent)
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private hasMetConfidenceThreshold(
|
|
115
|
+
node: HtIntentNode,
|
|
116
|
+
predictedConfidence: number
|
|
117
|
+
): boolean {
|
|
118
|
+
const nodeConfidence = node.content.confidence / 100
|
|
119
|
+
return predictedConfidence >= nodeConfidence
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
getNodeByKeyword(
|
|
123
|
+
userInput: string,
|
|
124
|
+
locale: string
|
|
125
|
+
): HtNodeWithContent | undefined {
|
|
126
|
+
try {
|
|
127
|
+
const keywordNodes = this.flow.nodes.filter(
|
|
128
|
+
node => node.type == HtNodeWithContentType.KEYWORD
|
|
129
|
+
) as HtKeywordNode[]
|
|
130
|
+
const matchedKeywordNodes = keywordNodes.filter(node =>
|
|
131
|
+
this.matchKeywords(node, userInput, locale)
|
|
132
|
+
)
|
|
133
|
+
if (matchedKeywordNodes.length > 0 && matchedKeywordNodes[0].target) {
|
|
134
|
+
return this.getNode<HtNodeWithContent>(matchedKeywordNodes[0].target.id)
|
|
135
|
+
}
|
|
136
|
+
} catch (error) {
|
|
137
|
+
console.error(`Error getting node by keyword '${userInput}': `, error)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return undefined
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private matchKeywords(
|
|
144
|
+
node: HtKeywordNode,
|
|
145
|
+
input: string,
|
|
146
|
+
locale: string
|
|
147
|
+
): boolean {
|
|
148
|
+
const result = node.content.keywords.find(
|
|
149
|
+
i => i.locale === locale && this.containsAnyKeywords(input, i.values)
|
|
150
|
+
)
|
|
151
|
+
return Boolean(result)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private containsAnyKeywords(input: string, keywords: string[]): boolean {
|
|
155
|
+
for (let i = 0; i < keywords.length; i++) {
|
|
156
|
+
if (input.includes(keywords[i])) {
|
|
157
|
+
return true
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return false
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from '
|
|
2
|
+
HtMediaFileLocale,
|
|
3
|
+
HtTextLocale,
|
|
4
|
+
HtVideoLocale,
|
|
5
|
+
} from './hubtype-fields'
|
|
6
6
|
|
|
7
7
|
export abstract class ContentFieldsBase {
|
|
8
8
|
constructor(public readonly id: string) {}
|
|
9
9
|
|
|
10
|
-
static getTextByLocale(locale: string, text:
|
|
10
|
+
static getTextByLocale(locale: string, text: HtTextLocale[]): string {
|
|
11
11
|
const result = text.find(t => t.locale === locale)
|
|
12
12
|
return result?.message ?? ''
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
static getImageByLocale(locale: string, image:
|
|
15
|
+
static getImageByLocale(locale: string, image: HtMediaFileLocale[]): string {
|
|
16
16
|
const result = image.find(i => i.locale === locale)
|
|
17
17
|
return result?.file ?? ''
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
static getVideoByLocale(locale: string, video:
|
|
20
|
+
static getVideoByLocale(locale: string, video: HtVideoLocale[]): string {
|
|
21
21
|
const result = video.find(v => v.locale === locale)
|
|
22
22
|
return result?.url ?? ''
|
|
23
23
|
}
|