@botonic/plugin-flow-builder 0.24.1 → 0.24.2-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 (85) hide show
  1. package/lib/cjs/action/index.js +10 -6
  2. package/lib/cjs/action/index.js.map +1 -1
  3. package/lib/cjs/action/intent.d.ts +2 -2
  4. package/lib/cjs/action/intent.js +10 -12
  5. package/lib/cjs/action/intent.js.map +1 -1
  6. package/lib/cjs/action/keyword.d.ts +2 -2
  7. package/lib/cjs/action/keyword.js +3 -3
  8. package/lib/cjs/action/keyword.js.map +1 -1
  9. package/lib/cjs/action/user-input.d.ts +2 -2
  10. package/lib/cjs/action/user-input.js +4 -10
  11. package/lib/cjs/action/user-input.js.map +1 -1
  12. package/lib/cjs/api.d.ts +4 -2
  13. package/lib/cjs/api.js +21 -2
  14. package/lib/cjs/api.js.map +1 -1
  15. package/lib/cjs/constants.d.ts +2 -1
  16. package/lib/cjs/constants.js +3 -2
  17. package/lib/cjs/constants.js.map +1 -1
  18. package/lib/cjs/content-fields/flow-button.js +2 -1
  19. package/lib/cjs/content-fields/flow-button.js.map +1 -1
  20. package/lib/cjs/content-fields/flow-handoff.js +8 -9
  21. package/lib/cjs/content-fields/flow-handoff.js.map +1 -1
  22. package/lib/cjs/content-fields/hubtype-fields/bot-action.d.ts +10 -0
  23. package/lib/cjs/content-fields/hubtype-fields/bot-action.js +3 -0
  24. package/lib/cjs/content-fields/hubtype-fields/bot-action.js.map +1 -0
  25. package/lib/cjs/content-fields/hubtype-fields/index.d.ts +1 -0
  26. package/lib/cjs/content-fields/hubtype-fields/index.js +1 -0
  27. package/lib/cjs/content-fields/hubtype-fields/index.js.map +1 -1
  28. package/lib/cjs/content-fields/hubtype-fields/node-types.d.ts +2 -1
  29. package/lib/cjs/content-fields/hubtype-fields/node-types.js +1 -0
  30. package/lib/cjs/content-fields/hubtype-fields/node-types.js.map +1 -1
  31. package/lib/cjs/content-fields/hubtype-fields/nodes.d.ts +2 -1
  32. package/lib/cjs/index.d.ts +3 -2
  33. package/lib/cjs/index.js +12 -0
  34. package/lib/cjs/index.js.map +1 -1
  35. package/lib/cjs/types.d.ts +3 -0
  36. package/lib/esm/action/index.js +10 -6
  37. package/lib/esm/action/index.js.map +1 -1
  38. package/lib/esm/action/intent.d.ts +2 -2
  39. package/lib/esm/action/intent.js +8 -10
  40. package/lib/esm/action/intent.js.map +1 -1
  41. package/lib/esm/action/keyword.d.ts +2 -2
  42. package/lib/esm/action/keyword.js +1 -1
  43. package/lib/esm/action/keyword.js.map +1 -1
  44. package/lib/esm/action/user-input.d.ts +2 -2
  45. package/lib/esm/action/user-input.js +6 -12
  46. package/lib/esm/action/user-input.js.map +1 -1
  47. package/lib/esm/api.d.ts +4 -2
  48. package/lib/esm/api.js +21 -2
  49. package/lib/esm/api.js.map +1 -1
  50. package/lib/esm/constants.d.ts +2 -1
  51. package/lib/esm/constants.js +2 -1
  52. package/lib/esm/constants.js.map +1 -1
  53. package/lib/esm/content-fields/flow-button.js +2 -1
  54. package/lib/esm/content-fields/flow-button.js.map +1 -1
  55. package/lib/esm/content-fields/flow-handoff.js +8 -9
  56. package/lib/esm/content-fields/flow-handoff.js.map +1 -1
  57. package/lib/esm/content-fields/hubtype-fields/bot-action.d.ts +10 -0
  58. package/lib/esm/content-fields/hubtype-fields/bot-action.js +2 -0
  59. package/lib/esm/content-fields/hubtype-fields/bot-action.js.map +1 -0
  60. package/lib/esm/content-fields/hubtype-fields/index.d.ts +1 -0
  61. package/lib/esm/content-fields/hubtype-fields/index.js +1 -0
  62. package/lib/esm/content-fields/hubtype-fields/index.js.map +1 -1
  63. package/lib/esm/content-fields/hubtype-fields/node-types.d.ts +2 -1
  64. package/lib/esm/content-fields/hubtype-fields/node-types.js +1 -0
  65. package/lib/esm/content-fields/hubtype-fields/node-types.js.map +1 -1
  66. package/lib/esm/content-fields/hubtype-fields/nodes.d.ts +2 -1
  67. package/lib/esm/index.d.ts +3 -2
  68. package/lib/esm/index.js +13 -1
  69. package/lib/esm/index.js.map +1 -1
  70. package/lib/esm/types.d.ts +3 -0
  71. package/package.json +1 -1
  72. package/src/action/index.tsx +11 -14
  73. package/src/action/intent.ts +12 -13
  74. package/src/action/keyword.ts +3 -3
  75. package/src/action/user-input.ts +7 -14
  76. package/src/api.ts +32 -5
  77. package/src/constants.ts +2 -1
  78. package/src/content-fields/flow-button.tsx +5 -3
  79. package/src/content-fields/flow-handoff.tsx +7 -26
  80. package/src/content-fields/hubtype-fields/bot-action.ts +11 -0
  81. package/src/content-fields/hubtype-fields/index.ts +1 -0
  82. package/src/content-fields/hubtype-fields/node-types.ts +1 -0
  83. package/src/content-fields/hubtype-fields/nodes.ts +6 -1
  84. package/src/index.ts +28 -3
  85. package/src/types.ts +4 -0
package/src/api.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { Input, PluginPreRequest } from '@botonic/core'
2
2
  import axios from 'axios'
3
3
 
4
+ import { SEPARATOR } from './constants'
4
5
  import {
6
+ HtBotActionNode,
5
7
  HtFallbackNode,
6
8
  HtFlowBuilderData,
7
9
  HtIntentNode,
@@ -11,6 +13,7 @@ import {
11
13
  HtNodeWithContent,
12
14
  HtNodeWithContentType,
13
15
  HtNodeWithoutContentType,
16
+ HtPayloadNode,
14
17
  } from './content-fields/hubtype-fields'
15
18
  import { FlowBuilderApiOptions } from './types'
16
19
 
@@ -142,18 +145,16 @@ export class FlowBuilderApi {
142
145
  getNodeByKeyword(
143
146
  userInput: string,
144
147
  locale: string
145
- ): HtNodeWithContent | undefined {
148
+ ): HtKeywordNode | undefined {
146
149
  try {
147
150
  const keywordNodes = this.flow.nodes.filter(
148
- node => node.type == HtNodeWithContentType.KEYWORD
151
+ node => node.type === HtNodeWithContentType.KEYWORD
149
152
  ) as HtKeywordNode[]
150
153
  const matchedKeywordNodes = keywordNodes.filter(node =>
151
154
  this.matchKeywords(node, userInput, locale)
152
155
  )
153
156
  if (matchedKeywordNodes.length > 0 && matchedKeywordNodes[0].target) {
154
- return this.getNodeById<HtNodeWithContent>(
155
- matchedKeywordNodes[0].target.id
156
- )
157
+ return matchedKeywordNodes[0]
157
158
  }
158
159
  } catch (error) {
159
160
  console.error(`Error getting node by keyword '${userInput}': `, error)
@@ -176,4 +177,30 @@ export class FlowBuilderApi {
176
177
  private containsAnyKeywords(input: string, keywords: string[]): boolean {
177
178
  return keywords.some(keyword => input.includes(keyword))
178
179
  }
180
+
181
+ getPayload(target?: HtNodeLink): string | undefined {
182
+ if (!target) {
183
+ return undefined
184
+ }
185
+
186
+ if (target.type === HtNodeWithoutContentType.BOT_ACTION) {
187
+ const botActionNode = this.getNodeById<HtBotActionNode>(target.id)
188
+ return this.createPayloadWithParams(botActionNode)
189
+ }
190
+
191
+ return target.id
192
+ }
193
+
194
+ private createPayloadWithParams(botActionNode: HtBotActionNode): string {
195
+ const payloadId = botActionNode.content.payload_id
196
+ const payloadNode = this.getNodeById<HtPayloadNode>(payloadId)
197
+ const customParams = JSON.parse(
198
+ botActionNode.content.payload_params || '{}'
199
+ )
200
+ const payloadJson = JSON.stringify({
201
+ ...customParams,
202
+ followUpId: botActionNode.follow_up?.id,
203
+ })
204
+ return `${payloadNode.content.payload}${SEPARATOR}${payloadJson}`
205
+ }
179
206
  }
package/src/constants.ts CHANGED
@@ -1,2 +1,3 @@
1
- export const SOURCE_INFO_SEPARATOR = '|source_'
1
+ export const SEPARATOR = '|'
2
+ export const SOURCE_INFO_SEPARATOR = `${SEPARATOR}source_`
2
3
  export const VARIABLE_REGEX = /{([^}]+)}/g
@@ -27,14 +27,16 @@ export class FlowButton extends ContentFieldsBase {
27
27
  const newButton = new FlowButton(cmsButton.id)
28
28
  newButton.text = this.getTextByLocale(locale, cmsButton.text)
29
29
  if (cmsButton.target) {
30
- newButton.payload = cmsButton.target.id
30
+ newButton.payload = cmsApi.getPayload(cmsButton.target)
31
31
  }
32
+
33
+ // OLD PAYLOAD
32
34
  if (cmsButton.payload && payloadId) {
33
- const payloadNode = cmsApi.getNodeById(payloadId) as HtPayloadNode
35
+ const payloadNode = cmsApi.getNodeById<HtPayloadNode>(payloadId)
34
36
  newButton.payload = payloadNode.content.payload
35
37
  }
36
38
  if (cmsButton.url && urlId) {
37
- const payloadNode = cmsApi.getNodeById(urlId) as HtUrlNode
39
+ const payloadNode = cmsApi.getNodeById<HtUrlNode>(urlId)
38
40
  newButton.url = payloadNode.content.url
39
41
  }
40
42
 
@@ -6,23 +6,7 @@ import { EventName, trackEvent } from '../action/tracking'
6
6
  import { FlowBuilderApi } from '../api'
7
7
  import { getQueueAvailability } from '../functions/conditional-queue-status'
8
8
  import { ContentFieldsBase } from './content-fields-base'
9
- import {
10
- HtCarouselNode,
11
- HtHandoffNode,
12
- HtImageNode,
13
- HtPayloadNode,
14
- HtQueueLocale,
15
- HtTextNode,
16
- HtVideoNode,
17
- HtWhatsappButtonListNode,
18
- } from './hubtype-fields'
19
-
20
- type HtAfterHandoff =
21
- | HtTextNode
22
- | HtImageNode
23
- | HtVideoNode
24
- | HtCarouselNode
25
- | HtWhatsappButtonListNode
9
+ import { HtHandoffNode, HtPayloadNode, HtQueueLocale } from './hubtype-fields'
26
10
 
27
11
  export class FlowHandoff extends ContentFieldsBase {
28
12
  public code: string
@@ -54,21 +38,18 @@ export class FlowHandoff extends ContentFieldsBase {
54
38
  cmsApi: FlowBuilderApi
55
39
  ): string | undefined {
56
40
  if (cmsHandoff.target?.id) {
57
- const handoffTargetNode = cmsApi.getNodeById<HtAfterHandoff>(
58
- cmsHandoff.target?.id
59
- )
60
- if (handoffTargetNode?.id) return handoffTargetNode?.id
41
+ return cmsApi.getPayload(cmsHandoff.target)
61
42
  }
62
43
 
44
+ // OLD PAYLOAD
63
45
  const payloadId = cmsHandoff.content.payload.find(
64
46
  payload => payload.locale === locale
65
47
  )?.id
48
+ if (payloadId) {
49
+ return cmsApi.getNodeById<HtPayloadNode>(payloadId).content.payload
50
+ }
66
51
 
67
- if (!payloadId) return undefined
68
-
69
- const actionPayload = cmsApi.getNodeById(payloadId)
70
-
71
- return (actionPayload as HtPayloadNode).content.payload
52
+ return undefined
72
53
  }
73
54
 
74
55
  async doHandoff(request: ActionRequest): Promise<void> {
@@ -0,0 +1,11 @@
1
+ import { HtBaseNode } from './common'
2
+ import { HtNodeWithoutContentType } from './node-types'
3
+
4
+ export interface HtBotActionNode extends HtBaseNode {
5
+ id: string
6
+ type: HtNodeWithoutContentType.BOT_ACTION
7
+ content: {
8
+ payload_id: string
9
+ payload_params?: string
10
+ }
11
+ }
@@ -1,3 +1,4 @@
1
+ export * from './bot-action'
1
2
  export * from './button'
2
3
  export * from './carousel'
3
4
  export * from './common'
@@ -15,6 +15,7 @@ export enum HtNodeWithoutContentType {
15
15
  URL = 'url',
16
16
  PAYLOAD = 'payload',
17
17
  GO_TO_FLOW = 'go-to-flow',
18
+ BOT_ACTION = 'bot-action',
18
19
  }
19
20
 
20
21
  export enum HtButtonStyle {
@@ -1,3 +1,4 @@
1
+ import { HtBotActionNode } from './bot-action'
1
2
  import { HtCarouselNode } from './carousel'
2
3
  import { HtFallbackNode } from './fallback'
3
4
  import { HtFunctionNode } from './function'
@@ -24,6 +25,10 @@ export type HtNodeWithContent =
24
25
  | HtFallbackNode
25
26
  | HtWhatsappButtonListNode
26
27
 
27
- export type HtNodeWithoutContent = HtUrlNode | HtPayloadNode | HtGoToFlow
28
+ export type HtNodeWithoutContent =
29
+ | HtUrlNode
30
+ | HtPayloadNode
31
+ | HtGoToFlow
32
+ | HtBotActionNode
28
33
 
29
34
  export type HtNodeComponent = HtNodeWithContent | HtNodeWithoutContent
package/src/index.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import { Plugin, PluginPreRequest, Session } from '@botonic/core'
2
2
  import { ActionRequest } from '@botonic/react'
3
3
 
4
+ import { getNodeByUserInput } from './action/user-input'
4
5
  import { FlowBuilderApi } from './api'
5
- import { SOURCE_INFO_SEPARATOR } from './constants'
6
+ import { SEPARATOR, SOURCE_INFO_SEPARATOR } from './constants'
6
7
  import {
7
8
  FlowCarousel,
8
9
  FlowContent,
@@ -20,7 +21,11 @@ import {
20
21
  HtNodeWithContentType,
21
22
  } from './content-fields/hubtype-fields'
22
23
  import { DEFAULT_FUNCTIONS } from './functions'
23
- import { BotonicPluginFlowBuilderOptions, KnowledgeBaseResponse } from './types'
24
+ import {
25
+ BotonicPluginFlowBuilderOptions,
26
+ KnowledgeBaseResponse,
27
+ PayloadParamsBase,
28
+ } from './types'
24
29
  import { resolveGetAccessToken } from './utils'
25
30
 
26
31
  export default class BotonicPluginFlowBuilder implements Plugin {
@@ -59,6 +64,21 @@ export default class BotonicPluginFlowBuilder implements Plugin {
59
64
  accessToken: this.getAccessToken(request.session),
60
65
  request: this.currentRequest,
61
66
  })
67
+
68
+ const checkUserTextInput =
69
+ request.input.data &&
70
+ !request.input.payload &&
71
+ !request.session.is_first_interaction
72
+
73
+ if (checkUserTextInput) {
74
+ const nodeByUserInput = await getNodeByUserInput(
75
+ this.cmsApi,
76
+ this.getLocale(request.session),
77
+ request as unknown as ActionRequest
78
+ )
79
+ request.input.payload = this.cmsApi.getPayload(nodeByUserInput?.target)
80
+ }
81
+
62
82
  if (request.input.payload) {
63
83
  request.input.payload = request.input.payload?.split(
64
84
  SOURCE_INFO_SEPARATOR
@@ -165,8 +185,13 @@ export default class BotonicPluginFlowBuilder implements Plugin {
165
185
  }
166
186
  return result.target.id
167
187
  }
188
+
189
+ getPayloadParams<T extends PayloadParamsBase>(payload: string): T {
190
+ const payloadParams = JSON.parse(payload.split(SEPARATOR)[1] || '{}')
191
+ return payloadParams
192
+ }
168
193
  }
169
194
 
170
195
  export * from './action'
171
196
  export * from './content-fields'
172
- export { BotonicPluginFlowBuilderOptions } from './types'
197
+ export { BotonicPluginFlowBuilderOptions, PayloadParamsBase } from './types'
package/src/types.ts CHANGED
@@ -39,3 +39,7 @@ export interface KnowledgeBaseResponse {
39
39
  page?: number
40
40
  }[]
41
41
  }
42
+
43
+ export interface PayloadParamsBase {
44
+ followUpId?: string
45
+ }