@botonic/plugin-flow-builder 0.57.0-rslib-esm.2 → 0.58.0-alpha-new-stack.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.
Files changed (93) hide show
  1. package/lib/action/ai-agent-from-user-input.js +8 -0
  2. package/lib/action/ai-agent-from-user-input.js.map +1 -1
  3. package/lib/action/first-interaction.js +10 -0
  4. package/lib/action/first-interaction.js.map +1 -1
  5. package/lib/action/get-contents.js +5 -2
  6. package/lib/action/get-contents.js.map +1 -1
  7. package/lib/action/index.js +8 -1
  8. package/lib/action/index.js.map +1 -1
  9. package/lib/api.d.ts +8 -3
  10. package/lib/api.js +37 -13
  11. package/lib/api.js.map +1 -1
  12. package/lib/bot-context-manager.d.ts +17 -0
  13. package/lib/bot-context-manager.js +101 -0
  14. package/lib/bot-context-manager.js.map +1 -0
  15. package/lib/constants.d.ts +2 -1
  16. package/lib/constants.js +4 -3
  17. package/lib/constants.js.map +1 -1
  18. package/lib/content-fields/contact-reasons-conditional-matcher.d.ts +4 -0
  19. package/lib/content-fields/contact-reasons-conditional-matcher.js +10 -0
  20. package/lib/content-fields/contact-reasons-conditional-matcher.js.map +1 -0
  21. package/lib/content-fields/flow-ai-agent-base.js +1 -1
  22. package/lib/content-fields/flow-ai-agent-base.js.map +1 -1
  23. package/lib/content-fields/flow-ai-agent-router.js +2 -1
  24. package/lib/content-fields/flow-ai-agent-router.js.map +1 -1
  25. package/lib/content-fields/flow-ai-agent.js +2 -1
  26. package/lib/content-fields/flow-ai-agent.js.map +1 -1
  27. package/lib/content-fields/flow-contact-reasons-conditional.d.ts +14 -0
  28. package/lib/content-fields/flow-contact-reasons-conditional.js +68 -0
  29. package/lib/content-fields/flow-contact-reasons-conditional.js.map +1 -0
  30. package/lib/content-fields/flow-do-nothing.d.ts +9 -0
  31. package/lib/content-fields/flow-do-nothing.js +33 -0
  32. package/lib/content-fields/flow-do-nothing.js.map +1 -0
  33. package/lib/content-fields/flow-handoff.d.ts +7 -1
  34. package/lib/content-fields/flow-handoff.js +41 -3
  35. package/lib/content-fields/flow-handoff.js.map +1 -1
  36. package/lib/content-fields/flow-whatsapp-request-contact-info.js +1 -0
  37. package/lib/content-fields/flow-whatsapp-request-contact-info.js.map +1 -1
  38. package/lib/content-fields/hubtype-fields/contact-reasons-conditional.d.ts +16 -0
  39. package/lib/content-fields/hubtype-fields/contact-reasons-conditional.js +4 -0
  40. package/lib/content-fields/hubtype-fields/contact-reasons-conditional.js.map +1 -0
  41. package/lib/content-fields/hubtype-fields/do-nothing.d.ts +6 -0
  42. package/lib/content-fields/hubtype-fields/do-nothing.js +4 -0
  43. package/lib/content-fields/hubtype-fields/do-nothing.js.map +1 -0
  44. package/lib/content-fields/hubtype-fields/handoff.d.ts +11 -1
  45. package/lib/content-fields/hubtype-fields/handoff.js +7 -1
  46. package/lib/content-fields/hubtype-fields/handoff.js.map +1 -1
  47. package/lib/content-fields/hubtype-fields/index.d.ts +1 -0
  48. package/lib/content-fields/hubtype-fields/index.js +2 -0
  49. package/lib/content-fields/hubtype-fields/index.js.map +1 -1
  50. package/lib/content-fields/hubtype-fields/node-types.d.ts +3 -1
  51. package/lib/content-fields/hubtype-fields/node-types.js +2 -0
  52. package/lib/content-fields/hubtype-fields/node-types.js.map +1 -1
  53. package/lib/content-fields/hubtype-fields/nodes.d.ts +3 -1
  54. package/lib/content-fields/hubtype-fields/nodes.js.map +1 -1
  55. package/lib/content-fields/hubtype-fields/whatsapp-request-contact-info.d.ts +2 -0
  56. package/lib/content-fields/hubtype-fields/whatsapp-request-contact-info.js.map +1 -1
  57. package/lib/content-fields/index.d.ts +4 -2
  58. package/lib/content-fields/index.js +6 -0
  59. package/lib/content-fields/index.js.map +1 -1
  60. package/lib/flow-factory.js +5 -1
  61. package/lib/flow-factory.js.map +1 -1
  62. package/lib/index.d.ts +5 -8
  63. package/lib/index.js +17 -55
  64. package/lib/index.js.map +1 -1
  65. package/lib/types.d.ts +2 -2
  66. package/lib/types.js.map +1 -1
  67. package/package.json +3 -3
  68. package/src/action/ai-agent-from-user-input.ts +7 -0
  69. package/src/action/first-interaction.ts +6 -0
  70. package/src/action/get-contents.ts +17 -2
  71. package/src/action/index.tsx +7 -0
  72. package/src/api.ts +52 -15
  73. package/src/bot-context-manager.ts +153 -0
  74. package/src/constants.ts +2 -1
  75. package/src/content-fields/contact-reasons-conditional-matcher.ts +24 -0
  76. package/src/content-fields/flow-ai-agent-base.tsx +1 -1
  77. package/src/content-fields/flow-ai-agent-router.tsx +1 -0
  78. package/src/content-fields/flow-ai-agent.tsx +1 -0
  79. package/src/content-fields/flow-contact-reasons-conditional.tsx +90 -0
  80. package/src/content-fields/flow-do-nothing.tsx +29 -0
  81. package/src/content-fields/flow-handoff.tsx +54 -7
  82. package/src/content-fields/flow-whatsapp-request-contact-info.tsx +2 -0
  83. package/src/content-fields/hubtype-fields/contact-reasons-conditional.ts +18 -0
  84. package/src/content-fields/hubtype-fields/do-nothing.ts +7 -0
  85. package/src/content-fields/hubtype-fields/handoff.ts +17 -1
  86. package/src/content-fields/hubtype-fields/index.ts +1 -0
  87. package/src/content-fields/hubtype-fields/node-types.ts +2 -0
  88. package/src/content-fields/hubtype-fields/nodes.ts +4 -0
  89. package/src/content-fields/hubtype-fields/whatsapp-request-contact-info.ts +2 -0
  90. package/src/content-fields/index.ts +6 -0
  91. package/src/flow-factory.ts +11 -0
  92. package/src/index.ts +26 -88
  93. package/src/types.ts +1 -2
@@ -1,3 +1,4 @@
1
+ import type { HtButton } from './button'
1
2
  import type { HtBaseNode, HtTextLocale } from './common'
2
3
  import type { HtNodeWithContentType } from './node-types'
3
4
 
@@ -5,5 +6,6 @@ export interface HtWhatsappRequestContactInfoNode extends HtBaseNode {
5
6
  type: HtNodeWithContentType.WHATSAPP_REQUEST_CONTACT_INFO
6
7
  content: {
7
8
  text: HtTextLocale[]
9
+ button: HtButton
8
10
  }
9
11
  }
@@ -5,8 +5,10 @@ import { FlowBotAction } from './flow-bot-action'
5
5
  import { FlowCaptureUserInput } from './flow-capture-user-input'
6
6
  import { FlowCarousel } from './flow-carousel'
7
7
  import { FlowChannelConditional } from './flow-channel-conditional'
8
+ import { FlowContactReasonsConditional } from './flow-contact-reasons-conditional'
8
9
  import { FlowCountryConditional } from './flow-country-conditional'
9
10
  import { FlowCustomConditional } from './flow-custom-conditional'
11
+ import { FlowDoNothing } from './flow-do-nothing'
10
12
  import { FlowGoToFlow } from './flow-go-to-flow'
11
13
  import { FlowHandoff } from './flow-handoff'
12
14
  import { FlowImage } from './flow-image'
@@ -33,9 +35,11 @@ export {
33
35
  FlowCaptureUserInput,
34
36
  FlowCarousel,
35
37
  FlowChannelConditional,
38
+ FlowContactReasonsConditional,
36
39
  FlowCountryConditional,
37
40
  FlowCustomConditional,
38
41
  FlowCustomConditionalV2,
42
+ FlowDoNothing,
39
43
  FlowGoToFlow,
40
44
  FlowHandoff,
41
45
  FlowImage,
@@ -72,3 +76,5 @@ export type FlowContent =
72
76
  | FlowCaptureUserInput
73
77
  | FlowAiAgentRouter
74
78
  | FlowCustomConditionalV2
79
+ | FlowDoNothing
80
+ | FlowContactReasonsConditional
@@ -7,10 +7,12 @@ import {
7
7
  FlowBotAction,
8
8
  FlowCarousel,
9
9
  FlowChannelConditional,
10
+ FlowContactReasonsConditional,
10
11
  type FlowContent,
11
12
  FlowCountryConditional,
12
13
  FlowCustomConditional,
13
14
  FlowCustomConditionalV2,
15
+ FlowDoNothing,
14
16
  FlowGoToFlow,
15
17
  FlowHandoff,
16
18
  FlowImage,
@@ -118,6 +120,15 @@ export class FlowFactory {
118
120
  this.botContext
119
121
  )
120
122
 
123
+ case HtNodeWithContentType.DO_NOTHING:
124
+ return FlowDoNothing.fromHubtypeCMS(hubtypeContent)
125
+
126
+ case HtNodeWithContentType.CONTACT_REASONS_CONDITION:
127
+ return FlowContactReasonsConditional.fromHubtypeCMS(
128
+ hubtypeContent,
129
+ this.botContext
130
+ )
131
+
121
132
  default:
122
133
  return undefined
123
134
  }
package/src/index.ts CHANGED
@@ -1,24 +1,16 @@
1
- import {
2
- INPUT,
3
- type Plugin,
4
- type PluginPreRequest,
5
- PROVIDER,
6
- type ResolvedPlugins,
7
- type Session,
1
+ import type {
2
+ BotContext,
3
+ Plugin,
4
+ ResolvedPlugins,
5
+ Session,
8
6
  } from '@botonic/core'
9
- import type { ActionRequest } from '@botonic/react'
10
7
  import { v7 as uuidv7 } from 'uuid'
11
8
 
12
9
  import { FlowBuilderApi } from './api'
13
- import {
14
- EMPTY_PAYLOAD,
15
- FLOW_BUILDER_API_URL_PROD,
16
- SEPARATOR,
17
- SOURCE_INFO_SEPARATOR,
18
- } from './constants'
10
+ import { BotContextManager } from './bot-context-manager'
11
+ import { FLOW_BUILDER_API_URL_PROD, SEPARATOR } from './constants'
19
12
  import type { FlowContent } from './content-fields'
20
13
  import {
21
- type HtBotActionNode,
22
14
  type HtFlowBuilderData,
23
15
  type HtNodeWithContent,
24
16
  HtNodeWithContentType,
@@ -35,10 +27,8 @@ import {
35
27
  type RatingSubmittedInfo,
36
28
  type TrackEventFunction,
37
29
  } from './types'
38
- import { getNextPayloadByUserInput } from './user-input'
39
30
  import type { SmartIntentsInferenceConfig } from './user-input/smart-intent'
40
31
  import { resolveGetAccessToken } from './utils/authentication'
41
- import { inputHasTextOrTranscript } from './utils/input'
42
32
 
43
33
  // TODO: Create a proper service to wrap all calls and allow api versioning
44
34
 
@@ -46,7 +36,7 @@ export default class BotonicPluginFlowBuilder implements Plugin {
46
36
  public cmsApi: FlowBuilderApi
47
37
  private flow?: HtFlowBuilderData
48
38
  private functions: Record<any, any>
49
- private currentRequest: PluginPreRequest
39
+ private botContext: BotContext
50
40
  public getAccessToken: (session: Session) => string
51
41
  public trackEvent?: TrackEventFunction
52
42
  public getAiAgentResponse?: AiAgentFunction
@@ -85,85 +75,33 @@ export default class BotonicPluginFlowBuilder implements Plugin {
85
75
  options.disableAIAgentInFirstInteraction || false
86
76
  }
87
77
 
88
- resolveFlowUrl(request: PluginPreRequest): string {
89
- if (request.session.is_test_integration) {
78
+ resolveFlowUrl(botContext: BotContext): string {
79
+ if (botContext.session.is_test_integration) {
90
80
  return `${this.apiUrl}/v1/bot_flows/{bot_id}/versions/${FlowBuilderJSONVersion.DRAFT}/`
91
81
  }
92
82
  return `${this.apiUrl}/v1/bot_flows/{bot_id}/versions/${this.jsonVersion}/`
93
83
  }
94
84
 
95
- async pre(request: PluginPreRequest): Promise<void> {
96
- // When AI Agent is executed in Whatsapp, button payloads come as referral and must be converted to text being processed by the agent.
97
- this.convertWhatsappAiAgentEmptyPayloads(request)
98
-
99
- this.currentRequest = request
85
+ async pre(botContext: BotContext): Promise<void> {
86
+ this.botContext = botContext
100
87
  this.cmsApi = await FlowBuilderApi.create({
101
- flowUrl: this.resolveFlowUrl(request),
88
+ flowUrl: this.resolveFlowUrl(botContext),
102
89
  url: this.apiUrl,
103
90
  flow: this.flow,
104
- accessToken: this.getAccessToken(request.session),
105
- request: this.currentRequest,
91
+ accessToken: this.getAccessToken(botContext.session),
92
+ botContext: this.botContext,
106
93
  })
107
94
 
108
- const checkUserTextInput =
109
- inputHasTextOrTranscript(request.input) && !request.input.payload
110
-
111
- if (checkUserTextInput) {
112
- const resolvedLocale = this.cmsApi.getResolvedLocale()
113
- const nextPayload = await getNextPayloadByUserInput(
114
- this.cmsApi,
115
- resolvedLocale,
116
- request as unknown as ActionRequest,
117
- this.smartIntentsConfig
118
- )
119
- request.input.payload = nextPayload
120
- }
121
-
122
- await this.updateRequestBeforeRoutes(request)
123
- }
124
-
125
- private convertWhatsappAiAgentEmptyPayloads(request: PluginPreRequest): void {
126
- if (request.session.user.provider === PROVIDER.WHATSAPP) {
127
- const shouldUseReferral =
128
- request.input.referral &&
129
- request.input.payload?.startsWith(EMPTY_PAYLOAD)
130
-
131
- if (shouldUseReferral) {
132
- request.input.type = INPUT.TEXT
133
- request.input.data = request.input.referral
134
- }
135
- }
136
- }
137
-
138
- private async updateRequestBeforeRoutes(
139
- request: PluginPreRequest
140
- ): Promise<void> {
141
- this.cmsApi.removeCaptureUserInputId()
142
- if (request.input.payload) {
143
- request.input.payload = this.removeSourceSuffix(request.input.payload)
144
-
145
- if (this.cmsApi.isBotAction(request.input.payload)) {
146
- const cmsBotAction = this.cmsApi.getNodeById<HtBotActionNode>(
147
- request.input.payload
148
- )
149
-
150
- request.input.payload =
151
- this.cmsApi.createPayloadWithParams(cmsBotAction)
152
-
153
- // Re-execute convertWhatsappAiAgentEmptyPayloads function to handle
154
- // the case that a BotAction has a payload equals to EMPTY_PAYLOAD
155
- this.convertWhatsappAiAgentEmptyPayloads(request)
156
- }
157
- }
158
- }
159
-
160
- private removeSourceSuffix(payload: string): string {
161
- return payload.split(SOURCE_INFO_SEPARATOR)[0]
95
+ const botContextManager = new BotContextManager(
96
+ this.cmsApi,
97
+ this.smartIntentsConfig
98
+ )
99
+ await botContextManager.prepareInputForRoutes(botContext)
162
100
  }
163
101
 
164
- post(request: PluginPreRequest): void {
165
- request.input.nluResolution = undefined
166
- delete request.session.user.system_locale_updated
102
+ post(botContext: BotContext): void {
103
+ botContext.input.nluResolution = undefined
104
+ delete botContext.session.user.system_locale_updated
167
105
  }
168
106
 
169
107
  async getContentsByContentID(
@@ -189,7 +127,7 @@ export default class BotonicPluginFlowBuilder implements Plugin {
189
127
 
190
128
  async getStartContents(): Promise<FlowContent[]> {
191
129
  const startNode = this.cmsApi.getStartNode()
192
- this.currentRequest.session.flow_thread_id = uuidv7()
130
+ this.botContext.session.flow_thread_id = uuidv7()
193
131
  return await this.getContentsByNode(startNode)
194
132
  }
195
133
 
@@ -206,7 +144,7 @@ export default class BotonicPluginFlowBuilder implements Plugin {
206
144
  ) {
207
145
  const customFunctionResolver = new CustomFunction(
208
146
  this.functions,
209
- this.currentRequest,
147
+ this.botContext,
210
148
  resolvedLocale
211
149
  )
212
150
  const targetId = await customFunctionResolver.call(node)
@@ -214,7 +152,7 @@ export default class BotonicPluginFlowBuilder implements Plugin {
214
152
  }
215
153
 
216
154
  const flowFactory = new FlowFactory(
217
- this.currentRequest,
155
+ this.botContext,
218
156
  this.cmsApi,
219
157
  resolvedLocale
220
158
  )
package/src/types.ts CHANGED
@@ -3,7 +3,6 @@ import type {
3
3
  BotContext,
4
4
  GuardrailRule,
5
5
  InferenceResponse,
6
- PluginPreRequest,
7
6
  ResolvedPlugins,
8
7
  } from '@botonic/core'
9
8
  import type { FlowContent } from './content-fields'
@@ -67,7 +66,7 @@ export interface FlowBuilderApiOptions {
67
66
  flowUrl: string
68
67
  flow?: HtFlowBuilderData
69
68
  accessToken: string
70
- request: PluginPreRequest
69
+ botContext: BotContext
71
70
  }
72
71
 
73
72
  export enum ProcessEnvNodeEnvs {