@botonic/plugin-flow-builder 0.45.0-alpha.1 → 0.46.0-alpha-3
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/ai-agent.js +2 -0
- package/lib/cjs/action/ai-agent.js.map +1 -1
- package/lib/cjs/action/first-interaction.js +1 -1
- package/lib/cjs/action/first-interaction.js.map +1 -1
- package/lib/cjs/action/index.js +1 -1
- package/lib/cjs/action/index.js.map +1 -1
- package/lib/cjs/action/knowledge-bases.js +1 -1
- package/lib/cjs/action/knowledge-bases.js.map +1 -1
- package/lib/cjs/api.d.ts +1 -0
- package/lib/cjs/api.js +4 -0
- package/lib/cjs/api.js.map +1 -1
- package/lib/cjs/content-fields/flow-ai-agent.d.ts +3 -1
- package/lib/cjs/content-fields/flow-ai-agent.js +5 -0
- package/lib/cjs/content-fields/flow-ai-agent.js.map +1 -1
- package/lib/cjs/content-fields/flow-go-to-flow.d.ts +1 -0
- package/lib/cjs/content-fields/flow-go-to-flow.js +8 -0
- package/lib/cjs/content-fields/flow-go-to-flow.js.map +1 -1
- package/lib/cjs/content-fields/flow-whatsapp-template.d.ts +2 -1
- package/lib/cjs/content-fields/flow-whatsapp-template.js +13 -5
- package/lib/cjs/content-fields/flow-whatsapp-template.js.map +1 -1
- package/lib/cjs/content-fields/hubtype-fields/ai-agent.d.ts +3 -0
- package/lib/cjs/content-fields/hubtype-fields/whatsapp-template.d.ts +11 -8
- package/lib/cjs/flow-factory.js +1 -1
- package/lib/cjs/flow-factory.js.map +1 -1
- package/lib/cjs/index.d.ts +1 -1
- package/lib/cjs/index.js +8 -3
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/user-input/capture-user-input-api.d.ts +2 -1
- package/lib/cjs/user-input/capture-user-input-api.js +6 -5
- package/lib/cjs/user-input/capture-user-input-api.js.map +1 -1
- package/lib/cjs/user-input/index.js +6 -4
- package/lib/cjs/user-input/index.js.map +1 -1
- package/lib/cjs/user-input/keyword.d.ts +4 -2
- package/lib/cjs/user-input/keyword.js +5 -4
- package/lib/cjs/user-input/keyword.js.map +1 -1
- package/lib/cjs/user-input/smart-intent.d.ts +2 -2
- package/lib/cjs/user-input/smart-intent.js +5 -5
- package/lib/cjs/user-input/smart-intent.js.map +1 -1
- package/lib/cjs/utils.d.ts +2 -1
- package/lib/cjs/utils.js +16 -3
- package/lib/cjs/utils.js.map +1 -1
- package/lib/esm/action/ai-agent.js +2 -0
- package/lib/esm/action/ai-agent.js.map +1 -1
- package/lib/esm/action/first-interaction.js +1 -1
- package/lib/esm/action/first-interaction.js.map +1 -1
- package/lib/esm/action/index.js +1 -1
- package/lib/esm/action/index.js.map +1 -1
- package/lib/esm/action/knowledge-bases.js +1 -1
- package/lib/esm/action/knowledge-bases.js.map +1 -1
- package/lib/esm/api.d.ts +1 -0
- package/lib/esm/api.js +4 -0
- package/lib/esm/api.js.map +1 -1
- package/lib/esm/content-fields/flow-ai-agent.d.ts +3 -1
- package/lib/esm/content-fields/flow-ai-agent.js +5 -0
- package/lib/esm/content-fields/flow-ai-agent.js.map +1 -1
- package/lib/esm/content-fields/flow-go-to-flow.d.ts +1 -0
- package/lib/esm/content-fields/flow-go-to-flow.js +8 -0
- package/lib/esm/content-fields/flow-go-to-flow.js.map +1 -1
- package/lib/esm/content-fields/flow-whatsapp-template.d.ts +2 -1
- package/lib/esm/content-fields/flow-whatsapp-template.js +13 -5
- package/lib/esm/content-fields/flow-whatsapp-template.js.map +1 -1
- package/lib/esm/content-fields/hubtype-fields/ai-agent.d.ts +3 -0
- package/lib/esm/content-fields/hubtype-fields/whatsapp-template.d.ts +11 -8
- package/lib/esm/flow-factory.js +1 -1
- package/lib/esm/flow-factory.js.map +1 -1
- package/lib/esm/index.d.ts +1 -1
- package/lib/esm/index.js +8 -3
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/user-input/capture-user-input-api.d.ts +2 -1
- package/lib/esm/user-input/capture-user-input-api.js +6 -5
- package/lib/esm/user-input/capture-user-input-api.js.map +1 -1
- package/lib/esm/user-input/index.js +6 -4
- package/lib/esm/user-input/index.js.map +1 -1
- package/lib/esm/user-input/keyword.d.ts +4 -2
- package/lib/esm/user-input/keyword.js +5 -4
- package/lib/esm/user-input/keyword.js.map +1 -1
- package/lib/esm/user-input/smart-intent.d.ts +2 -2
- package/lib/esm/user-input/smart-intent.js +5 -5
- package/lib/esm/user-input/smart-intent.js.map +1 -1
- package/lib/esm/utils.d.ts +2 -1
- package/lib/esm/utils.js +16 -3
- package/lib/esm/utils.js.map +1 -1
- package/package.json +3 -3
- package/src/action/ai-agent.ts +2 -0
- package/src/action/first-interaction.ts +2 -2
- package/src/action/index.tsx +2 -2
- package/src/action/knowledge-bases.ts +2 -2
- package/src/api.ts +5 -0
- package/src/content-fields/flow-ai-agent.tsx +5 -1
- package/src/content-fields/flow-go-to-flow.tsx +13 -1
- package/src/content-fields/flow-whatsapp-template.tsx +26 -5
- package/src/content-fields/hubtype-fields/ai-agent.ts +3 -0
- package/src/content-fields/hubtype-fields/whatsapp-template.ts +13 -9
- package/src/flow-factory.ts +1 -1
- package/src/index.ts +19 -5
- package/src/user-input/capture-user-input-api.ts +12 -6
- package/src/user-input/index.ts +9 -7
- package/src/user-input/keyword.ts +10 -4
- package/src/user-input/smart-intent.ts +4 -4
- package/src/utils.ts +18 -2
|
@@ -69,18 +69,22 @@ export interface HtWhatsAppTemplate {
|
|
|
69
69
|
namespace: string
|
|
70
70
|
parameter_format: string
|
|
71
71
|
}
|
|
72
|
+
|
|
73
|
+
export interface HtWhatsappTemplateContentByLocale {
|
|
74
|
+
template: HtWhatsAppTemplate
|
|
75
|
+
header_variables?: {
|
|
76
|
+
type: WhatsAppTemplateParameterType
|
|
77
|
+
text?: Record<string, string>
|
|
78
|
+
media?: HtMediaFileLocale[]
|
|
79
|
+
}
|
|
80
|
+
variable_values: Record<string, string>
|
|
81
|
+
url_variable_values?: Record<string, string>
|
|
82
|
+
}
|
|
83
|
+
|
|
72
84
|
export interface HtWhatsappTemplateNode extends HtBaseNode {
|
|
73
85
|
type: HtNodeWithContentType.WHATSAPP_TEMPLATE
|
|
74
86
|
content: {
|
|
75
|
-
|
|
76
|
-
header_variables?: {
|
|
77
|
-
type: WhatsAppTemplateParameterType
|
|
78
|
-
text?: Record<string, string>
|
|
79
|
-
media?: HtMediaFileLocale[]
|
|
80
|
-
}
|
|
81
|
-
variable_values: Record<string, string>
|
|
82
|
-
|
|
87
|
+
by_locale: Record<string, HtWhatsappTemplateContentByLocale>
|
|
83
88
|
buttons: HtButton[]
|
|
84
|
-
url_variable_values?: Record<string, string>
|
|
85
89
|
}
|
|
86
90
|
}
|
package/src/flow-factory.ts
CHANGED
|
@@ -93,7 +93,7 @@ export class FlowFactory {
|
|
|
93
93
|
return FlowGoToFlow.fromHubtypeCMS(hubtypeContent, this.cmsApi)
|
|
94
94
|
|
|
95
95
|
case HtNodeWithContentType.WHATSAPP_TEMPLATE:
|
|
96
|
-
return FlowWhatsappTemplate.fromHubtypeCMS(hubtypeContent)
|
|
96
|
+
return FlowWhatsappTemplate.fromHubtypeCMS(hubtypeContent, this.locale)
|
|
97
97
|
|
|
98
98
|
case HtNodeWithContentType.CAPTURE_USER_INPUT:
|
|
99
99
|
return FlowCaptureUserInput.fromHubtypeCMS(hubtypeContent)
|
package/src/index.ts
CHANGED
|
@@ -16,10 +16,11 @@ import {
|
|
|
16
16
|
SEPARATOR,
|
|
17
17
|
SOURCE_INFO_SEPARATOR,
|
|
18
18
|
} from './constants'
|
|
19
|
-
import type
|
|
19
|
+
import { type FlowContent, FlowGoToFlow } from './content-fields'
|
|
20
20
|
import {
|
|
21
21
|
type HtBotActionNode,
|
|
22
22
|
type HtFlowBuilderData,
|
|
23
|
+
type HtGoToFlow,
|
|
23
24
|
type HtNodeWithContent,
|
|
24
25
|
HtNodeWithContentType,
|
|
25
26
|
} from './content-fields/hubtype-fields'
|
|
@@ -38,7 +39,7 @@ import {
|
|
|
38
39
|
} from './types'
|
|
39
40
|
import { getNextPayloadByUserInput } from './user-input'
|
|
40
41
|
import type { SmartIntentsInferenceConfig } from './user-input/smart-intent'
|
|
41
|
-
import {
|
|
42
|
+
import { inputHasTextOrTranscript, resolveGetAccessToken } from './utils'
|
|
42
43
|
|
|
43
44
|
// TODO: Create a proper service to wrap all calls and allow api versioning
|
|
44
45
|
|
|
@@ -109,7 +110,7 @@ export default class BotonicPluginFlowBuilder implements Plugin {
|
|
|
109
110
|
})
|
|
110
111
|
|
|
111
112
|
const checkUserTextInput =
|
|
112
|
-
|
|
113
|
+
inputHasTextOrTranscript(request.input) && !request.input.payload
|
|
113
114
|
|
|
114
115
|
if (checkUserTextInput) {
|
|
115
116
|
const resolvedLocale = this.cmsApi.getResolvedLocale()
|
|
@@ -122,7 +123,7 @@ export default class BotonicPluginFlowBuilder implements Plugin {
|
|
|
122
123
|
request.input.payload = nextPayload
|
|
123
124
|
}
|
|
124
125
|
|
|
125
|
-
this.updateRequestBeforeRoutes(request)
|
|
126
|
+
await this.updateRequestBeforeRoutes(request)
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
private convertWhatsappAiAgentEmptyPayloads(request: PluginPreRequest): void {
|
|
@@ -138,7 +139,9 @@ export default class BotonicPluginFlowBuilder implements Plugin {
|
|
|
138
139
|
}
|
|
139
140
|
}
|
|
140
141
|
|
|
141
|
-
private updateRequestBeforeRoutes(
|
|
142
|
+
private async updateRequestBeforeRoutes(
|
|
143
|
+
request: PluginPreRequest
|
|
144
|
+
): Promise<void> {
|
|
142
145
|
this.cmsApi.removeCaptureUserInputId()
|
|
143
146
|
if (request.input.payload) {
|
|
144
147
|
request.input.payload = this.removeSourceSuffix(request.input.payload)
|
|
@@ -155,6 +158,17 @@ export default class BotonicPluginFlowBuilder implements Plugin {
|
|
|
155
158
|
// the case that a BotAction has a payload equals to EMPTY_PAYLOAD
|
|
156
159
|
this.convertWhatsappAiAgentEmptyPayloads(request)
|
|
157
160
|
}
|
|
161
|
+
|
|
162
|
+
if (this.cmsApi.isGoToFlow(request.input.payload)) {
|
|
163
|
+
const cmsGoToFlow = this.cmsApi.getNodeById<HtGoToFlow>(
|
|
164
|
+
request.input.payload
|
|
165
|
+
)
|
|
166
|
+
await FlowGoToFlow.resolveToAiAgentsFlow(
|
|
167
|
+
request,
|
|
168
|
+
cmsGoToFlow,
|
|
169
|
+
this.cmsApi
|
|
170
|
+
)
|
|
171
|
+
}
|
|
158
172
|
}
|
|
159
173
|
}
|
|
160
174
|
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
getCommonFlowContentEventArgsForContentId,
|
|
14
14
|
trackEvent,
|
|
15
15
|
} from '../tracking'
|
|
16
|
-
import {
|
|
16
|
+
import { inputHasTextOrTranscript } from '../utils'
|
|
17
17
|
|
|
18
18
|
interface AiCaptureResponseSuccess {
|
|
19
19
|
success: true
|
|
@@ -29,19 +29,25 @@ type AiCaptureResponse = AiCaptureResponseSuccess | AiCaptureResponseFailure
|
|
|
29
29
|
export class CaptureUserInputApi {
|
|
30
30
|
private cmsApi: FlowBuilderApi
|
|
31
31
|
private request: ActionRequest
|
|
32
|
+
private textOrTranscript: string
|
|
32
33
|
|
|
33
|
-
constructor(
|
|
34
|
+
constructor(
|
|
35
|
+
cmsApi: FlowBuilderApi,
|
|
36
|
+
request: ActionRequest,
|
|
37
|
+
textOrTranscript: string
|
|
38
|
+
) {
|
|
34
39
|
this.cmsApi = cmsApi
|
|
35
40
|
this.request = request
|
|
41
|
+
this.textOrTranscript = textOrTranscript
|
|
36
42
|
}
|
|
37
43
|
|
|
38
44
|
async getNextNodeId(): Promise<string | undefined> {
|
|
39
45
|
if (
|
|
40
|
-
|
|
46
|
+
inputHasTextOrTranscript(this.request.input) &&
|
|
41
47
|
this.cmsApi.shouldCaptureUserInput()
|
|
42
48
|
) {
|
|
43
49
|
const captureUserInputNode = this.cmsApi.getCaptureUserInputNode()
|
|
44
|
-
if (!captureUserInputNode) {
|
|
50
|
+
if (!captureUserInputNode || !this.textOrTranscript) {
|
|
45
51
|
return undefined
|
|
46
52
|
}
|
|
47
53
|
const captureUserInput =
|
|
@@ -50,7 +56,7 @@ export class CaptureUserInputApi {
|
|
|
50
56
|
if (captureUserInput.aiValidationType === HtAiValidationType.NONE) {
|
|
51
57
|
this.cmsApi.setUserExtraDataVariable(
|
|
52
58
|
captureUserInputNode.content.field_name,
|
|
53
|
-
this.
|
|
59
|
+
this.textOrTranscript
|
|
54
60
|
)
|
|
55
61
|
await this.trackUserInputCapture(captureUserInputNode, true)
|
|
56
62
|
return captureUserInput.captureSuccessId
|
|
@@ -82,7 +88,7 @@ export class CaptureUserInputApi {
|
|
|
82
88
|
field_name: captureUserInputNode.content.field_name,
|
|
83
89
|
validation_instructions:
|
|
84
90
|
captureUserInputNode.content.ai_validation_instructions,
|
|
85
|
-
user_input: this.
|
|
91
|
+
user_input: this.textOrTranscript,
|
|
86
92
|
}
|
|
87
93
|
const pluginFlowBuilder = getFlowBuilderPlugin(this.request.plugins)
|
|
88
94
|
const token = pluginFlowBuilder.getAccessToken(this.request.session)
|
package/src/user-input/index.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { ActionRequest } from '@botonic/react'
|
|
|
2
2
|
|
|
3
3
|
import type { FlowBuilderApi } from '../api'
|
|
4
4
|
import {
|
|
5
|
-
|
|
5
|
+
getTextOrTranscript,
|
|
6
6
|
isKeywordsAllowed,
|
|
7
7
|
isSmartIntentsAllowed,
|
|
8
8
|
} from '../utils'
|
|
@@ -19,11 +19,13 @@ export async function getNextPayloadByUserInput(
|
|
|
19
19
|
request: ActionRequest,
|
|
20
20
|
smartIntentsConfig: SmartIntentsInferenceConfig
|
|
21
21
|
): Promise<string | undefined> {
|
|
22
|
-
|
|
22
|
+
const userTextOrTranscript = getTextOrTranscript(request.input)
|
|
23
|
+
if (userTextOrTranscript) {
|
|
23
24
|
if (cmsApi.shouldCaptureUserInput()) {
|
|
24
25
|
const captureUserInputApi = new CaptureUserInputApi(
|
|
25
26
|
cmsApi,
|
|
26
|
-
request
|
|
27
|
+
request,
|
|
28
|
+
userTextOrTranscript
|
|
27
29
|
)
|
|
28
30
|
return await captureUserInputApi.getNextNodeId()
|
|
29
31
|
}
|
|
@@ -33,10 +35,9 @@ export async function getNextPayloadByUserInput(
|
|
|
33
35
|
cmsApi,
|
|
34
36
|
locale,
|
|
35
37
|
request,
|
|
38
|
+
userTextOrTranscript,
|
|
36
39
|
})
|
|
37
|
-
const keywordNode = await keywordMatcher.getNodeByInput(
|
|
38
|
-
request.input.data!
|
|
39
|
-
)
|
|
40
|
+
const keywordNode = await keywordMatcher.getNodeByInput()
|
|
40
41
|
if (keywordNode) {
|
|
41
42
|
return cmsApi.getPayload(keywordNode.target)
|
|
42
43
|
}
|
|
@@ -46,7 +47,8 @@ export async function getNextPayloadByUserInput(
|
|
|
46
47
|
const smartIntentsApi = new SmartIntentsApi(
|
|
47
48
|
cmsApi,
|
|
48
49
|
request,
|
|
49
|
-
smartIntentsConfig
|
|
50
|
+
smartIntentsConfig,
|
|
51
|
+
userTextOrTranscript
|
|
50
52
|
)
|
|
51
53
|
const smartIntentNode = await smartIntentsApi.getNodeByInput()
|
|
52
54
|
if (smartIntentNode) {
|
|
@@ -16,6 +16,7 @@ interface KeywordProps {
|
|
|
16
16
|
cmsApi: FlowBuilderApi
|
|
17
17
|
locale: string
|
|
18
18
|
request: ActionRequest
|
|
19
|
+
userTextOrTranscript: string
|
|
19
20
|
}
|
|
20
21
|
export class KeywordMatcher {
|
|
21
22
|
public cmsApi: FlowBuilderApi
|
|
@@ -25,17 +26,22 @@ export class KeywordMatcher {
|
|
|
25
26
|
public matchedKeyword?: string
|
|
26
27
|
public keywordNodeId?: string
|
|
27
28
|
public flowId?: string
|
|
29
|
+
public userTextOrTranscript: string
|
|
28
30
|
|
|
29
|
-
constructor({ cmsApi, locale, request }: KeywordProps) {
|
|
31
|
+
constructor({ cmsApi, locale, request, userTextOrTranscript }: KeywordProps) {
|
|
30
32
|
this.cmsApi = cmsApi
|
|
31
33
|
this.locale = locale
|
|
32
34
|
this.request = request
|
|
33
35
|
this.isRegExp = false
|
|
36
|
+
this.userTextOrTranscript = userTextOrTranscript
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
async getNodeByInput(
|
|
39
|
+
async getNodeByInput(): Promise<HtKeywordNode | undefined> {
|
|
37
40
|
const keywordNodes = this.cmsApi.getKeywordNodes()
|
|
38
|
-
const keywordNode = this.getNodeByKeyword(
|
|
41
|
+
const keywordNode = this.getNodeByKeyword(
|
|
42
|
+
this.userTextOrTranscript,
|
|
43
|
+
keywordNodes
|
|
44
|
+
)
|
|
39
45
|
if (!keywordNode || !this.matchedKeyword) {
|
|
40
46
|
return undefined
|
|
41
47
|
}
|
|
@@ -120,7 +126,7 @@ export class KeywordMatcher {
|
|
|
120
126
|
nluKeywordName: this.matchedKeyword as string,
|
|
121
127
|
nluKeywordIsRegex: this.isRegExp,
|
|
122
128
|
nluKeywordMessageId: this.request.input.message_id,
|
|
123
|
-
userInput: this.
|
|
129
|
+
userInput: this.userTextOrTranscript,
|
|
124
130
|
}
|
|
125
131
|
const { action, ...eventArgs } = event
|
|
126
132
|
await trackEvent(this.request, action, eventArgs)
|
|
@@ -28,11 +28,11 @@ export class SmartIntentsApi {
|
|
|
28
28
|
public cmsApi: FlowBuilderApi,
|
|
29
29
|
public currentRequest: ActionRequest,
|
|
30
30
|
public smartIntentsConfig: SmartIntentsInferenceConfig,
|
|
31
|
-
public
|
|
31
|
+
public userTextOrTranscript: string
|
|
32
32
|
) {}
|
|
33
33
|
|
|
34
34
|
async getNodeByInput(): Promise<HtSmartIntentNode | undefined> {
|
|
35
|
-
if (!this.
|
|
35
|
+
if (!this.userTextOrTranscript) {
|
|
36
36
|
return undefined
|
|
37
37
|
}
|
|
38
38
|
const smartIntentNodes = this.cmsApi.getSmartIntentNodes()
|
|
@@ -42,7 +42,7 @@ export class SmartIntentsApi {
|
|
|
42
42
|
|
|
43
43
|
const params = {
|
|
44
44
|
bot_id: this.currentRequest.session.bot.id,
|
|
45
|
-
text: this.
|
|
45
|
+
text: this.userTextOrTranscript,
|
|
46
46
|
num_smart_intents_to_use: this.smartIntentsConfig.numSmartIntentsToUse,
|
|
47
47
|
use_latest: this.resolveUseLatest(),
|
|
48
48
|
}
|
|
@@ -73,7 +73,7 @@ export class SmartIntentsApi {
|
|
|
73
73
|
nluIntentSmartTitle: response.data.smart_intent_title,
|
|
74
74
|
nluIntentSmartNumUsed: response.data.smart_intents_used.length,
|
|
75
75
|
nluIntentSmartMessageId: this.currentRequest.input.message_id,
|
|
76
|
-
userInput: this.
|
|
76
|
+
userInput: this.userTextOrTranscript,
|
|
77
77
|
flowThreadId: this.currentRequest.session.flow_thread_id as string,
|
|
78
78
|
flowId,
|
|
79
79
|
flowName,
|
package/src/utils.ts
CHANGED
|
@@ -24,8 +24,24 @@ export function resolveGetAccessToken(
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export function
|
|
28
|
-
|
|
27
|
+
export function inputHasTextOrTranscript(input: Input): boolean {
|
|
28
|
+
const isTextInput = Boolean(input.data) && input.type === INPUT.TEXT
|
|
29
|
+
const isTranscriptText =
|
|
30
|
+
Boolean(input.transcript) && input.type === INPUT.AUDIO
|
|
31
|
+
|
|
32
|
+
return isTextInput || isTranscriptText
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function getTextOrTranscript(input: Input): string | undefined {
|
|
36
|
+
if (input.type === INPUT.TEXT && input.data) {
|
|
37
|
+
return input.data
|
|
38
|
+
}
|
|
39
|
+
if (input.type === INPUT.AUDIO && input.transcript) {
|
|
40
|
+
return input.transcript
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
console.error('No text or transcript found in input', input)
|
|
44
|
+
return undefined
|
|
29
45
|
}
|
|
30
46
|
|
|
31
47
|
function isNluAllowed(
|