@botonic/plugin-flow-builder 0.21.0-alpha.4 → 0.21.0-alpha.6
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.d.ts +3 -5
- package/lib/cjs/action.js +23 -16
- package/lib/cjs/action.js.map +1 -1
- package/lib/cjs/content-fields/content-fields-base.d.ts +7 -0
- package/lib/cjs/content-fields/{content-base.js → content-fields-base.js} +7 -2
- package/lib/cjs/content-fields/content-fields-base.js.map +1 -0
- package/lib/cjs/content-fields/{button.d.ts → flow-button.d.ts} +3 -3
- package/lib/cjs/content-fields/{button.js → flow-button.js} +5 -5
- package/lib/cjs/content-fields/flow-button.js.map +1 -0
- package/lib/cjs/content-fields/flow-carousel.d.ts +10 -0
- package/lib/cjs/content-fields/{carousel.js → flow-carousel.js} +10 -10
- package/lib/cjs/content-fields/flow-carousel.js.map +1 -0
- package/lib/cjs/content-fields/flow-element.d.ts +11 -0
- package/lib/cjs/content-fields/{element.js → flow-element.js} +6 -7
- package/lib/cjs/content-fields/flow-element.js.map +1 -0
- package/lib/cjs/content-fields/flow-image.d.ts +9 -0
- package/lib/cjs/content-fields/{image.js → flow-image.js} +4 -5
- package/lib/cjs/content-fields/flow-image.js.map +1 -0
- package/lib/cjs/content-fields/flow-text.d.ts +12 -0
- package/lib/cjs/content-fields/{text.js → flow-text.js} +8 -8
- package/lib/cjs/content-fields/flow-text.js.map +1 -0
- package/lib/cjs/content-fields/index.d.ts +7 -0
- package/lib/cjs/content-fields/index.js +16 -0
- package/lib/cjs/content-fields/index.js.map +1 -0
- package/lib/cjs/content-fields/types.d.ts +4 -0
- package/lib/cjs/content-fields/types.js +3 -0
- package/lib/cjs/content-fields/types.js.map +1 -0
- package/lib/cjs/flow-builder-models.d.ts +174 -0
- package/lib/cjs/flow-builder-models.js +22 -0
- package/lib/cjs/flow-builder-models.js.map +1 -0
- package/lib/cjs/functions/conditional-queue-status.d.ts +2 -2
- package/lib/cjs/functions/conditional-queue-status.js +15 -2
- package/lib/cjs/functions/conditional-queue-status.js.map +1 -1
- package/lib/cjs/functions/index.d.ts +1 -1
- package/lib/cjs/functions/index.js +3 -1
- package/lib/cjs/functions/index.js.map +1 -1
- package/lib/cjs/handoff.d.ts +1 -1
- package/lib/cjs/handoff.js +11 -15
- package/lib/cjs/handoff.js.map +1 -1
- package/lib/cjs/index.d.ts +19 -14
- package/lib/cjs/index.js +40 -24
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/utils.d.ts +1 -2
- package/lib/cjs/utils.js +6 -6
- package/lib/cjs/utils.js.map +1 -1
- package/lib/esm/action.d.ts +3 -5
- package/lib/esm/action.js +22 -15
- package/lib/esm/action.js.map +1 -1
- package/lib/esm/content-fields/content-fields-base.d.ts +7 -0
- package/lib/esm/content-fields/content-fields-base.js +16 -0
- package/lib/esm/content-fields/content-fields-base.js.map +1 -0
- package/lib/esm/content-fields/{button.d.ts → flow-button.d.ts} +3 -3
- package/lib/esm/content-fields/{button.js → flow-button.js} +4 -4
- package/lib/esm/content-fields/flow-button.js.map +1 -0
- package/lib/esm/content-fields/flow-carousel.d.ts +10 -0
- package/lib/esm/content-fields/{carousel.js → flow-carousel.js} +9 -9
- package/lib/esm/content-fields/flow-carousel.js.map +1 -0
- package/lib/esm/content-fields/flow-element.d.ts +11 -0
- package/lib/esm/content-fields/{element.js → flow-element.js} +4 -5
- package/lib/esm/content-fields/flow-element.js.map +1 -0
- package/lib/esm/content-fields/flow-image.d.ts +9 -0
- package/lib/esm/content-fields/{image.js → flow-image.js} +3 -4
- package/lib/esm/content-fields/flow-image.js.map +1 -0
- package/lib/esm/content-fields/flow-text.d.ts +12 -0
- package/lib/esm/content-fields/{text.js → flow-text.js} +4 -4
- package/lib/esm/content-fields/flow-text.js.map +1 -0
- package/lib/esm/content-fields/index.d.ts +7 -0
- package/lib/esm/content-fields/index.js +7 -0
- package/lib/esm/content-fields/index.js.map +1 -0
- package/lib/esm/content-fields/types.d.ts +4 -0
- package/lib/esm/content-fields/types.js +2 -0
- package/lib/esm/content-fields/types.js.map +1 -0
- package/lib/esm/flow-builder-models.d.ts +174 -0
- package/lib/esm/flow-builder-models.js +19 -0
- package/lib/esm/flow-builder-models.js.map +1 -0
- package/lib/esm/functions/conditional-queue-status.d.ts +2 -2
- package/lib/esm/functions/conditional-queue-status.js +15 -2
- package/lib/esm/functions/conditional-queue-status.js.map +1 -1
- package/lib/esm/functions/index.d.ts +1 -1
- package/lib/esm/functions/index.js +3 -1
- package/lib/esm/functions/index.js.map +1 -1
- package/lib/esm/handoff.d.ts +1 -1
- package/lib/esm/handoff.js +12 -16
- package/lib/esm/handoff.js.map +1 -1
- package/lib/esm/index.d.ts +19 -14
- package/lib/esm/index.js +35 -21
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/utils.d.ts +1 -2
- package/lib/esm/utils.js +4 -4
- package/lib/esm/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/action.tsx +26 -20
- package/src/content-fields/content-fields-base.ts +15 -0
- package/src/content-fields/{button.tsx → flow-button.tsx} +5 -5
- package/src/content-fields/flow-carousel.tsx +39 -0
- package/src/content-fields/{element.tsx → flow-element.tsx} +8 -6
- package/src/content-fields/{image.tsx → flow-image.tsx} +5 -6
- package/src/content-fields/{text.tsx → flow-text.tsx} +5 -5
- package/src/content-fields/index.ts +7 -0
- package/src/content-fields/types.ts +5 -0
- package/src/flow-builder-models.ts +220 -0
- package/src/functions/conditional-queue-status.ts +24 -2
- package/src/functions/index.ts +3 -1
- package/src/handoff.ts +18 -17
- package/src/index.ts +75 -50
- package/src/utils.ts +10 -5
- package/lib/cjs/content-fields/button.js.map +0 -1
- package/lib/cjs/content-fields/carousel.d.ts +0 -10
- package/lib/cjs/content-fields/carousel.js.map +0 -1
- package/lib/cjs/content-fields/content-base.d.ts +0 -10
- package/lib/cjs/content-fields/content-base.js.map +0 -1
- package/lib/cjs/content-fields/element.d.ts +0 -11
- package/lib/cjs/content-fields/element.js.map +0 -1
- package/lib/cjs/content-fields/image.d.ts +0 -9
- package/lib/cjs/content-fields/image.js.map +0 -1
- package/lib/cjs/content-fields/text.d.ts +0 -12
- package/lib/cjs/content-fields/text.js.map +0 -1
- package/lib/cjs/hubtype-models.d.ts +0 -152
- package/lib/cjs/hubtype-models.js +0 -50
- package/lib/cjs/hubtype-models.js.map +0 -1
- package/lib/esm/content-fields/button.js.map +0 -1
- package/lib/esm/content-fields/carousel.d.ts +0 -10
- package/lib/esm/content-fields/carousel.js.map +0 -1
- package/lib/esm/content-fields/content-base.d.ts +0 -10
- package/lib/esm/content-fields/content-base.js +0 -11
- package/lib/esm/content-fields/content-base.js.map +0 -1
- package/lib/esm/content-fields/element.d.ts +0 -11
- package/lib/esm/content-fields/element.js.map +0 -1
- package/lib/esm/content-fields/image.d.ts +0 -9
- package/lib/esm/content-fields/image.js.map +0 -1
- package/lib/esm/content-fields/text.d.ts +0 -12
- package/lib/esm/content-fields/text.js.map +0 -1
- package/lib/esm/hubtype-models.d.ts +0 -152
- package/lib/esm/hubtype-models.js +0 -47
- package/lib/esm/hubtype-models.js.map +0 -1
- package/src/content-fields/carousel.tsx +0 -39
- package/src/content-fields/content-base.ts +0 -15
- package/src/hubtype-models.ts +0 -190
package/lib/esm/utils.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export declare function getImageByLocale(locale: string, image: HtMediaFileLocale[]): string;
|
|
1
|
+
export declare function getWebpackEnvVar(webpackEnvVar: string | false, name: string, defaultValue: string): string;
|
package/lib/esm/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export function
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
export function getWebpackEnvVar(webpackEnvVar, name, defaultValue) {
|
|
2
|
+
return (webpackEnvVar ||
|
|
3
|
+
(typeof process !== 'undefined' && process.env[name]) ||
|
|
4
|
+
defaultValue);
|
|
5
5
|
}
|
|
6
6
|
//# sourceMappingURL=utils.js.map
|
package/lib/esm/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB,CAC9B,aAA6B,EAC7B,IAAY,EACZ,YAAoB;IAEpB,OAAO,CACL,aAAa;QACb,CAAC,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrD,YAAY,CACb,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
package/src/action.tsx
CHANGED
|
@@ -1,57 +1,63 @@
|
|
|
1
1
|
import { ActionRequest, RequestContext, Text } from '@botonic/react'
|
|
2
2
|
import React from 'react'
|
|
3
3
|
|
|
4
|
-
import { FlowContent } from './content-fields
|
|
4
|
+
import { FlowContent } from './content-fields'
|
|
5
5
|
import { doHandoff } from './handoff'
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
// TODO: remove this from here and use the new "start" attribute in the flow
|
|
9
|
-
export const START = '08c7df06-0c7c-4f06-b8c1-4157582efeb2'
|
|
6
|
+
import BotonicPluginFlowBuilder from './index'
|
|
10
7
|
|
|
11
8
|
type FlowBuilderActionProps = {
|
|
12
9
|
content?: FlowContent[]
|
|
13
|
-
|
|
10
|
+
isHandoff?: boolean
|
|
14
11
|
}
|
|
15
12
|
|
|
16
|
-
export
|
|
13
|
+
export class FlowBuilderAction extends React.Component<FlowBuilderActionProps> {
|
|
17
14
|
static contextType = RequestContext
|
|
18
15
|
|
|
19
16
|
static async botonicInit(request: ActionRequest): Promise<any> {
|
|
20
|
-
const flowBuilderPlugin = request.plugins
|
|
17
|
+
const flowBuilderPlugin = request.plugins
|
|
18
|
+
.hubtypeFlowBuilder as BotonicPluginFlowBuilder
|
|
19
|
+
const locale = flowBuilderPlugin.getLocale(request.session)
|
|
20
|
+
let payload = request.input.payload
|
|
21
|
+
? request.input.payload
|
|
22
|
+
: await flowBuilderPlugin.getStartId()
|
|
21
23
|
|
|
22
|
-
let payload = request.input.payload ? request.input.payload : START
|
|
23
24
|
if (!request.input.payload) {
|
|
24
25
|
const intentPayload = await flowBuilderPlugin.getPayloadByInput(
|
|
25
26
|
request.input,
|
|
26
|
-
|
|
27
|
+
locale
|
|
27
28
|
)
|
|
28
29
|
if (intentPayload) {
|
|
29
30
|
payload = intentPayload
|
|
30
31
|
}
|
|
31
32
|
const keywordPayload = await flowBuilderPlugin.getPayloadByKeyword(
|
|
32
33
|
request.input,
|
|
33
|
-
|
|
34
|
+
locale
|
|
34
35
|
)
|
|
35
36
|
if (keywordPayload) {
|
|
36
37
|
payload = keywordPayload
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
// We use only Spanish because they are the backend examples
|
|
40
|
-
const content = await flowBuilderPlugin.getContents(payload,
|
|
41
|
+
const content = await flowBuilderPlugin.getContents(payload, locale)
|
|
41
42
|
|
|
42
|
-
if (content.length
|
|
43
|
-
const
|
|
44
|
-
|
|
43
|
+
if (content.length === 0) {
|
|
44
|
+
const handoffParams = {
|
|
45
|
+
queue: 'Test', // TODO: Take it from the flow
|
|
46
|
+
agentEmail: 'test@gmail.com',
|
|
47
|
+
note: 'This is a note that will be attached to the case as a reminder',
|
|
48
|
+
}
|
|
49
|
+
await doHandoff(request, handoffParams.queue, handoffParams.note)
|
|
50
|
+
const isHandoff = true
|
|
51
|
+
return { isHandoff }
|
|
45
52
|
}
|
|
46
53
|
return { content }
|
|
47
54
|
}
|
|
48
55
|
|
|
49
|
-
render() {
|
|
56
|
+
render(): JSX.Element | JSX.Element[] {
|
|
50
57
|
// @ts-ignore
|
|
51
|
-
const { content: contents,
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
return <Text>{handoffMsg}</Text>
|
|
58
|
+
const { content: contents, isHandoff } = this.props
|
|
59
|
+
if (isHandoff) {
|
|
60
|
+
return <Text>You are being transferred to an agent!</Text>
|
|
55
61
|
} else {
|
|
56
62
|
return contents!.map((content, index) => content.toBotonic(index))
|
|
57
63
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { MediaFileLocale, TextLocale } from '../flow-builder-models'
|
|
2
|
+
|
|
3
|
+
export abstract class ContentFieldsBase {
|
|
4
|
+
constructor(private readonly id: string) {}
|
|
5
|
+
|
|
6
|
+
static getTextByLocale(locale: string, text: TextLocale[]): string {
|
|
7
|
+
const result = text.find(t => t.locale === locale)
|
|
8
|
+
return result?.message ?? ''
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static getImageByLocale(locale: string, image: MediaFileLocale[]): string {
|
|
12
|
+
const result = image.find(t => t.locale === locale)
|
|
13
|
+
return result?.file ?? ''
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { Button, Reply } from '@botonic/react'
|
|
2
2
|
import React from 'react'
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import { ContentFieldsBase } from './content-base'
|
|
4
|
+
import { Button as FbButton, ButtonStyle } from '../flow-builder-models'
|
|
5
|
+
import { ContentFieldsBase } from './content-fields-base'
|
|
6
6
|
|
|
7
7
|
export class FlowButton extends ContentFieldsBase {
|
|
8
8
|
public text = ''
|
|
9
9
|
public url?: string
|
|
10
10
|
public payload?: string
|
|
11
11
|
|
|
12
|
-
static fromHubtypeCMS(component:
|
|
12
|
+
static fromHubtypeCMS(component: FbButton, locale: string): FlowButton {
|
|
13
13
|
const newButton = new FlowButton(component.id)
|
|
14
14
|
newButton.text = FlowButton.getTextByLocale(locale, component.text)
|
|
15
15
|
newButton.payload = component.target?.id
|
|
16
16
|
return newButton
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
renderButton(index: number, buttonStyle: ButtonStyle) {
|
|
20
|
-
if (buttonStyle
|
|
19
|
+
renderButton(index: number, buttonStyle: ButtonStyle): JSX.Element {
|
|
20
|
+
if (buttonStyle === ButtonStyle.QUICK_REPLY) {
|
|
21
21
|
return (
|
|
22
22
|
<Reply payload={this.payload} key={index}>
|
|
23
23
|
{this.text}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Button, Carousel, Element, Pic, Subtitle, Title } from '@botonic/react'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
import { CarouselNode } from '../flow-builder-models'
|
|
5
|
+
import { ContentFieldsBase } from './content-fields-base'
|
|
6
|
+
import { FlowElement } from './flow-element'
|
|
7
|
+
|
|
8
|
+
export class FlowCarousel extends ContentFieldsBase {
|
|
9
|
+
public code = ''
|
|
10
|
+
public elements: FlowElement[] = []
|
|
11
|
+
|
|
12
|
+
static fromHubtypeCMS(component: CarouselNode, locale: string): FlowCarousel {
|
|
13
|
+
const newCarousel = new FlowCarousel(component.id)
|
|
14
|
+
newCarousel.code = component.code
|
|
15
|
+
newCarousel.elements = component.content.elements.map(element =>
|
|
16
|
+
FlowElement.fromHubtypeCMS(element, locale)
|
|
17
|
+
)
|
|
18
|
+
return newCarousel
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
toBotonic(index: number): JSX.Element {
|
|
22
|
+
return (
|
|
23
|
+
<Carousel key={index}>
|
|
24
|
+
{this.elements.map((element, eIndex) => (
|
|
25
|
+
<Element key={eIndex}>
|
|
26
|
+
<Pic src={element.image} />
|
|
27
|
+
<Title style=''>{element.title}</Title>
|
|
28
|
+
<Subtitle style=''>{element.subtitle}</Subtitle>
|
|
29
|
+
{/* @ts-ignore */}
|
|
30
|
+
<Button payload={element.buttons?.payload}>
|
|
31
|
+
{element.buttons?.text}
|
|
32
|
+
</Button>
|
|
33
|
+
,
|
|
34
|
+
</Element>
|
|
35
|
+
))}
|
|
36
|
+
</Carousel>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { FlowButton } from './button'
|
|
4
|
-
import { ContentFieldsBase } from './content-base'
|
|
1
|
+
import { CarouselElementNode } from '../flow-builder-models'
|
|
2
|
+
import { ContentFieldsBase } from './content-fields-base'
|
|
3
|
+
import { FlowButton } from './flow-button'
|
|
5
4
|
|
|
6
5
|
export class FlowElement extends ContentFieldsBase {
|
|
7
6
|
public title = ''
|
|
@@ -10,14 +9,17 @@ export class FlowElement extends ContentFieldsBase {
|
|
|
10
9
|
public image = ''
|
|
11
10
|
public hidden = false
|
|
12
11
|
|
|
13
|
-
static fromHubtypeCMS(
|
|
12
|
+
static fromHubtypeCMS(
|
|
13
|
+
component: CarouselElementNode,
|
|
14
|
+
locale: string
|
|
15
|
+
): FlowElement {
|
|
14
16
|
const newElement = new FlowElement(component.id)
|
|
15
17
|
newElement.title = FlowElement.getTextByLocale(locale, component.title)
|
|
16
18
|
newElement.subtitle = FlowElement.getTextByLocale(
|
|
17
19
|
locale,
|
|
18
20
|
component.subtitle
|
|
19
21
|
)
|
|
20
|
-
newElement.image = getImageByLocale(locale, component.image)
|
|
22
|
+
newElement.image = FlowElement.getImageByLocale(locale, component.image)
|
|
21
23
|
newElement.buttons = FlowButton.fromHubtypeCMS(component.button, locale)
|
|
22
24
|
return newElement
|
|
23
25
|
}
|
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
import { Image } from '@botonic/react'
|
|
2
2
|
import React from 'react'
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { ContentFieldsBase } from './content-base'
|
|
4
|
+
import { ImageNode } from '../flow-builder-models'
|
|
5
|
+
import { ContentFieldsBase } from './content-fields-base'
|
|
7
6
|
|
|
8
7
|
export class FlowImage extends ContentFieldsBase {
|
|
9
8
|
public src = ''
|
|
10
9
|
public code = ''
|
|
11
10
|
|
|
12
|
-
static fromHubtypeCMS(component:
|
|
11
|
+
static fromHubtypeCMS(component: ImageNode, locale: string): FlowImage {
|
|
13
12
|
const newImage = new FlowImage(component.id)
|
|
14
13
|
newImage.code = component.code
|
|
15
|
-
newImage.src = getImageByLocale(locale, component.content.image)
|
|
14
|
+
newImage.src = this.getImageByLocale(locale, component.content.image)
|
|
16
15
|
return newImage
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
toBotonic(index: number) {
|
|
18
|
+
toBotonic(index: number): JSX.Element {
|
|
20
19
|
return <Image src={this.src} key={index} />
|
|
21
20
|
}
|
|
22
21
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Text } from '@botonic/react'
|
|
2
2
|
import React from 'react'
|
|
3
3
|
|
|
4
|
-
import { ButtonStyle,
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { ButtonStyle, TextNode } from '../flow-builder-models'
|
|
5
|
+
import { ContentFieldsBase } from './content-fields-base'
|
|
6
|
+
import { FlowButton } from './flow-button'
|
|
7
7
|
|
|
8
8
|
export class FlowText extends ContentFieldsBase {
|
|
9
9
|
public text = ''
|
|
@@ -11,7 +11,7 @@ export class FlowText extends ContentFieldsBase {
|
|
|
11
11
|
public buttons: FlowButton[] = []
|
|
12
12
|
public buttonStyle = ButtonStyle.BUTTON
|
|
13
13
|
|
|
14
|
-
static fromHubtypeCMS(component:
|
|
14
|
+
static fromHubtypeCMS(component: TextNode, locale: string): FlowText {
|
|
15
15
|
const newText = new FlowText(component.id)
|
|
16
16
|
newText.code = component.code
|
|
17
17
|
newText.buttonStyle = component.content.buttons_style || ButtonStyle.BUTTON
|
|
@@ -22,7 +22,7 @@ export class FlowText extends ContentFieldsBase {
|
|
|
22
22
|
return newText
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
toBotonic(index: number) {
|
|
25
|
+
toBotonic(index: number): JSX.Element {
|
|
26
26
|
return (
|
|
27
27
|
<Text key={index}>
|
|
28
28
|
{this.text}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { ContentFieldsBase } from './content-fields-base'
|
|
2
|
+
export { FlowButton } from './flow-button'
|
|
3
|
+
export { FlowCarousel } from './flow-carousel'
|
|
4
|
+
export { FlowElement } from './flow-element'
|
|
5
|
+
export { FlowImage } from './flow-image'
|
|
6
|
+
export { FlowText } from './flow-text'
|
|
7
|
+
export type { FlowContent } from './types'
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
export interface FlowBuilderData {
|
|
2
|
+
version: string
|
|
3
|
+
name: string
|
|
4
|
+
locales: string[]
|
|
5
|
+
start_node_id?: string
|
|
6
|
+
ai_model_id?: string
|
|
7
|
+
nodes: NodeComponent[]
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export enum NodeType {
|
|
11
|
+
TEXT = 'text',
|
|
12
|
+
IMAGE = 'image',
|
|
13
|
+
CAROUSEL = 'carousel',
|
|
14
|
+
HANDOFF = 'handoff',
|
|
15
|
+
KEYWORD = 'keyword',
|
|
16
|
+
INTENT = 'intent',
|
|
17
|
+
START_UP = 'start-up',
|
|
18
|
+
URL = 'url',
|
|
19
|
+
PAYLOAD = 'payload',
|
|
20
|
+
FUNCTION = 'function',
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface BaseNode {
|
|
24
|
+
id: string
|
|
25
|
+
type: NodeType
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface Meta {
|
|
29
|
+
x: number
|
|
30
|
+
y: number
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface Node extends BaseNode {
|
|
34
|
+
code: string
|
|
35
|
+
meta: Meta
|
|
36
|
+
follow_up?: NodeLink
|
|
37
|
+
target?: NodeLink
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface NodeLink {
|
|
41
|
+
id: string
|
|
42
|
+
type: NodeType
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface TextLocale {
|
|
46
|
+
message: string
|
|
47
|
+
locale: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export enum ButtonStyle {
|
|
51
|
+
BUTTON = 'button',
|
|
52
|
+
QUICK_REPLY = 'quick-reply',
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface UrlLocale {
|
|
56
|
+
id: string
|
|
57
|
+
locale: string
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface PayloadLocale {
|
|
61
|
+
id: string
|
|
62
|
+
locale: string
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface Button {
|
|
66
|
+
id: string
|
|
67
|
+
text: TextLocale[]
|
|
68
|
+
target?: NodeLink
|
|
69
|
+
hidden: string
|
|
70
|
+
url?: UrlLocale
|
|
71
|
+
payload?: PayloadLocale
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface TextNodeContent {
|
|
75
|
+
text: TextLocale[]
|
|
76
|
+
buttons_style?: ButtonStyle
|
|
77
|
+
buttons: Button[]
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface TextNode extends Node {
|
|
81
|
+
type: NodeType.TEXT
|
|
82
|
+
content: TextNodeContent
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface MediaFileLocale {
|
|
86
|
+
id: string
|
|
87
|
+
file: string
|
|
88
|
+
locale: string
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface ImageNodeContent {
|
|
92
|
+
image: MediaFileLocale[]
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface ImageNode extends Node {
|
|
96
|
+
type: NodeType.IMAGE
|
|
97
|
+
content: ImageNodeContent
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface CarouselElementNode {
|
|
101
|
+
id: string
|
|
102
|
+
title: TextLocale[]
|
|
103
|
+
subtitle: TextLocale[]
|
|
104
|
+
image: MediaFileLocale[]
|
|
105
|
+
button: Button
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface CarouselNodeContent {
|
|
109
|
+
elements: CarouselElementNode[]
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface CarouselNode extends Node {
|
|
113
|
+
type: NodeType.CAROUSEL
|
|
114
|
+
content: CarouselNodeContent
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface QueueLocale {
|
|
118
|
+
id: string
|
|
119
|
+
name: string
|
|
120
|
+
locale: string
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export interface HandoffNodeContent {
|
|
124
|
+
message: TextLocale[]
|
|
125
|
+
fail_message: TextLocale[]
|
|
126
|
+
queue: QueueLocale[]
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface HandoffNode extends Node {
|
|
130
|
+
type: NodeType.HANDOFF
|
|
131
|
+
content: HandoffNodeContent
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface InputLocale {
|
|
135
|
+
values: string[]
|
|
136
|
+
locale: string
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface KeywordNodeContent {
|
|
140
|
+
title: TextLocale[]
|
|
141
|
+
keywords: InputLocale[]
|
|
142
|
+
}
|
|
143
|
+
export interface KeywordNode extends Node {
|
|
144
|
+
type: NodeType.KEYWORD
|
|
145
|
+
content: KeywordNodeContent
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export interface IntentNodeContent {
|
|
149
|
+
title: TextLocale[]
|
|
150
|
+
intents: InputLocale[]
|
|
151
|
+
confidence: number
|
|
152
|
+
}
|
|
153
|
+
export interface IntentNode extends Node {
|
|
154
|
+
type: NodeType.INTENT
|
|
155
|
+
content: IntentNodeContent
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export interface StartNode extends BaseNode {
|
|
159
|
+
type: NodeType.START_UP
|
|
160
|
+
target: NodeLink
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export interface UrlNodeContent {
|
|
164
|
+
url: string
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export interface UrlNode extends BaseNode {
|
|
168
|
+
type: NodeType.URL
|
|
169
|
+
content: UrlNodeContent
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export interface PayloadNodeContent {
|
|
173
|
+
payload: string
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export interface PayloadNode extends BaseNode {
|
|
177
|
+
type: NodeType.PAYLOAD
|
|
178
|
+
content: PayloadNodeContent
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export type ArgumentType = number | string | Record<any, any>
|
|
182
|
+
|
|
183
|
+
export interface FunctionNodeArgument {
|
|
184
|
+
type: ArgumentType
|
|
185
|
+
name: string
|
|
186
|
+
value: string
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export interface FunctionNodeArgumentLocale {
|
|
190
|
+
locale: string
|
|
191
|
+
values: FunctionNodeArgument[]
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export interface FunctionNodeResult {
|
|
195
|
+
result: string
|
|
196
|
+
target: NodeLink
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export interface FunctionNodeContent {
|
|
200
|
+
action: string
|
|
201
|
+
arguments: FunctionNodeArgumentLocale[]
|
|
202
|
+
result_mapping: FunctionNodeResult[]
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export interface FunctionNode extends Node {
|
|
206
|
+
type: NodeType.FUNCTION
|
|
207
|
+
content: FunctionNodeContent
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export type NodeComponent =
|
|
211
|
+
| TextNode
|
|
212
|
+
| ImageNode
|
|
213
|
+
| CarouselNode
|
|
214
|
+
| HandoffNode
|
|
215
|
+
| KeywordNode
|
|
216
|
+
| IntentNode
|
|
217
|
+
| UrlNode
|
|
218
|
+
| StartNode
|
|
219
|
+
| PayloadNode
|
|
220
|
+
| FunctionNode
|
|
@@ -1,8 +1,30 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
1
2
|
import axios from 'axios'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
import { getWebpackEnvVar } from '../utils'
|
|
5
|
+
|
|
6
|
+
const _HUBTYPE_API_URL_ = getWebpackEnvVar(
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
typeof HUBTYPE_API_URL !== 'undefined' && HUBTYPE_API_URL,
|
|
9
|
+
'HUBTYPE_API_URL',
|
|
10
|
+
'https://api.hubtype.com'
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
export async function conditionalQueueStatus({
|
|
14
|
+
queue_id,
|
|
15
|
+
}: {
|
|
16
|
+
queue_id: string
|
|
17
|
+
}): Promise<string> {
|
|
4
18
|
const response = await axios.get(
|
|
5
|
-
|
|
19
|
+
`${_HUBTYPE_API_URL_}/v1/queues/${queue_id}/availability/`,
|
|
20
|
+
// TODO: Make it configurable in the future
|
|
21
|
+
{
|
|
22
|
+
params: {
|
|
23
|
+
check_queue_schedule: true,
|
|
24
|
+
check_waiting_cases: false,
|
|
25
|
+
check_available_agents: false,
|
|
26
|
+
},
|
|
27
|
+
}
|
|
6
28
|
)
|
|
7
29
|
const isAvailable = response.data.available
|
|
8
30
|
return isAvailable ? 'open' : 'closed'
|
package/src/functions/index.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { conditionalProvider } from './conditional-provider'
|
|
|
2
2
|
import { conditionalQueueStatus } from './conditional-queue-status'
|
|
3
3
|
|
|
4
4
|
export const DEFAULT_FUNCTIONS = {
|
|
5
|
-
|
|
5
|
+
// TODO: Rename api action name
|
|
6
|
+
// 'conditional-queue-status': conditionalQueueStatus,
|
|
7
|
+
'check-queue-status': conditionalQueueStatus,
|
|
6
8
|
'conditional-provider': conditionalProvider,
|
|
7
9
|
}
|
package/src/handoff.ts
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HandOffBuilder } from '@botonic/core'
|
|
2
2
|
import { ActionRequest } from '@botonic/react'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
export async function doHandoff(
|
|
5
|
+
request: ActionRequest,
|
|
6
|
+
queue: string,
|
|
7
|
+
note?: string,
|
|
8
|
+
agentEmail?: string
|
|
9
|
+
): Promise<void> {
|
|
9
10
|
// @ts-ignore
|
|
10
11
|
const flowBuilderPlugin = request.plugins.hubtypeFlowBuilder as any
|
|
11
12
|
const handoffContent = await flowBuilderPlugin.getHandoffContent()
|
|
12
|
-
|
|
13
|
+
|
|
13
14
|
// @ts-ignore
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (openQueues.queues.indexOf(queueName) !== -1) {
|
|
17
|
-
// @ts-ignore
|
|
18
|
-
const handOffBuilder = new HandOffBuilder(request.session)
|
|
19
|
-
handOffBuilder.withQueue('Test')
|
|
20
|
-
handOffBuilder.withOnFinishPayload(handoffContent.target?.id!)
|
|
21
|
-
await handOffBuilder.handOff()
|
|
15
|
+
const handOffBuilder = new HandOffBuilder(request.session)
|
|
16
|
+
handOffBuilder.withQueue(queue)
|
|
22
17
|
|
|
23
|
-
|
|
18
|
+
if (note) {
|
|
19
|
+
handOffBuilder.withNote(note)
|
|
24
20
|
}
|
|
25
21
|
|
|
26
|
-
|
|
22
|
+
if (agentEmail) {
|
|
23
|
+
handOffBuilder.withAgentEmail(agentEmail)
|
|
24
|
+
}
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
26
|
+
handOffBuilder.withOnFinishPayload(handoffContent.target?.id!)
|
|
27
|
+
await handOffBuilder.handOff()
|
|
27
28
|
}
|