@telia-ace/conversational-hub-bot-provider 0.0.2 → 0.0.4
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/.eslintrc.json +23 -0
- package/README.md +7 -0
- package/package.json +1 -1
- package/project.json +57 -0
- package/src/declaration.d.ts +2 -0
- package/src/emotion.d.ts +7 -0
- package/src/plugin.ts +198 -0
- package/src/types.ts +20 -0
- package/tsconfig.json +21 -0
- package/tsconfig.lib.json +23 -0
- package/tsconfig.spec.json +19 -0
- package/vite.config.ts +53 -0
- package/index.js +0 -1095
- package/index.mjs +0 -9944
- package/plugin.d.ts +0 -6
- package/types.d.ts +0 -18
- /package/{index.d.ts → src/index.ts} +0 -0
package/.eslintrc.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": ["plugin:@nx/react", "../../../.eslintrc.json"],
|
|
3
|
+
"ignorePatterns": ["!**/*"],
|
|
4
|
+
"overrides": [
|
|
5
|
+
{
|
|
6
|
+
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
|
7
|
+
"rules": {}
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"files": ["*.ts", "*.tsx"],
|
|
11
|
+
"rules": {
|
|
12
|
+
"@typescript-eslint/ban-types": "off",
|
|
13
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
14
|
+
"@typescript-eslint/no-unused-vars": "off",
|
|
15
|
+
"@typescript-eslint/no-empty-function": "off"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"files": ["*.js", "*.jsx"],
|
|
20
|
+
"rules": {}
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
package/README.md
ADDED
package/package.json
CHANGED
package/project.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@telia-ace/conversational-hub-bot-provider",
|
|
3
|
+
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
+
"sourceRoot": "libs/conversational-hub/bot-provider/src",
|
|
5
|
+
"projectType": "library",
|
|
6
|
+
"tags": [],
|
|
7
|
+
"targets": {
|
|
8
|
+
"lint": {
|
|
9
|
+
"executor": "@nx/linter:eslint",
|
|
10
|
+
"outputs": ["{options.outputFile}"],
|
|
11
|
+
"options": {
|
|
12
|
+
"lintFilePatterns": [
|
|
13
|
+
"libs/conversational-hub/bot-provider/**/*.{ts,tsx,js,jsx}",
|
|
14
|
+
"libs/conversational-hub/bot-provider/package.json"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"build": {
|
|
19
|
+
"executor": "@nx/vite:build",
|
|
20
|
+
"outputs": ["{options.outputPath}"],
|
|
21
|
+
"defaultConfiguration": "production",
|
|
22
|
+
"options": {
|
|
23
|
+
"outputPath": "dist/libs/conversational-hub/bot-provider"
|
|
24
|
+
},
|
|
25
|
+
"configurations": {
|
|
26
|
+
"development": {
|
|
27
|
+
"mode": "development"
|
|
28
|
+
},
|
|
29
|
+
"production": {
|
|
30
|
+
"mode": "production"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"publish": {
|
|
35
|
+
"executor": "nx:run-commands",
|
|
36
|
+
"options": {
|
|
37
|
+
"command": "npm publish",
|
|
38
|
+
"cwd": "dist/libs/conversational-hub/bot-provider"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"prerelease": {
|
|
42
|
+
"executor": "nx:run-commands",
|
|
43
|
+
"options": {
|
|
44
|
+
"command": "npm publish --tag=rc",
|
|
45
|
+
"cwd": "dist/libs/conversational-hub/bot-provider"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"test": {
|
|
49
|
+
"executor": "@nx/vite:test",
|
|
50
|
+
"outputs": ["{options.reportsDirectory}"],
|
|
51
|
+
"options": {
|
|
52
|
+
"passWithNoTests": true,
|
|
53
|
+
"reportsDirectory": "../../../coverage/libs/conversational-hub/bot-provider"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
package/src/emotion.d.ts
ADDED
package/src/plugin.ts
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ConversationPlatform,
|
|
3
|
+
ConversationProvider,
|
|
4
|
+
Agent,
|
|
5
|
+
} from '@telia-ace/widget-conversation';
|
|
6
|
+
import { Container, Widget } from '@webprovisions/platform';
|
|
7
|
+
import { AgentResponse, AgentPrompt, Action } from './types';
|
|
8
|
+
import { Logger } from '@telia-ace/widget-utilities';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Plugin for communicating with Webconnector API in Conversational Hub.
|
|
12
|
+
*/
|
|
13
|
+
export const ConversationalHubPlugin = async (container: Container) => {
|
|
14
|
+
const widget: Widget = container.get('$widget');
|
|
15
|
+
|
|
16
|
+
// Get extension from widget configuration.
|
|
17
|
+
const settings =
|
|
18
|
+
widget?.container?.get('$settings')?.components?.conversation?.properties
|
|
19
|
+
?.conversationalHubPluginSettings;
|
|
20
|
+
|
|
21
|
+
// Get Conversation Platform from widget.
|
|
22
|
+
const conversationPlatform = await ConversationPlatform.getInstance(
|
|
23
|
+
container
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
let conversation: ConversationProvider;
|
|
27
|
+
let agent: Agent;
|
|
28
|
+
let connectionAttempts = settings?.connectionAttempts
|
|
29
|
+
? settings.connectionAttempts
|
|
30
|
+
: 5;
|
|
31
|
+
|
|
32
|
+
// Register a provider for plugin.
|
|
33
|
+
conversationPlatform.registerProvider(
|
|
34
|
+
'chub-plugin',
|
|
35
|
+
(conversationProvider, component) => {
|
|
36
|
+
conversation = conversationProvider;
|
|
37
|
+
|
|
38
|
+
// Create an agent.
|
|
39
|
+
agent = conversation.createAgent({
|
|
40
|
+
name: settings?.botName,
|
|
41
|
+
avatar: settings?.avatar,
|
|
42
|
+
}) as Agent;
|
|
43
|
+
|
|
44
|
+
initialize();
|
|
45
|
+
|
|
46
|
+
// Watch for actions (button click).
|
|
47
|
+
component.actions.watch('conversation.action', (action, next) => {
|
|
48
|
+
sendAction(action);
|
|
49
|
+
return next(action);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Watch for user input.
|
|
53
|
+
component.actions.watch('conversation.user-submit', (input, next) => {
|
|
54
|
+
sendInput(input.text);
|
|
55
|
+
return next(input);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Initialize session with Conversational Hub.
|
|
62
|
+
*/
|
|
63
|
+
async function initialize(print = true) {
|
|
64
|
+
await fetchFromApi(
|
|
65
|
+
settings.baseUrl + '/initialize',
|
|
66
|
+
`{"extension": "${settings.extension}"}`,
|
|
67
|
+
print
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Send action to Webconnector API.
|
|
73
|
+
* @param action - User interaction.
|
|
74
|
+
*/
|
|
75
|
+
async function sendAction(action: Action) {
|
|
76
|
+
await fetchFromApi(
|
|
77
|
+
`${settings.baseUrl}/input/${settings.sessionId}`,
|
|
78
|
+
`{"type":"button_click","language":"${settings.language}","content":{"button_text":"${action.label}","value":"${action.actionKey}"}}`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Send user text message to Webconnector API.
|
|
84
|
+
* @param text - Text message.
|
|
85
|
+
*/
|
|
86
|
+
async function sendInput(text: string) {
|
|
87
|
+
await fetchFromApi(
|
|
88
|
+
`${settings.baseUrl}/input/${settings.sessionId}`,
|
|
89
|
+
`{"type":"text","language":"${settings.language}","content":{"text":"${text}"}}`
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Fetch data from endpoint in Webconnector API.
|
|
95
|
+
* @param url - API endpoint.
|
|
96
|
+
* @param body - Request payload.
|
|
97
|
+
*/
|
|
98
|
+
async function fetchFromApi(url: string, body: string, print = true) {
|
|
99
|
+
// Activate loader animation.
|
|
100
|
+
const loader = conversation.loading();
|
|
101
|
+
|
|
102
|
+
let response;
|
|
103
|
+
let result;
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
response = await fetch(url, {
|
|
107
|
+
method: 'POST',
|
|
108
|
+
body: body,
|
|
109
|
+
});
|
|
110
|
+
result = await response?.json();
|
|
111
|
+
} catch (error) {
|
|
112
|
+
if (error instanceof SyntaxError) {
|
|
113
|
+
Logger.error('Incorrect JSON format.', error);
|
|
114
|
+
} else {
|
|
115
|
+
Logger.error('Network error: check connection or baseUrl.', error);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
loader();
|
|
119
|
+
agent.print(settings.errorMessage);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (!response?.ok) {
|
|
124
|
+
Logger.error(`HTTP ${response?.status}.`, JSON.stringify(result));
|
|
125
|
+
|
|
126
|
+
loader();
|
|
127
|
+
|
|
128
|
+
// Check if the session has expired.
|
|
129
|
+
const sessionExpired = !!result?.errors?.filter(
|
|
130
|
+
(error: any) => error.code === '1003'
|
|
131
|
+
).length;
|
|
132
|
+
|
|
133
|
+
// Initialize again and fetch data depening on payload content.
|
|
134
|
+
if (sessionExpired && connectionAttempts > 0) {
|
|
135
|
+
connectionAttempts--;
|
|
136
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
137
|
+
await initialize(false);
|
|
138
|
+
|
|
139
|
+
const payload = JSON.parse(body);
|
|
140
|
+
if (payload?.content?.text) {
|
|
141
|
+
await sendInput(payload.content.text);
|
|
142
|
+
} else if (payload?.content?.action) {
|
|
143
|
+
await sendAction(payload?.content?.action);
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
agent.print(settings.errorMessage);
|
|
147
|
+
}
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Remove loader animation.
|
|
152
|
+
loader();
|
|
153
|
+
|
|
154
|
+
connectionAttempts = 5;
|
|
155
|
+
settings.sessionId = result?.session_id;
|
|
156
|
+
|
|
157
|
+
if (print) {
|
|
158
|
+
printResult(result);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Print text results and prompts.
|
|
164
|
+
* @param result - Data to print.
|
|
165
|
+
*/
|
|
166
|
+
function printResult(result: any) {
|
|
167
|
+
// Print every message in result.
|
|
168
|
+
result?.agent_response.forEach((response: AgentResponse) => {
|
|
169
|
+
agent.print(response.payload.text);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Print every prompt in result.
|
|
173
|
+
if (result?.prompt?.items) {
|
|
174
|
+
agent.print([
|
|
175
|
+
'button-list',
|
|
176
|
+
{
|
|
177
|
+
actions: result.prompt.items.map((prompt: AgentPrompt) => {
|
|
178
|
+
let result;
|
|
179
|
+
if (prompt.type === 'button')
|
|
180
|
+
result = { actionKey: prompt.value, label: prompt.text };
|
|
181
|
+
if (prompt.type === 'link')
|
|
182
|
+
result = {
|
|
183
|
+
actionKey: prompt.value,
|
|
184
|
+
label: prompt.text,
|
|
185
|
+
data: {
|
|
186
|
+
href: prompt.url,
|
|
187
|
+
target: settings?.linkTarget ? settings.linkTarget : '_blank',
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
return result;
|
|
191
|
+
}),
|
|
192
|
+
},
|
|
193
|
+
]);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
export default ConversationalHubPlugin;
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type AgentResponse = {
|
|
2
|
+
language: string;
|
|
3
|
+
type: string;
|
|
4
|
+
payload: {
|
|
5
|
+
text: string;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type AgentPrompt = {
|
|
10
|
+
value: string;
|
|
11
|
+
text: string;
|
|
12
|
+
url?: string;
|
|
13
|
+
type: 'button' | 'link';
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type Action = {
|
|
17
|
+
actionKey: string;
|
|
18
|
+
label: string;
|
|
19
|
+
url?: string;
|
|
20
|
+
};
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"jsx": "react-jsx",
|
|
4
|
+
"allowJs": false,
|
|
5
|
+
"esModuleInterop": false,
|
|
6
|
+
"allowSyntheticDefaultImports": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"types": ["vite/client", "vitest"]
|
|
9
|
+
},
|
|
10
|
+
"files": [],
|
|
11
|
+
"include": [],
|
|
12
|
+
"references": [
|
|
13
|
+
{
|
|
14
|
+
"path": "./tsconfig.lib.json"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"path": "./tsconfig.spec.json"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"extends": "../../../tsconfig.base.json"
|
|
21
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "../../../dist/out-tsc",
|
|
5
|
+
"types": [
|
|
6
|
+
"node",
|
|
7
|
+
"@nx/react/typings/cssmodule.d.ts",
|
|
8
|
+
"@nx/react/typings/image.d.ts",
|
|
9
|
+
"vite/client"
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
"exclude": [
|
|
13
|
+
"**/*.spec.ts",
|
|
14
|
+
"**/*.test.ts",
|
|
15
|
+
"**/*.spec.tsx",
|
|
16
|
+
"**/*.test.tsx",
|
|
17
|
+
"**/*.spec.js",
|
|
18
|
+
"**/*.test.js",
|
|
19
|
+
"**/*.spec.jsx",
|
|
20
|
+
"**/*.test.jsx"
|
|
21
|
+
],
|
|
22
|
+
"include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]
|
|
23
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "../../dist/out-tsc",
|
|
5
|
+
"types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"]
|
|
6
|
+
},
|
|
7
|
+
"include": [
|
|
8
|
+
"vite.config.ts",
|
|
9
|
+
"src/**/*.test.ts",
|
|
10
|
+
"src/**/*.spec.ts",
|
|
11
|
+
"src/**/*.test.tsx",
|
|
12
|
+
"src/**/*.spec.tsx",
|
|
13
|
+
"src/**/*.test.js",
|
|
14
|
+
"src/**/*.spec.js",
|
|
15
|
+
"src/**/*.test.jsx",
|
|
16
|
+
"src/**/*.spec.jsx",
|
|
17
|
+
"src/**/*.d.ts"
|
|
18
|
+
]
|
|
19
|
+
}
|
package/vite.config.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/// <reference types="vitest" />
|
|
2
|
+
import { defineConfig } from 'vite';
|
|
3
|
+
import react from '@vitejs/plugin-react-swc';
|
|
4
|
+
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
|
|
5
|
+
import dts from 'vite-plugin-dts';
|
|
6
|
+
import * as path from 'path';
|
|
7
|
+
|
|
8
|
+
export default defineConfig({
|
|
9
|
+
cacheDir:
|
|
10
|
+
'../../../node_modules/.vite/@telia-ace/conversational-hub-bot-provider',
|
|
11
|
+
|
|
12
|
+
plugins: [
|
|
13
|
+
dts({
|
|
14
|
+
entryRoot: 'src',
|
|
15
|
+
tsConfigFilePath: path.join(__dirname, 'tsconfig.lib.json'),
|
|
16
|
+
skipDiagnostics: true,
|
|
17
|
+
}),
|
|
18
|
+
react(),
|
|
19
|
+
nxViteTsPaths(),
|
|
20
|
+
],
|
|
21
|
+
|
|
22
|
+
// Uncomment this if you are using workers.
|
|
23
|
+
// worker: {
|
|
24
|
+
// plugins: [ nxViteTsPaths() ],
|
|
25
|
+
// },
|
|
26
|
+
|
|
27
|
+
// Configuration for building your library.
|
|
28
|
+
// See: https://vitejs.dev/guide/build.html#library-mode
|
|
29
|
+
build: {
|
|
30
|
+
lib: {
|
|
31
|
+
// Could also be a dictionary or array of multiple entry points.
|
|
32
|
+
entry: 'src/index.ts',
|
|
33
|
+
name: '@telia-ace/conversational-hub-bot-provider',
|
|
34
|
+
fileName: 'index',
|
|
35
|
+
// Change this to the formats you want to support.
|
|
36
|
+
// Don't forget to update your package.json as well.
|
|
37
|
+
formats: ['es', 'cjs'],
|
|
38
|
+
},
|
|
39
|
+
rollupOptions: {
|
|
40
|
+
// External packages that should not be bundled into your library.
|
|
41
|
+
external: ['react', 'react-dom', 'react/jsx-runtime'],
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
test: {
|
|
46
|
+
globals: true,
|
|
47
|
+
cache: {
|
|
48
|
+
dir: '../../../node_modules/.vitest',
|
|
49
|
+
},
|
|
50
|
+
environment: 'jsdom',
|
|
51
|
+
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
52
|
+
},
|
|
53
|
+
});
|