@botonic/plugin-flow-builder 0.22.3 → 0.22.4-alpha.1

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.
Files changed (114) hide show
  1. package/lib/cjs/{action.d.ts → action/index.d.ts} +2 -3
  2. package/lib/cjs/action/index.js +72 -0
  3. package/lib/cjs/action/index.js.map +1 -0
  4. package/lib/cjs/action/intent.d.ts +4 -0
  5. package/lib/cjs/action/intent.js +33 -0
  6. package/lib/cjs/action/intent.js.map +1 -0
  7. package/lib/cjs/action/keyword.d.ts +3 -0
  8. package/lib/cjs/action/keyword.js +21 -0
  9. package/lib/cjs/action/keyword.js.map +1 -0
  10. package/lib/cjs/action/tracking.d.ts +3 -0
  11. package/lib/cjs/action/tracking.js +13 -0
  12. package/lib/cjs/action/tracking.js.map +1 -0
  13. package/lib/cjs/action/user-input.d.ts +4 -0
  14. package/lib/cjs/action/user-input.js +28 -0
  15. package/lib/cjs/action/user-input.js.map +1 -0
  16. package/lib/cjs/api.d.ts +4 -4
  17. package/lib/cjs/api.js +4 -10
  18. package/lib/cjs/api.js.map +1 -1
  19. package/lib/cjs/content-fields/content-fields-base.d.ts +2 -1
  20. package/lib/cjs/content-fields/content-fields-base.js +3 -0
  21. package/lib/cjs/content-fields/content-fields-base.js.map +1 -1
  22. package/lib/cjs/content-fields/flow-handoff.d.ts +15 -0
  23. package/lib/cjs/content-fields/flow-handoff.js +60 -0
  24. package/lib/cjs/content-fields/flow-handoff.js.map +1 -0
  25. package/lib/cjs/content-fields/index.d.ts +3 -1
  26. package/lib/cjs/content-fields/index.js +3 -1
  27. package/lib/cjs/content-fields/index.js.map +1 -1
  28. package/lib/cjs/functions/conditional-provider.d.ts +7 -4
  29. package/lib/cjs/functions/conditional-provider.js +1 -1
  30. package/lib/cjs/functions/conditional-provider.js.map +1 -1
  31. package/lib/cjs/functions/conditional-queue-status.d.ts +10 -1
  32. package/lib/cjs/functions/conditional-queue-status.js +11 -16
  33. package/lib/cjs/functions/conditional-queue-status.js.map +1 -1
  34. package/lib/cjs/functions/index.js +0 -1
  35. package/lib/cjs/functions/index.js.map +1 -1
  36. package/lib/cjs/helpers.d.ts +0 -2
  37. package/lib/cjs/helpers.js +1 -6
  38. package/lib/cjs/helpers.js.map +1 -1
  39. package/lib/cjs/index.d.ts +5 -7
  40. package/lib/cjs/index.js +16 -12
  41. package/lib/cjs/index.js.map +1 -1
  42. package/lib/cjs/types.js.map +1 -1
  43. package/lib/esm/{action.d.ts → action/index.d.ts} +2 -3
  44. package/lib/esm/action/index.js +66 -0
  45. package/lib/esm/action/index.js.map +1 -0
  46. package/lib/esm/action/intent.d.ts +4 -0
  47. package/lib/esm/action/intent.js +29 -0
  48. package/lib/esm/action/intent.js.map +1 -0
  49. package/lib/esm/action/keyword.d.ts +3 -0
  50. package/lib/esm/action/keyword.js +17 -0
  51. package/lib/esm/action/keyword.js.map +1 -0
  52. package/lib/esm/action/tracking.d.ts +3 -0
  53. package/lib/esm/action/tracking.js +9 -0
  54. package/lib/esm/action/tracking.js.map +1 -0
  55. package/lib/esm/action/user-input.d.ts +4 -0
  56. package/lib/esm/action/user-input.js +24 -0
  57. package/lib/esm/action/user-input.js.map +1 -0
  58. package/lib/esm/api.d.ts +4 -4
  59. package/lib/esm/api.js +4 -10
  60. package/lib/esm/api.js.map +1 -1
  61. package/lib/esm/content-fields/content-fields-base.d.ts +2 -1
  62. package/lib/esm/content-fields/content-fields-base.js +3 -0
  63. package/lib/esm/content-fields/content-fields-base.js.map +1 -1
  64. package/lib/esm/content-fields/flow-handoff.d.ts +15 -0
  65. package/lib/esm/content-fields/flow-handoff.js +55 -0
  66. package/lib/esm/content-fields/flow-handoff.js.map +1 -0
  67. package/lib/esm/content-fields/index.d.ts +3 -1
  68. package/lib/esm/content-fields/index.js +1 -0
  69. package/lib/esm/content-fields/index.js.map +1 -1
  70. package/lib/esm/functions/conditional-provider.d.ts +7 -4
  71. package/lib/esm/functions/conditional-provider.js +1 -1
  72. package/lib/esm/functions/conditional-provider.js.map +1 -1
  73. package/lib/esm/functions/conditional-queue-status.d.ts +10 -1
  74. package/lib/esm/functions/conditional-queue-status.js +8 -14
  75. package/lib/esm/functions/conditional-queue-status.js.map +1 -1
  76. package/lib/esm/functions/index.js +0 -1
  77. package/lib/esm/functions/index.js.map +1 -1
  78. package/lib/esm/helpers.d.ts +0 -2
  79. package/lib/esm/helpers.js +0 -4
  80. package/lib/esm/helpers.js.map +1 -1
  81. package/lib/esm/index.d.ts +5 -7
  82. package/lib/esm/index.js +17 -13
  83. package/lib/esm/index.js.map +1 -1
  84. package/lib/esm/types.js.map +1 -1
  85. package/package.json +2 -1
  86. package/src/action/index.tsx +104 -0
  87. package/src/action/intent.ts +48 -0
  88. package/src/action/keyword.ts +28 -0
  89. package/src/action/tracking.ts +12 -0
  90. package/src/action/user-input.ts +40 -0
  91. package/src/api.ts +6 -14
  92. package/src/content-fields/content-fields-base.ts +8 -0
  93. package/src/content-fields/flow-handoff.tsx +106 -0
  94. package/src/content-fields/index.ts +3 -0
  95. package/src/functions/conditional-provider.ts +11 -1
  96. package/src/functions/conditional-queue-status.ts +19 -16
  97. package/src/functions/index.ts +0 -1
  98. package/src/helpers.ts +0 -9
  99. package/src/index.ts +29 -21
  100. package/src/types.ts +0 -1
  101. package/lib/cjs/action.js +0 -52
  102. package/lib/cjs/action.js.map +0 -1
  103. package/lib/cjs/handoff.d.ts +0 -3
  104. package/lib/cjs/handoff.js +0 -53
  105. package/lib/cjs/handoff.js.map +0 -1
  106. package/lib/esm/action.js +0 -46
  107. package/lib/esm/action.js.map +0 -1
  108. package/lib/esm/handoff.d.ts +0 -3
  109. package/lib/esm/handoff.js +0 -49
  110. package/lib/esm/handoff.js.map +0 -1
  111. package/src/.DS_Store +0 -0
  112. package/src/action.tsx +0 -77
  113. package/src/content-fields/.DS_Store +0 -0
  114. package/src/handoff.ts +0 -76
@@ -1,11 +1,15 @@
1
1
  import axios from 'axios';
2
- import { getFlowBuilderPlugin } from '../helpers';
3
2
  import { getWebpackEnvVar } from '../utils';
4
3
  const _HUBTYPE_API_URL_ = getWebpackEnvVar(
5
4
  // @ts-ignore
6
5
  typeof HUBTYPE_API_URL !== 'undefined' && HUBTYPE_API_URL, 'HUBTYPE_API_URL', 'https://api.hubtype.com');
7
- export async function conditionalQueueStatus({ request, queue_id, queue_name, }) {
8
- const response = await axios.get(`${_HUBTYPE_API_URL_}/v1/queues/${queue_id}/availability/`,
6
+ export async function conditionalQueueStatus({ queue_id, }) {
7
+ const data = await getQueueAvailability(queue_id);
8
+ const isAvailable = data.available;
9
+ return isAvailable ? 'open' : 'closed';
10
+ }
11
+ export async function getQueueAvailability(queueId) {
12
+ const response = await axios.get(`${_HUBTYPE_API_URL_}/v1/queues/${queueId}/availability/`,
9
13
  // TODO: Make it configurable in the future
10
14
  {
11
15
  params: {
@@ -14,16 +18,6 @@ export async function conditionalQueueStatus({ request, queue_id, queue_name, })
14
18
  check_available_agents: false,
15
19
  },
16
20
  });
17
- const isAvailable = response.data.available;
18
- const flowBuilderPlugin = getFlowBuilderPlugin(request.plugins);
19
- if (flowBuilderPlugin.trackEvent) {
20
- const eventName = `QUEUE_${isAvailable ? 'OPEN' : 'CLOSED'}`;
21
- const args = {
22
- queue_id,
23
- queue_name,
24
- };
25
- await flowBuilderPlugin.trackEvent(request, eventName, args);
26
- }
27
- return isAvailable ? 'open' : 'closed';
21
+ return response.data;
28
22
  }
29
23
  //# sourceMappingURL=conditional-queue-status.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"conditional-queue-status.js","sourceRoot":"","sources":["../../../src/functions/conditional-queue-status.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAE3C,MAAM,iBAAiB,GAAG,gBAAgB;AACxC,aAAa;AACb,OAAO,eAAe,KAAK,WAAW,IAAI,eAAe,EACzD,iBAAiB,EACjB,yBAAyB,CAC1B,CAAA;AAQD,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,EAC3C,OAAO,EACP,QAAQ,EACR,UAAU,GACiB;IAC3B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAC9B,GAAG,iBAAiB,cAAc,QAAQ,gBAAgB;IAC1D,2CAA2C;IAC3C;QACE,MAAM,EAAE;YACN,oBAAoB,EAAE,IAAI;YAC1B,mBAAmB,EAAE,KAAK;YAC1B,sBAAsB,EAAE,KAAK;SAC9B;KACF,CACF,CAAA;IACD,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAA;IAE3C,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/D,IAAI,iBAAiB,CAAC,UAAU,EAAE;QAChC,MAAM,SAAS,GAAG,SAAS,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC5D,MAAM,IAAI,GAAG;YACX,QAAQ;YACR,UAAU;SACX,CAAA;QACD,MAAM,iBAAiB,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAA;KAC7D;IAED,OAAO,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAA;AACxC,CAAC"}
1
+ {"version":3,"file":"conditional-queue-status.js","sourceRoot":"","sources":["../../../src/functions/conditional-queue-status.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAE3C,MAAM,iBAAiB,GAAG,gBAAgB;AACxC,aAAa;AACb,OAAO,eAAe,KAAK,WAAW,IAAI,eAAe,EACzD,iBAAiB,EACjB,yBAAyB,CAC1B,CAAA;AAQD,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,EAC3C,QAAQ,GACmB;IAC3B,MAAM,IAAI,GAAG,MAAM,oBAAoB,CAAC,QAAQ,CAAC,CAAA;IACjD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAA;IAClC,OAAO,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAA;AACxC,CAAC;AAWD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAe;IAEf,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAC9B,GAAG,iBAAiB,cAAc,OAAO,gBAAgB;IACzD,2CAA2C;IAC3C;QACE,MAAM,EAAE;YACN,oBAAoB,EAAE,IAAI;YAC1B,mBAAmB,EAAE,KAAK;YAC1B,sBAAsB,EAAE,KAAK;SAC9B;KACF,CACF,CAAA;IACD,OAAO,QAAQ,CAAC,IAAI,CAAA;AACtB,CAAC"}
@@ -2,7 +2,6 @@ import { conditionalProvider } from './conditional-provider';
2
2
  import { conditionalQueueStatus } from './conditional-queue-status';
3
3
  export const DEFAULT_FUNCTIONS = {
4
4
  // TODO: Rename api action name
5
- // 'conditional-queue-status': conditionalQueueStatus,
6
5
  'check-queue-status': conditionalQueueStatus,
7
6
  'get-channel-type': conditionalProvider,
8
7
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/functions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAEnE,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,+BAA+B;IAC/B,sDAAsD;IACtD,oBAAoB,EAAE,sBAAsB;IAC5C,kBAAkB,EAAE,mBAAmB;CACxC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/functions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAEnE,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,+BAA+B;IAC/B,oBAAoB,EAAE,sBAAsB;IAC5C,kBAAkB,EAAE,mBAAmB;CACxC,CAAA"}
@@ -1,7 +1,5 @@
1
1
  import { Plugin } from '@botonic/core';
2
- import { HtHandoffNode, HtNodeWithContent } from './content-fields/hubtype-fields';
3
2
  import BotonicPluginFlowBuilder from './index';
4
3
  export declare function getFlowBuilderPlugin(plugins: {
5
4
  [id: string]: Plugin;
6
5
  }): BotonicPluginFlowBuilder;
7
- export declare function isHandoffNode(node: HtNodeWithContent): node is HtHandoffNode;
@@ -1,4 +1,3 @@
1
- import { HtNodeWithContentType, } from './content-fields/hubtype-fields';
2
1
  const FLOW_BUILDER_PLUGIN_NAME = 'BotonicPluginFlowBuilder';
3
2
  export function getFlowBuilderPlugin(plugins) {
4
3
  const flowBuilderPlugin = Object.values(plugins).find(
@@ -8,7 +7,4 @@ export function getFlowBuilderPlugin(plugins) {
8
7
  throw new Error(`You must include '@botonic/plugin-flow-builder' in your plugins file.`);
9
8
  return flowBuilderPlugin;
10
9
  }
11
- export function isHandoffNode(node) {
12
- return node.type === HtNodeWithContentType.HANDOFF;
13
- }
14
10
  //# sourceMappingURL=helpers.js.map
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"AAIA,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"}
@@ -1,8 +1,8 @@
1
- import { Plugin, PluginPostRequest, PluginPreRequest, Session } from '@botonic/core';
1
+ import { Plugin, PluginPreRequest, Session } from '@botonic/core';
2
2
  import { ActionRequest } from '@botonic/react';
3
3
  import { FlowBuilderApi } from './api';
4
4
  import { FlowContent } from './content-fields';
5
- import { HtFunctionNode, HtHandoffNode, HtNodeWithContent } from './content-fields/hubtype-fields';
5
+ import { HtFunctionNode, HtNodeWithContent } from './content-fields/hubtype-fields';
6
6
  import { BotonicPluginFlowBuilderOptions } from './types';
7
7
  export default class BotonicPluginFlowBuilder implements Plugin {
8
8
  readonly options: BotonicPluginFlowBuilderOptions;
@@ -16,11 +16,9 @@ export default class BotonicPluginFlowBuilder implements Plugin {
16
16
  trackEvent?: (request: ActionRequest, eventName: string, args?: Record<string, any>) => Promise<void>;
17
17
  constructor(options: BotonicPluginFlowBuilderOptions);
18
18
  pre(request: PluginPreRequest): Promise<void>;
19
- post(_request: PluginPostRequest): Promise<void>;
20
- getContents(nodeOrId: HtNodeWithContent | string, locale: string, prevContents?: FlowContent[]): Promise<{
21
- contents: FlowContent[];
22
- handoffNode?: HtHandoffNode;
23
- }>;
19
+ getContentsByCode(code: string, locale: string, prevContents?: FlowContent[]): Promise<FlowContent[]>;
20
+ getContentsById(id: string, locale: string, prevContents?: FlowContent[]): Promise<FlowContent[]>;
21
+ getContentsByNode(node: HtNodeWithContent, locale: string, prevContents?: FlowContent[]): Promise<FlowContent[]>;
24
22
  private getFlowContent;
25
23
  callFunction(functionNode: HtFunctionNode, locale: string): Promise<string>;
26
24
  }
package/lib/esm/index.js CHANGED
@@ -1,8 +1,7 @@
1
1
  import { FlowBuilderApi } from './api';
2
- import { FlowCarousel, FlowImage, FlowText, FlowVideo, FlowWhatsappButtonList, } from './content-fields';
2
+ import { FlowCarousel, FlowHandoff, FlowImage, FlowText, FlowVideo, FlowWhatsappButtonList, } from './content-fields';
3
3
  import { HtNodeWithContentType, } from './content-fields/hubtype-fields';
4
4
  import { DEFAULT_FUNCTIONS } from './functions';
5
- import { isHandoffNode } from './helpers';
6
5
  import { resolveGetAccessToken } from './utils';
7
6
  export default class BotonicPluginFlowBuilder {
8
7
  constructor(options) {
@@ -23,26 +22,29 @@ export default class BotonicPluginFlowBuilder {
23
22
  accessToken: this.getAccessToken(request.session),
24
23
  });
25
24
  }
26
- async post(_request) { }
27
- async getContents(nodeOrId, locale, prevContents) {
25
+ getContentsByCode(code, locale, prevContents) {
26
+ const node = this.cmsApi.getNodeByCode(code);
27
+ return this.getContentsByNode(node, locale, prevContents);
28
+ }
29
+ async getContentsById(id, locale, prevContents) {
30
+ const node = this.cmsApi.getNodeById(id);
31
+ return this.getContentsByNode(node, locale, prevContents);
32
+ }
33
+ async getContentsByNode(node, locale, prevContents) {
28
34
  const contents = prevContents || [];
29
- let node = nodeOrId;
30
- if (typeof nodeOrId === 'string') {
31
- node = this.cmsApi.getNodeById(nodeOrId);
32
- }
33
- const content = await this.getFlowContent(node, locale);
35
+ const content = this.getFlowContent(node, locale);
34
36
  if (node.type === HtNodeWithContentType.FUNCTION) {
35
37
  const targetId = await this.callFunction(node, locale);
36
- return this.getContents(targetId, locale, contents);
38
+ return this.getContentsById(targetId, locale, contents);
37
39
  }
38
40
  else {
39
41
  if (content)
40
42
  contents.push(content);
41
43
  // TODO: prevent infinite recursive calls
42
44
  if (node.follow_up)
43
- return this.getContents(node.follow_up.id, locale, contents);
45
+ return this.getContentsById(node.follow_up.id, locale, contents);
44
46
  }
45
- return { contents, handoffNode: isHandoffNode(node) ? node : undefined };
47
+ return contents;
46
48
  }
47
49
  getFlowContent(hubtypeContent, locale) {
48
50
  switch (hubtypeContent.type) {
@@ -56,6 +58,8 @@ export default class BotonicPluginFlowBuilder {
56
58
  return FlowVideo.fromHubtypeCMS(hubtypeContent, locale);
57
59
  case HtNodeWithContentType.WHATSAPP_BUTTON_LIST:
58
60
  return FlowWhatsappButtonList.fromHubtypeCMS(hubtypeContent, locale);
61
+ case HtNodeWithContentType.HANDOFF:
62
+ return FlowHandoff.fromHubtypeCMS(hubtypeContent, locale, this.cmsApi);
59
63
  default:
60
64
  return undefined;
61
65
  }
@@ -67,7 +71,7 @@ export default class BotonicPluginFlowBuilder {
67
71
  .find(arg => arg.locale === locale)) === null || _a === void 0 ? void 0 : _a.values.map(value => ({ [value.name]: value.value }))) || [];
68
72
  const args = Object.assign({
69
73
  request: this.currentRequest,
70
- results: [functionNode.content.result_mapping.map(r => r.result)],
74
+ results: functionNode.content.result_mapping.map(r => r.result),
71
75
  }, ...nameValues);
72
76
  const functionResult = await this.functions[functionNode.content.action](args);
73
77
  // TODO define result_mapping per locale??
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAyBA,MAAM,CAAN,IAAY,kBAGX;AAHD,WAAY,kBAAkB;IAC5B,+CAAyB,CAAA;IACzB,iDAA2B,CAAA;AAC7B,CAAC,EAHW,kBAAkB,KAAlB,kBAAkB,QAG7B"}
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.3",
3
+ "version": "0.22.4-alpha.1",
4
4
  "main": "./lib/cjs/index.js",
5
5
  "module": "./lib/esm/index.js",
6
6
  "description": "Use Flow Builder to show your contents",
@@ -48,6 +48,7 @@
48
48
  "dependencies": {
49
49
  "@babel/runtime": "^7.21.0",
50
50
  "@botonic/react": "^0.22.2",
51
+ "@botonic/plugin-hubtype-analytics": "0.22.0-alpha.5",
51
52
  "axios": "^1.3.6"
52
53
  }
53
54
  }
@@ -0,0 +1,104 @@
1
+ import {
2
+ EventBotFaq,
3
+ EventFallback,
4
+ EventName,
5
+ } from '@botonic/plugin-hubtype-analytics/lib/cjs/types'
6
+ import { ActionRequest, Multichannel, RequestContext } from '@botonic/react'
7
+ import React from 'react'
8
+
9
+ import { FlowBuilderApi } from '../api'
10
+ import { FlowContent, FlowHandoff } from '../content-fields'
11
+ import { HtNodeWithContent } from '../content-fields/hubtype-fields'
12
+ import { getFlowBuilderPlugin } from '../helpers'
13
+ import { trackEvent } from './tracking'
14
+ import { getNodeByUserInput } from './user-input'
15
+
16
+ type FlowBuilderActionProps = {
17
+ contents: FlowContent[]
18
+ }
19
+
20
+ export class FlowBuilderAction extends React.Component<FlowBuilderActionProps> {
21
+ static contextType = RequestContext
22
+
23
+ static async botonicInit(
24
+ request: ActionRequest
25
+ ): Promise<FlowBuilderActionProps> {
26
+ const flowBuilderPlugin = getFlowBuilderPlugin(request.plugins)
27
+ const locale = flowBuilderPlugin.getLocale(request.session)
28
+
29
+ const targetNode = await getTargetNode(
30
+ flowBuilderPlugin.cmsApi,
31
+ locale,
32
+ request
33
+ )
34
+
35
+ const contents = await flowBuilderPlugin.getContentsByNode(
36
+ targetNode,
37
+ locale
38
+ )
39
+
40
+ const renderContents = contents.filter(async content => {
41
+ if (content instanceof FlowHandoff) {
42
+ await content.doHandoff(request)
43
+ return false
44
+ }
45
+ return true
46
+ })
47
+
48
+ return { contents: renderContents }
49
+ }
50
+
51
+ render(): JSX.Element | JSX.Element[] {
52
+ const { contents } = this.props
53
+ return contents.map(content => content.toBotonic(content.id))
54
+ }
55
+ }
56
+
57
+ export class FlowBuilderMultichannelAction extends FlowBuilderAction {
58
+ render(): JSX.Element | JSX.Element[] {
59
+ const { contents } = this.props
60
+ return (
61
+ <Multichannel text={{ buttonsAsText: false }}>
62
+ {contents.map(content => content.toBotonic(content.id))}
63
+ </Multichannel>
64
+ )
65
+ }
66
+ }
67
+
68
+ async function getTargetNode(
69
+ cmsApi: FlowBuilderApi,
70
+ locale: string,
71
+ request: ActionRequest
72
+ ) {
73
+ const contentId = request.input.payload
74
+ let targetNode: HtNodeWithContent | undefined
75
+ if (!contentId) {
76
+ targetNode = await getNodeByUserInput(cmsApi, locale, request)
77
+ } else {
78
+ targetNode = cmsApi.getNodeById(contentId) as HtNodeWithContent
79
+ }
80
+ if (targetNode) {
81
+ const event: EventBotFaq = {
82
+ event_type: EventName.botFaq,
83
+ event_data: {
84
+ faq_name: targetNode.code,
85
+ },
86
+ }
87
+ await trackEvent(request, event)
88
+ return targetNode
89
+ }
90
+ return await getFallbackNode(cmsApi, request)
91
+ }
92
+
93
+ async function getFallbackNode(cmsApi: FlowBuilderApi, request: ActionRequest) {
94
+ const isFirstFallbackOption =
95
+ request.session.user.extra_data.isFirstFallbackOption || true
96
+ const fallbackNode = cmsApi.getFallbackNode(isFirstFallbackOption)
97
+ request.session.user.extra_data.isFirstFallbackOption = !isFirstFallbackOption
98
+
99
+ const event: EventFallback = {
100
+ event_type: EventName.fallback,
101
+ }
102
+ await trackEvent(request, event)
103
+ return fallbackNode
104
+ }
@@ -0,0 +1,48 @@
1
+ import {
2
+ EventBotAiModel,
3
+ EventName,
4
+ } from '@botonic/plugin-hubtype-analytics/lib/cjs/types'
5
+ import { ActionRequest } from '@botonic/react'
6
+
7
+ import { FlowBuilderApi } from '../api'
8
+ import {
9
+ HtIntentNode,
10
+ HtNodeWithContent,
11
+ } from '../content-fields/hubtype-fields'
12
+ import { trackEvent } from './tracking'
13
+
14
+ export async function getNodeByIntent(
15
+ cmsApi: FlowBuilderApi,
16
+ locale: string,
17
+ request: ActionRequest
18
+ ) {
19
+ const intentNode = cmsApi.getIntentNode(request.input, locale)
20
+ const eventBotAiModel: EventBotAiModel = {
21
+ event_type: EventName.botAiModel,
22
+ event_data: {
23
+ intent: request.input.intent as string,
24
+ confidence: request.input.confidence as number,
25
+ confidence_successful: true,
26
+ },
27
+ }
28
+ if (isIntentValid(intentNode, request, cmsApi) && intentNode?.target?.id) {
29
+ await trackEvent(request, eventBotAiModel)
30
+ return cmsApi.getNodeById<HtNodeWithContent>(intentNode.target.id)
31
+ } else {
32
+ eventBotAiModel.event_data.confidence_successful = false
33
+ await trackEvent(request, eventBotAiModel)
34
+ return undefined
35
+ }
36
+ }
37
+
38
+ function isIntentValid(
39
+ intentNode: HtIntentNode | undefined,
40
+ request: ActionRequest,
41
+ cmsApi: FlowBuilderApi
42
+ ) {
43
+ return (
44
+ intentNode &&
45
+ request.input.confidence &&
46
+ cmsApi.hasMetConfidenceThreshold(intentNode, request.input.confidence)
47
+ )
48
+ }
@@ -0,0 +1,28 @@
1
+ import {
2
+ EventBotKeywordModel,
3
+ EventName,
4
+ } from '@botonic/plugin-hubtype-analytics/lib/cjs/types'
5
+ import { ActionRequest } from '@botonic/react'
6
+
7
+ import { FlowBuilderApi } from '../api'
8
+ import { trackEvent } from './tracking'
9
+
10
+ export async function getNodeByKeyword(
11
+ cmsApi: FlowBuilderApi,
12
+ locale: string,
13
+ request: ActionRequest,
14
+ userInput: string
15
+ ) {
16
+ const keywordNode = cmsApi.getNodeByKeyword(userInput, locale)
17
+ const eventBotKeywordModel: EventBotKeywordModel = {
18
+ event_type: EventName.botKeywordsModel,
19
+ event_data: {
20
+ confidence_successful: true,
21
+ },
22
+ }
23
+ if (keywordNode) {
24
+ await trackEvent(request, eventBotKeywordModel)
25
+ return keywordNode
26
+ }
27
+ return undefined
28
+ }
@@ -0,0 +1,12 @@
1
+ import { HtEventProps } from '@botonic/plugin-hubtype-analytics/lib/cjs/types'
2
+ import { ActionRequest } from '@botonic/react'
3
+
4
+ import { getFlowBuilderPlugin } from '../helpers'
5
+
6
+ export async function trackEvent(request: ActionRequest, event: HtEventProps) {
7
+ const flowBuilderPlugin = getFlowBuilderPlugin(request.plugins)
8
+ if (flowBuilderPlugin.trackEvent) {
9
+ await flowBuilderPlugin.trackEvent(request, event.event_type, event)
10
+ }
11
+ return
12
+ }
@@ -0,0 +1,40 @@
1
+ import {
2
+ EventBotStart,
3
+ EventName,
4
+ } from '@botonic/plugin-hubtype-analytics/lib/cjs/types'
5
+ import { ActionRequest } from '@botonic/react'
6
+
7
+ import { FlowBuilderApi } from '../api'
8
+ import { HtNodeWithContent } from '../content-fields/hubtype-fields'
9
+ import { getNodeByIntent } from './intent'
10
+ import { getNodeByKeyword } from './keyword'
11
+ import { trackEvent } from './tracking'
12
+
13
+ export async function getNodeByUserInput(
14
+ cmsApi: FlowBuilderApi,
15
+ locale: string,
16
+ request: ActionRequest
17
+ ): Promise<HtNodeWithContent | undefined> {
18
+ if (request.session.is_first_interaction) {
19
+ const startNode = cmsApi.getStartNode()
20
+ const event: EventBotStart = {
21
+ event_type: EventName.botStart,
22
+ }
23
+ await trackEvent(request, event)
24
+ return startNode
25
+ }
26
+
27
+ if (request.input.data) {
28
+ const nodeByIntent = await getNodeByIntent(cmsApi, locale, request)
29
+ if (nodeByIntent) return nodeByIntent
30
+
31
+ const keywordNode = await getNodeByKeyword(
32
+ cmsApi,
33
+ locale,
34
+ request,
35
+ request.input.data
36
+ )
37
+ if (keywordNode) return keywordNode
38
+ }
39
+ return undefined
40
+ }
package/src/api.ts CHANGED
@@ -78,24 +78,16 @@ export class FlowBuilderApi {
78
78
  : this.getNodeById(fallbackSecondMessage.id)
79
79
  }
80
80
 
81
- getNodeByIntent(input: Input, locale: string): HtNodeWithContent | undefined {
81
+ getIntentNode(input: Input, locale: string): HtIntentNode | undefined {
82
82
  try {
83
- const intents = this.flow.nodes.filter(
83
+ const intentsNodes = this.flow.nodes.filter(
84
84
  node => node.type === HtNodeWithContentType.INTENT
85
85
  ) as HtIntentNode[]
86
86
  const inputIntent = input.intent
87
- const inputConfidence = input.confidence
88
87
  if (inputIntent) {
89
- const matchedIntentNode = intents.find(
88
+ return intentsNodes.find(
90
89
  node =>
91
- inputIntent &&
92
- this.hasIntent(node, inputIntent, locale) &&
93
- inputConfidence &&
94
- this.hasMetConfidenceThreshold(node, inputConfidence)
95
- )
96
- return (
97
- matchedIntentNode?.target &&
98
- this.getNodeById<HtNodeWithContent>(matchedIntentNode?.target.id)
90
+ inputIntent && this.nodeContainsIntent(node, inputIntent, locale)
99
91
  )
100
92
  }
101
93
  } catch (error) {
@@ -105,7 +97,7 @@ export class FlowBuilderApi {
105
97
  return undefined
106
98
  }
107
99
 
108
- private hasIntent(
100
+ private nodeContainsIntent(
109
101
  node: HtIntentNode,
110
102
  intent: string,
111
103
  locale: string
@@ -115,7 +107,7 @@ export class FlowBuilderApi {
115
107
  )
116
108
  }
117
109
 
118
- private hasMetConfidenceThreshold(
110
+ hasMetConfidenceThreshold(
119
111
  node: HtIntentNode,
120
112
  predictedConfidence: number
121
113
  ): boolean {
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  HtMediaFileLocale,
3
+ HtQueueLocale,
3
4
  HtTextLocale,
4
5
  HtVideoLocale,
5
6
  } from './hubtype-fields'
@@ -21,4 +22,11 @@ export abstract class ContentFieldsBase {
21
22
  const result = video.find(v => v.locale === locale)
22
23
  return result?.url ?? ''
23
24
  }
25
+
26
+ static getQueueByLocale(
27
+ locale: string,
28
+ queues: HtQueueLocale[]
29
+ ): HtQueueLocale | undefined {
30
+ return queues.find(queue => queue.locale === locale)
31
+ }
24
32
  }
@@ -0,0 +1,106 @@
1
+ import { HandOffBuilder } from '@botonic/core'
2
+ import {
3
+ EventHandoffSuccess,
4
+ EventName,
5
+ } from '@botonic/plugin-hubtype-analytics/lib/cjs/types'
6
+ import { ActionRequest } from '@botonic/react'
7
+ import React from 'react'
8
+
9
+ import { trackEvent } from '../action/tracking'
10
+ import { FlowBuilderApi } from '../api'
11
+ import { getQueueAvailability } from '../functions/conditional-queue-status'
12
+ import { ContentFieldsBase } from './content-fields-base'
13
+ import {
14
+ HtCarouselNode,
15
+ HtHandoffNode,
16
+ HtImageNode,
17
+ HtPayloadNode,
18
+ HtQueueLocale,
19
+ HtTextNode,
20
+ HtVideoNode,
21
+ HtWhatsappButtonListNode,
22
+ } from './hubtype-fields'
23
+
24
+ type HtAfterHandoff =
25
+ | HtTextNode
26
+ | HtImageNode
27
+ | HtVideoNode
28
+ | HtCarouselNode
29
+ | HtWhatsappButtonListNode
30
+
31
+ export class FlowHandoff extends ContentFieldsBase {
32
+ public code: string
33
+ public queue?: HtQueueLocale
34
+ public onFinishPayload?: string
35
+ public handoffAutoAssign: boolean
36
+
37
+ static fromHubtypeCMS(
38
+ cmsHandoff: HtHandoffNode,
39
+ locale: string,
40
+ cmsApi: FlowBuilderApi
41
+ ): FlowHandoff {
42
+ const newHandoff = new FlowHandoff(cmsHandoff.id)
43
+ newHandoff.code = cmsHandoff.code
44
+ newHandoff.queue = this.getQueueByLocale(locale, cmsHandoff.content.queue)
45
+ newHandoff.onFinishPayload = this.getOnFinishPayload(
46
+ cmsHandoff,
47
+ locale,
48
+ cmsApi
49
+ )
50
+ newHandoff.handoffAutoAssign = cmsHandoff.content.has_auto_assign
51
+
52
+ return newHandoff
53
+ }
54
+
55
+ private static getOnFinishPayload(
56
+ cmsHandoff: HtHandoffNode,
57
+ locale: string,
58
+ cmsApi: FlowBuilderApi
59
+ ): string | undefined {
60
+ if (cmsHandoff.target?.id) {
61
+ const handoffTargetNode = cmsApi.getNodeById<HtAfterHandoff>(
62
+ cmsHandoff.target?.id
63
+ )
64
+ if (handoffTargetNode?.id) return handoffTargetNode?.id
65
+ }
66
+
67
+ const payloadId = cmsHandoff.content.payload.find(
68
+ payload => payload.locale === locale
69
+ )?.id
70
+
71
+ if (!payloadId) return undefined
72
+
73
+ const actionPayload = cmsApi.getNodeById(payloadId)
74
+
75
+ return (actionPayload as HtPayloadNode).content.payload
76
+ }
77
+
78
+ async doHandoff(request: ActionRequest) {
79
+ // @ts-ignore
80
+ const handOffBuilder = new HandOffBuilder(request.session)
81
+ handOffBuilder.withAutoAssignOnWaiting(this.handoffAutoAssign)
82
+ if (this.onFinishPayload) {
83
+ handOffBuilder.withOnFinishPayload(this.onFinishPayload)
84
+ }
85
+ if (this.queue) {
86
+ const availabilityData = await getQueueAvailability(this.queue.id)
87
+ const event: EventHandoffSuccess = {
88
+ event_type: EventName.handoffSuccess,
89
+ event_data: {
90
+ queue_open: availabilityData.open,
91
+ available_agents: availabilityData.available_agents > 0,
92
+ threshold_reached:
93
+ availabilityData.availability_threshold_waiting_cases > 0,
94
+ },
95
+ }
96
+ await trackEvent(request, event)
97
+
98
+ handOffBuilder.withQueue(this.queue.id)
99
+ await handOffBuilder.handOff()
100
+ }
101
+ }
102
+
103
+ toBotonic(): JSX.Element {
104
+ return <></>
105
+ }
106
+ }
@@ -1,4 +1,5 @@
1
1
  import { FlowCarousel } from './flow-carousel'
2
+ import { FlowHandoff } from './flow-handoff'
2
3
  import { FlowImage } from './flow-image'
3
4
  import { FlowText } from './flow-text'
4
5
  import { FlowVideo } from './flow-video'
@@ -8,6 +9,7 @@ export { ContentFieldsBase } from './content-fields-base'
8
9
  export { FlowButton } from './flow-button'
9
10
  export { FlowElement } from './flow-element'
10
11
  export { FlowCarousel, FlowImage, FlowText, FlowVideo, FlowWhatsappButtonList }
12
+ export { FlowHandoff } from './flow-handoff'
11
13
 
12
14
  export type FlowContent =
13
15
  | FlowCarousel
@@ -15,3 +17,4 @@ export type FlowContent =
15
17
  | FlowText
16
18
  | FlowVideo
17
19
  | FlowWhatsappButtonList
20
+ | FlowHandoff