@botonic/plugin-flow-builder 0.25.0-alpha.8 → 0.25.0-beta.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 (107) hide show
  1. package/lib/cjs/action/index.js +4 -2
  2. package/lib/cjs/action/index.js.map +1 -1
  3. package/lib/cjs/action/knowledge-bases.js +2 -1
  4. package/lib/cjs/action/knowledge-bases.js.map +1 -1
  5. package/lib/cjs/api.d.ts +3 -1
  6. package/lib/cjs/api.js +26 -3
  7. package/lib/cjs/api.js.map +1 -1
  8. package/lib/cjs/constants.d.ts +3 -1
  9. package/lib/cjs/constants.js +4 -2
  10. package/lib/cjs/constants.js.map +1 -1
  11. package/lib/cjs/content-fields/flow-text.d.ts +4 -2
  12. package/lib/cjs/content-fields/flow-text.js +17 -10
  13. package/lib/cjs/content-fields/flow-text.js.map +1 -1
  14. package/lib/cjs/content-fields/hubtype-fields/function.d.ts +3 -1
  15. package/lib/cjs/content-fields/hubtype-fields/function.js +1 -0
  16. package/lib/cjs/content-fields/hubtype-fields/function.js.map +1 -1
  17. package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list-row.d.ts +2 -1
  18. package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list-row.js +2 -3
  19. package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list-row.js.map +1 -1
  20. package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list-section.d.ts +2 -1
  21. package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list-section.js +2 -2
  22. package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list-section.js.map +1 -1
  23. package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list.d.ts +2 -1
  24. package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list.js +2 -2
  25. package/lib/cjs/content-fields/whatsapp-button-list/flow-whatsapp-button-list.js.map +1 -1
  26. package/lib/cjs/functions/conditional-bot-variable.d.ts +8 -0
  27. package/lib/cjs/functions/conditional-bot-variable.js +11 -0
  28. package/lib/cjs/functions/conditional-bot-variable.js.map +1 -0
  29. package/lib/cjs/functions/conditional-country.d.ts +7 -0
  30. package/lib/cjs/functions/conditional-country.js +9 -0
  31. package/lib/cjs/functions/conditional-country.js.map +1 -0
  32. package/lib/cjs/functions/conditional-provider.js +1 -3
  33. package/lib/cjs/functions/conditional-provider.js.map +1 -1
  34. package/lib/cjs/functions/conditional-queue-status.d.ts +8 -2
  35. package/lib/cjs/functions/conditional-queue-status.js +14 -6
  36. package/lib/cjs/functions/conditional-queue-status.js.map +1 -1
  37. package/lib/cjs/functions/index.d.ts +4 -0
  38. package/lib/cjs/functions/index.js +4 -0
  39. package/lib/cjs/functions/index.js.map +1 -1
  40. package/lib/cjs/index.d.ts +3 -2
  41. package/lib/cjs/index.js +30 -14
  42. package/lib/cjs/index.js.map +1 -1
  43. package/lib/cjs/utils.d.ts +2 -0
  44. package/lib/cjs/utils.js +18 -1
  45. package/lib/cjs/utils.js.map +1 -1
  46. package/lib/esm/action/index.js +4 -2
  47. package/lib/esm/action/index.js.map +1 -1
  48. package/lib/esm/action/knowledge-bases.js +2 -1
  49. package/lib/esm/action/knowledge-bases.js.map +1 -1
  50. package/lib/esm/api.d.ts +3 -1
  51. package/lib/esm/api.js +27 -4
  52. package/lib/esm/api.js.map +1 -1
  53. package/lib/esm/constants.d.ts +3 -1
  54. package/lib/esm/constants.js +3 -1
  55. package/lib/esm/constants.js.map +1 -1
  56. package/lib/esm/content-fields/flow-text.d.ts +4 -2
  57. package/lib/esm/content-fields/flow-text.js +18 -11
  58. package/lib/esm/content-fields/flow-text.js.map +1 -1
  59. package/lib/esm/content-fields/hubtype-fields/function.d.ts +3 -1
  60. package/lib/esm/content-fields/hubtype-fields/function.js +1 -0
  61. package/lib/esm/content-fields/hubtype-fields/function.js.map +1 -1
  62. package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list-row.d.ts +2 -1
  63. package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list-row.js +2 -3
  64. package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list-row.js.map +1 -1
  65. package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list-section.d.ts +2 -1
  66. package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list-section.js +2 -2
  67. package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list-section.js.map +1 -1
  68. package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list.d.ts +2 -1
  69. package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list.js +2 -2
  70. package/lib/esm/content-fields/whatsapp-button-list/flow-whatsapp-button-list.js.map +1 -1
  71. package/lib/esm/functions/conditional-bot-variable.d.ts +8 -0
  72. package/lib/esm/functions/conditional-bot-variable.js +7 -0
  73. package/lib/esm/functions/conditional-bot-variable.js.map +1 -0
  74. package/lib/esm/functions/conditional-country.d.ts +7 -0
  75. package/lib/esm/functions/conditional-country.js +5 -0
  76. package/lib/esm/functions/conditional-country.js.map +1 -0
  77. package/lib/esm/functions/conditional-provider.js +1 -3
  78. package/lib/esm/functions/conditional-provider.js.map +1 -1
  79. package/lib/esm/functions/conditional-queue-status.d.ts +8 -2
  80. package/lib/esm/functions/conditional-queue-status.js +14 -6
  81. package/lib/esm/functions/conditional-queue-status.js.map +1 -1
  82. package/lib/esm/functions/index.d.ts +4 -0
  83. package/lib/esm/functions/index.js +4 -0
  84. package/lib/esm/functions/index.js.map +1 -1
  85. package/lib/esm/index.d.ts +3 -2
  86. package/lib/esm/index.js +30 -14
  87. package/lib/esm/index.js.map +1 -1
  88. package/lib/esm/utils.d.ts +2 -0
  89. package/lib/esm/utils.js +16 -0
  90. package/lib/esm/utils.js.map +1 -1
  91. package/package.json +4 -6
  92. package/src/action/index.tsx +4 -2
  93. package/src/action/knowledge-bases.ts +3 -2
  94. package/src/api.ts +35 -4
  95. package/src/constants.ts +3 -1
  96. package/src/content-fields/flow-text.tsx +23 -17
  97. package/src/content-fields/hubtype-fields/function.ts +4 -1
  98. package/src/content-fields/whatsapp-button-list/flow-whatsapp-button-list-row.tsx +4 -2
  99. package/src/content-fields/whatsapp-button-list/flow-whatsapp-button-list-section.tsx +4 -2
  100. package/src/content-fields/whatsapp-button-list/flow-whatsapp-button-list.tsx +4 -2
  101. package/src/functions/conditional-bot-variable.ts +18 -0
  102. package/src/functions/conditional-country.ts +14 -0
  103. package/src/functions/conditional-provider.ts +1 -2
  104. package/src/functions/conditional-queue-status.ts +17 -6
  105. package/src/functions/index.ts +4 -0
  106. package/src/index.ts +48 -17
  107. package/src/utils.ts +26 -0
@@ -10,6 +10,5 @@ export function conditionalProvider({
10
10
  results,
11
11
  }: ConditionalProviderArgs): string {
12
12
  const provider = request.session.user.provider
13
- if (results.includes(provider)) return provider
14
- return 'default'
13
+ return results.find(result => result === provider) || 'default'
15
14
  }
@@ -7,14 +7,24 @@ type ConditionalQueueStatusArgs = {
7
7
  request: ActionRequest
8
8
  queue_id: string
9
9
  queue_name: string
10
+ check_available_agents: boolean
11
+ }
12
+
13
+ enum QueueStatusResult {
14
+ OPEN = 'open',
15
+ CLOSED = 'closed',
16
+ OPEN_WITHOUT_AGENTS = 'open-without-agents',
10
17
  }
11
18
 
12
19
  export async function conditionalQueueStatus({
13
20
  queue_id,
14
- }: ConditionalQueueStatusArgs): Promise<string> {
15
- const data = await getQueueAvailability(queue_id)
16
- const isAvailable = data.available
17
- return isAvailable ? 'open' : 'closed'
21
+ check_available_agents,
22
+ }: ConditionalQueueStatusArgs): Promise<QueueStatusResult> {
23
+ const data = await getQueueAvailability(queue_id, check_available_agents)
24
+ if (check_available_agents && data.open && data.available_agents === 0) {
25
+ return QueueStatusResult.OPEN_WITHOUT_AGENTS
26
+ }
27
+ return data.open ? QueueStatusResult.OPEN : QueueStatusResult.CLOSED
18
28
  }
19
29
 
20
30
  interface AvailabilityData {
@@ -27,7 +37,8 @@ interface AvailabilityData {
27
37
  }
28
38
 
29
39
  export async function getQueueAvailability(
30
- queueId: string
40
+ queueId: string,
41
+ checkAvailableAgents = false
31
42
  ): Promise<AvailabilityData> {
32
43
  const response = await axios.get(
33
44
  `${HUBTYPE_API_URL}/public/v1/queues/${queueId}/availability/`,
@@ -36,7 +47,7 @@ export async function getQueueAvailability(
36
47
  params: {
37
48
  check_queue_schedule: true,
38
49
  check_waiting_cases: false,
39
- check_available_agents: false,
50
+ check_available_agents: checkAvailableAgents,
40
51
  },
41
52
  }
42
53
  )
@@ -1,3 +1,5 @@
1
+ import { conditionalBotVariable } from './conditional-bot-variable'
2
+ import { conditionalCountry } from './conditional-country'
1
3
  import { conditionalProvider } from './conditional-provider'
2
4
  import { conditionalQueueStatus } from './conditional-queue-status'
3
5
 
@@ -5,4 +7,6 @@ export const DEFAULT_FUNCTIONS = {
5
7
  // TODO: Rename api action name
6
8
  'check-queue-status': conditionalQueueStatus,
7
9
  'get-channel-type': conditionalProvider,
10
+ 'check-country': conditionalCountry,
11
+ 'check-bot-variable': conditionalBotVariable,
8
12
  }
package/src/index.ts CHANGED
@@ -15,6 +15,8 @@ import {
15
15
  } from './content-fields'
16
16
  import {
17
17
  HtFlowBuilderData,
18
+ HtFunctionArgument,
19
+ HtFunctionArguments,
18
20
  HtFunctionNode,
19
21
  HtNodeComponent,
20
22
  HtNodeWithContent,
@@ -71,9 +73,11 @@ export default class BotonicPluginFlowBuilder implements Plugin {
71
73
  !request.session.is_first_interaction
72
74
 
73
75
  if (checkUserTextInput) {
76
+ const locale = this.getLocale(request.session)
77
+ const resolvedLocale = this.cmsApi.getResolvedLocale(locale)
74
78
  const nodeByUserInput = await getNodeByUserInput(
75
79
  this.cmsApi,
76
- this.getLocale(request.session),
80
+ resolvedLocale,
77
81
  request as unknown as ActionRequest
78
82
  )
79
83
  request.input.payload = this.cmsApi.getPayload(nodeByUserInput?.target)
@@ -115,18 +119,21 @@ export default class BotonicPluginFlowBuilder implements Plugin {
115
119
  prevContents?: FlowContent[]
116
120
  ): Promise<FlowContent[]> {
117
121
  const contents = prevContents || []
118
-
119
- const content = this.getFlowContent(node, locale)
122
+ const resolvedLocale = this.cmsApi.getResolvedLocale(locale)
120
123
 
121
124
  if (node.type === HtNodeWithContentType.FUNCTION) {
122
- const targetId = await this.callFunction(node, locale)
123
- return this.getContentsById(targetId, locale, contents)
124
- } else {
125
- if (content) contents.push(content)
126
- // TODO: prevent infinite recursive calls
127
-
128
- if (node.follow_up)
129
- return this.getContentsById(node.follow_up.id, locale, contents)
125
+ const targetId = await this.callFunction(node, resolvedLocale)
126
+ return this.getContentsById(targetId, resolvedLocale, contents)
127
+ }
128
+
129
+ const content = this.getFlowContent(node, resolvedLocale)
130
+ if (content) {
131
+ contents.push(content)
132
+ }
133
+ // TODO: prevent infinite recursive calls
134
+
135
+ if (node.follow_up) {
136
+ return this.getContentsById(node.follow_up.id, resolvedLocale, contents)
130
137
  }
131
138
 
132
139
  return contents
@@ -146,7 +153,11 @@ export default class BotonicPluginFlowBuilder implements Plugin {
146
153
  case HtNodeWithContentType.VIDEO:
147
154
  return FlowVideo.fromHubtypeCMS(hubtypeContent, locale)
148
155
  case HtNodeWithContentType.WHATSAPP_BUTTON_LIST:
149
- return FlowWhatsappButtonList.fromHubtypeCMS(hubtypeContent, locale)
156
+ return FlowWhatsappButtonList.fromHubtypeCMS(
157
+ hubtypeContent,
158
+ locale,
159
+ this.cmsApi
160
+ )
150
161
  case HtNodeWithContentType.HANDOFF:
151
162
  return FlowHandoff.fromHubtypeCMS(hubtypeContent, locale, this.cmsApi)
152
163
  default:
@@ -154,15 +165,18 @@ export default class BotonicPluginFlowBuilder implements Plugin {
154
165
  }
155
166
  }
156
167
 
157
- async callFunction(
168
+ private async callFunction(
158
169
  functionNode: HtFunctionNode,
159
170
  locale: string
160
171
  ): Promise<string> {
161
172
  const functionNodeId = functionNode.id
162
- const nameValues =
163
- functionNode.content.arguments
164
- .find(arg => arg.locale === locale)
165
- ?.values.map(value => ({ [value.name]: value.value })) || []
173
+ const functionArguments = this.getArgumentsByLocale(
174
+ functionNode.content.arguments,
175
+ locale
176
+ )
177
+ const nameValues = functionArguments.map(arg => {
178
+ return { [arg.name]: arg.value }
179
+ })
166
180
 
167
181
  const args = Object.assign(
168
182
  {
@@ -185,6 +199,23 @@ export default class BotonicPluginFlowBuilder implements Plugin {
185
199
  return result.target.id
186
200
  }
187
201
 
202
+ private getArgumentsByLocale(
203
+ args: HtFunctionArguments[],
204
+ locale: string
205
+ ): HtFunctionArgument[] {
206
+ let resultArguments: HtFunctionArgument[] = []
207
+ for (const arg of args) {
208
+ if ('locale' in arg && arg.locale === locale) {
209
+ resultArguments = [...resultArguments, ...arg.values]
210
+ }
211
+ if ('type' in arg) {
212
+ resultArguments = [...resultArguments, arg]
213
+ }
214
+ }
215
+
216
+ return resultArguments
217
+ }
218
+
188
219
  getPayloadParams<T extends PayloadParamsBase>(payload: string): T {
189
220
  const payloadParams = JSON.parse(payload.split(SEPARATOR)[1] || '{}')
190
221
  return payloadParams
package/src/utils.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Session } from '@botonic/core'
2
+ import { ActionRequest } from '@botonic/react'
2
3
 
3
4
  import { BotonicPluginFlowBuilderOptions, ProcessEnvNodeEnvs } from './types'
4
5
 
@@ -21,3 +22,28 @@ export function resolveGetAccessToken(
21
22
  throw new Error('No method defined for getting access token')
22
23
  }
23
24
  }
25
+
26
+ export function getValueFromKeyPath(
27
+ request: ActionRequest,
28
+ keyPath: string
29
+ ): any {
30
+ if (keyPath.startsWith('input') || keyPath.startsWith('session')) {
31
+ return keyPath
32
+ .split('.')
33
+ .reduce((object, key) => resolveObjectKey(object, key), request)
34
+ }
35
+
36
+ return keyPath
37
+ .split('.')
38
+ .reduce(
39
+ (object, key) => resolveObjectKey(object, key),
40
+ request.session.user.extra_data
41
+ )
42
+ }
43
+
44
+ function resolveObjectKey(object: any, key: string): any {
45
+ if (object && object[key] !== undefined) {
46
+ return object[key]
47
+ }
48
+ return undefined
49
+ }