wingbot 3.34.0 → 3.36.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.
- package/package.json +2 -2
- package/src/Ai.js +45 -11
- package/src/BotApp.js +43 -11
- package/src/Processor.js +1 -1
- package/src/resolvers/utils.js +8 -2
- package/src/templates/ButtonTemplate.js +57 -0
- package/src/utils/stateData.js +11 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wingbot",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.36.0",
|
|
4
4
|
"description": "Enterprise Messaging Bot Conversation Engine",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"eslint-plugin-react": "^7.29.4",
|
|
47
47
|
"graphql-markdown": "^6.0.0",
|
|
48
48
|
"jsdoc-to-markdown": "^7.1.1",
|
|
49
|
-
"mocha": "^
|
|
49
|
+
"mocha": "^10.0.0",
|
|
50
50
|
"nyc": "^15.1.0",
|
|
51
51
|
"rimraf": "^3.0.2",
|
|
52
52
|
"sinon": "^13.0.1",
|
package/src/Ai.js
CHANGED
|
@@ -40,6 +40,8 @@ let uq = 1;
|
|
|
40
40
|
|
|
41
41
|
/** @typedef {import('./Request').IntentAction} IntentAction */
|
|
42
42
|
/** @typedef {import('./Request')} Request */
|
|
43
|
+
/** @typedef {import('./Responder')} Responder */
|
|
44
|
+
/** @typedef {import('./wingbot/CachedModel').Result} Result */
|
|
43
45
|
/** @typedef {import('./wingbot/CustomEntityDetectionModel').Phrases} Phrases */
|
|
44
46
|
|
|
45
47
|
/**
|
|
@@ -348,13 +350,13 @@ class Ai {
|
|
|
348
350
|
const rules = this.matcher.preprocessRule(intent);
|
|
349
351
|
const matcher = this._createIntentMatcher(rules, usedEntities);
|
|
350
352
|
|
|
351
|
-
return async (req) => {
|
|
353
|
+
return async (req, res) => {
|
|
352
354
|
if (!req.isTextOrIntent()) {
|
|
353
355
|
return false;
|
|
354
356
|
}
|
|
355
357
|
|
|
356
358
|
if (!req.intents) {
|
|
357
|
-
await this._loadIntents(req);
|
|
359
|
+
await this._loadIntents(req, res);
|
|
358
360
|
}
|
|
359
361
|
|
|
360
362
|
const winningIntent = matcher(req);
|
|
@@ -523,9 +525,10 @@ class Ai {
|
|
|
523
525
|
/**
|
|
524
526
|
*
|
|
525
527
|
* @param {Request} req
|
|
528
|
+
* @param {Responder} [res]
|
|
526
529
|
* @returns {Promise}
|
|
527
530
|
*/
|
|
528
|
-
async preloadAi (req) {
|
|
531
|
+
async preloadAi (req, res = null) {
|
|
529
532
|
if (req.supportsFeature(req.FEATURE_PHRASES)) {
|
|
530
533
|
const model = this._getModelForRequest(req, false);
|
|
531
534
|
|
|
@@ -534,7 +537,7 @@ class Ai {
|
|
|
534
537
|
.catch(() => {});
|
|
535
538
|
}
|
|
536
539
|
}
|
|
537
|
-
return this._preloadIntent(req);
|
|
540
|
+
return this._preloadIntent(req, res);
|
|
538
541
|
}
|
|
539
542
|
|
|
540
543
|
/**
|
|
@@ -552,12 +555,43 @@ class Ai {
|
|
|
552
555
|
return CustomEntityDetectionModel.getEmptyPhrasesObject();
|
|
553
556
|
}
|
|
554
557
|
|
|
555
|
-
|
|
558
|
+
/**
|
|
559
|
+
*
|
|
560
|
+
* @param {Request} req
|
|
561
|
+
* @param {Responder} res
|
|
562
|
+
* @param {Result} result
|
|
563
|
+
* @returns {void}
|
|
564
|
+
*/
|
|
565
|
+
_setResultToReqRes (req, res, result) {
|
|
566
|
+
const { text = null, intents, entities = [] } = result;
|
|
567
|
+
Object.assign(req, { intents, entities, _anonymizedText: text });
|
|
568
|
+
|
|
569
|
+
if (!res) {
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
const entitiesObj = (entities || []).reduce((o, { entity, value }) => {
|
|
574
|
+
const list = o[entity] || [];
|
|
575
|
+
list.push(value);
|
|
576
|
+
return Object.assign(o, { [entity]: list });
|
|
577
|
+
}, {});
|
|
578
|
+
|
|
579
|
+
res.setData({
|
|
580
|
+
'@': entitiesObj
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
*
|
|
586
|
+
* @param {Request} req
|
|
587
|
+
* @param {Responder} [res]
|
|
588
|
+
* @returns {Promise}
|
|
589
|
+
*/
|
|
590
|
+
async _preloadIntent (req, res = null) {
|
|
556
591
|
const mockIntent = this._getMockIntent(req);
|
|
557
592
|
|
|
558
593
|
if (mockIntent) {
|
|
559
|
-
req
|
|
560
|
-
req.entities = mockIntent.entities;
|
|
594
|
+
this._setResultToReqRes(req, res, mockIntent);
|
|
561
595
|
return;
|
|
562
596
|
}
|
|
563
597
|
|
|
@@ -571,15 +605,15 @@ class Ai {
|
|
|
571
605
|
req.intents = [];
|
|
572
606
|
return;
|
|
573
607
|
}
|
|
574
|
-
await this._loadIntents(req, model);
|
|
608
|
+
await this._loadIntents(req, res, model);
|
|
575
609
|
} else {
|
|
576
610
|
req.intents = [];
|
|
577
611
|
}
|
|
578
612
|
}
|
|
579
613
|
|
|
580
|
-
async _loadIntents (req, model = null) {
|
|
581
|
-
const
|
|
582
|
-
|
|
614
|
+
async _loadIntents (req, res = null, model = null) {
|
|
615
|
+
const result = await this._queryModel(req, model);
|
|
616
|
+
this._setResultToReqRes(req, res, result);
|
|
583
617
|
}
|
|
584
618
|
|
|
585
619
|
async _queryModel (req, useModel = null) {
|
package/src/BotApp.js
CHANGED
|
@@ -46,6 +46,15 @@ const DEFAULT_API_URL = 'https://orchestrator-api.wingbot.ai';
|
|
|
46
46
|
* @prop {object} headers
|
|
47
47
|
*/
|
|
48
48
|
|
|
49
|
+
function defaultMsg (senderId, pageId) {
|
|
50
|
+
return {
|
|
51
|
+
sender: { id: senderId },
|
|
52
|
+
recipient: { id: pageId },
|
|
53
|
+
mid: null,
|
|
54
|
+
timestamp: Date.now()
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
49
58
|
/**
|
|
50
59
|
* Adapter for Wingbot flight director
|
|
51
60
|
*
|
|
@@ -239,32 +248,55 @@ class BotApp {
|
|
|
239
248
|
};
|
|
240
249
|
}
|
|
241
250
|
|
|
251
|
+
const sender = await this.createSender(senderId, pageId, message, secret, appId);
|
|
252
|
+
const res = await this._processor.processMessage(message, pageId, sender, { appId });
|
|
253
|
+
await this._processSenderResponses(sender, senderId, pageId, headers);
|
|
254
|
+
|
|
255
|
+
return {
|
|
256
|
+
status: res.status,
|
|
257
|
+
response_to_mid: message.mid,
|
|
258
|
+
messaging: []
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Creates a Sender to be able, for example, to upload files
|
|
264
|
+
*
|
|
265
|
+
* @param {string} senderId
|
|
266
|
+
* @param {string} pageId
|
|
267
|
+
* @param {object} [message]
|
|
268
|
+
* @param {string|Promise<string>} [secret]
|
|
269
|
+
* @param {string} appId
|
|
270
|
+
* @returns {Promise<BotAppSender>}
|
|
271
|
+
*/
|
|
272
|
+
async createSender (
|
|
273
|
+
senderId,
|
|
274
|
+
pageId,
|
|
275
|
+
message = defaultMsg(senderId, pageId),
|
|
276
|
+
secret = this._secret,
|
|
277
|
+
appId = this._appId
|
|
278
|
+
) {
|
|
279
|
+
const useSecret = await Promise.resolve(secret);
|
|
280
|
+
|
|
281
|
+
const setResponseToMid = message.response_to_mid || message.mid;
|
|
282
|
+
|
|
242
283
|
const options = {
|
|
243
284
|
...this._returnSenderOptions,
|
|
244
285
|
apiUrl: this._apiUrl,
|
|
245
286
|
pageId,
|
|
246
287
|
appId,
|
|
247
|
-
secret,
|
|
288
|
+
secret: useSecret,
|
|
248
289
|
mid: setResponseToMid,
|
|
249
290
|
fetch: this._fetch,
|
|
250
291
|
tls: this._tls
|
|
251
292
|
};
|
|
252
293
|
|
|
253
|
-
|
|
254
|
-
const res = await this._processor.processMessage(message, pageId, sender, { appId });
|
|
255
|
-
await this._processSenderResponses(sender, senderId, pageId, headers);
|
|
256
|
-
|
|
257
|
-
return {
|
|
258
|
-
status: res.status,
|
|
259
|
-
response_to_mid: message.mid,
|
|
260
|
-
messaging: []
|
|
261
|
-
};
|
|
294
|
+
return new BotAppSender(options, senderId, message, this._senderLogger);
|
|
262
295
|
}
|
|
263
296
|
|
|
264
297
|
/**
|
|
265
298
|
* Compatibility method for Notification engine
|
|
266
299
|
*
|
|
267
|
-
* @deprecated
|
|
268
300
|
* @param {object} message - wingbot chat event
|
|
269
301
|
* @param {string} senderId - chat event sender identifier
|
|
270
302
|
* @param {string} pageId - channel/page identifier
|
package/src/Processor.js
CHANGED
package/src/resolvers/utils.js
CHANGED
|
@@ -14,6 +14,7 @@ const TYPE_SHARE = 'element_share';
|
|
|
14
14
|
const TYPE_URL = 'web_url';
|
|
15
15
|
const TYPE_URL_WITH_EXT = 'web_url_extension';
|
|
16
16
|
const TYPE_POSTBACK = 'postback';
|
|
17
|
+
const TYPE_ATTACHMENT = 'attachment';
|
|
17
18
|
|
|
18
19
|
const WEBVIEW_FULL = 'full';
|
|
19
20
|
const WEBVIEW_TALL = 'tall';
|
|
@@ -227,10 +228,11 @@ function processButtons (
|
|
|
227
228
|
editableCondition,
|
|
228
229
|
setState
|
|
229
230
|
}) => {
|
|
231
|
+
|
|
230
232
|
if (hasCondition) {
|
|
231
233
|
const condition = getCondition({
|
|
232
234
|
hasCondition, conditionFn, hasEditableCondition, editableCondition
|
|
233
|
-
}, context, '
|
|
235
|
+
}, context, 'Button condition');
|
|
234
236
|
|
|
235
237
|
if (!condition(req, res)) {
|
|
236
238
|
return;
|
|
@@ -244,7 +246,8 @@ function processButtons (
|
|
|
244
246
|
url,
|
|
245
247
|
webviewHeight = WEBVIEW_TALL,
|
|
246
248
|
targetRouteId,
|
|
247
|
-
action
|
|
249
|
+
action,
|
|
250
|
+
payload
|
|
248
251
|
} = btnAction;
|
|
249
252
|
|
|
250
253
|
const isExtUrl = type === TYPE_URL_WITH_EXT;
|
|
@@ -273,6 +276,9 @@ function processButtons (
|
|
|
273
276
|
case TYPE_SHARE:
|
|
274
277
|
elem.shareButton(btnTitleText);
|
|
275
278
|
break;
|
|
279
|
+
case TYPE_ATTACHMENT:
|
|
280
|
+
elem.attachmentButton(btnTitleText, payload);
|
|
281
|
+
break;
|
|
276
282
|
default:
|
|
277
283
|
}
|
|
278
284
|
});
|
|
@@ -6,6 +6,38 @@
|
|
|
6
6
|
const BaseTemplate = require('./BaseTemplate');
|
|
7
7
|
const { makeAbsolute } = require('../utils');
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* @typedef MarkdownPayload
|
|
11
|
+
* @prop {"text/markdown"} contentType
|
|
12
|
+
* @prop {string} content
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Designer payload type
|
|
17
|
+
*
|
|
18
|
+
* @typedef {MarkdownPayload} Payload
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @typedef EncodedPayload
|
|
23
|
+
* @prop {string} content
|
|
24
|
+
* @prop {"text/markdown"} content_type
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Encodes different types of payloads from designer snapshot to payload for chat
|
|
29
|
+
* Content is Base64 encoded.
|
|
30
|
+
*
|
|
31
|
+
* @param {Payload} payload
|
|
32
|
+
* @returns {EncodedPayload}
|
|
33
|
+
*/
|
|
34
|
+
function encodePayload ({ content, contentType }) {
|
|
35
|
+
return {
|
|
36
|
+
content: Buffer.from(content).toString('base64'),
|
|
37
|
+
content_type: contentType
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
9
41
|
/**
|
|
10
42
|
* Helps with creating of button template
|
|
11
43
|
* Instance of button template is returned by {Responder}
|
|
@@ -92,6 +124,31 @@ class ButtonTemplate extends BaseTemplate {
|
|
|
92
124
|
return this;
|
|
93
125
|
}
|
|
94
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Adds button, which opens a popup with content on click.
|
|
129
|
+
*
|
|
130
|
+
* @param {string} title
|
|
131
|
+
* @param {Payload} payload
|
|
132
|
+
* @returns {this}
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* res.button('text')
|
|
136
|
+
* .attachmentButton('button title', {
|
|
137
|
+
* content: '# Heading 1',
|
|
138
|
+
* contentType: 'text/markdown'
|
|
139
|
+
* })
|
|
140
|
+
* .send();
|
|
141
|
+
*
|
|
142
|
+
*/
|
|
143
|
+
attachmentButton (title, payload) {
|
|
144
|
+
this.buttons.push({
|
|
145
|
+
type: 'attachment',
|
|
146
|
+
title: this._t(title),
|
|
147
|
+
payload: encodePayload(payload)
|
|
148
|
+
});
|
|
149
|
+
return this;
|
|
150
|
+
}
|
|
151
|
+
|
|
95
152
|
/**
|
|
96
153
|
*
|
|
97
154
|
* @returns {this}
|
package/src/utils/stateData.js
CHANGED
|
@@ -3,8 +3,19 @@
|
|
|
3
3
|
*/
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
|
+
/** @typedef {import('../Request')} Request */
|
|
7
|
+
/** @typedef {import('../Responder')} Responder */
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @param {Request} req
|
|
12
|
+
* @param {Responder} res
|
|
13
|
+
* @param {object} configuration
|
|
14
|
+
* @returns {object}
|
|
15
|
+
*/
|
|
6
16
|
module.exports = function stateData (req, res = null, configuration = null) {
|
|
7
17
|
const c = configuration || req.configuration;
|
|
18
|
+
|
|
8
19
|
return {
|
|
9
20
|
...req.state,
|
|
10
21
|
...(res ? res.newState : {}),
|