botium-core 1.12.2 → 1.12.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/dist/botium-cjs.js +103 -41
- package/dist/botium-cjs.js.map +1 -1
- package/dist/botium-es.js +103 -41
- package/dist/botium-es.js.map +1 -1
- package/package.json +12 -12
- package/src/BotDriver.js +3 -3
- package/src/Capabilities.js +5 -0
- package/src/Defaults.js +0 -1
- package/src/containers/plugins/SimpleRestContainer.js +75 -27
- package/test/connectors/simplerest.spec.js +64 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "botium-core",
|
|
3
|
-
"version": "1.12.
|
|
3
|
+
"version": "1.12.3",
|
|
4
4
|
"description": "The Selenium for Chatbots",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "dist/botium-es.js",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"homepage": "https://www.botium.ai",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@babel/runtime": "^7.
|
|
35
|
+
"@babel/runtime": "^7.17.2",
|
|
36
36
|
"async": "^3.2.3",
|
|
37
37
|
"body-parser": "^1.19.1",
|
|
38
38
|
"boolean": "^3.1.4",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"esprima": "^4.0.1",
|
|
43
43
|
"express": "^4.17.2",
|
|
44
44
|
"globby": "11.0.4",
|
|
45
|
-
"ioredis": "^4.28.
|
|
45
|
+
"ioredis": "^4.28.5",
|
|
46
46
|
"is-class": "^0.0.9",
|
|
47
47
|
"is-json": "^2.0.1",
|
|
48
48
|
"jsonpath": "^1.1.1",
|
|
@@ -65,21 +65,21 @@
|
|
|
65
65
|
"swagger-jsdoc": "^6.1.0",
|
|
66
66
|
"swagger-ui-express": "^4.3.0",
|
|
67
67
|
"uuid": "^8.3.2",
|
|
68
|
-
"vm2": "^3.9.
|
|
68
|
+
"vm2": "^3.9.7",
|
|
69
69
|
"write-yaml": "^1.0.0",
|
|
70
|
-
"xlsx": "^0.
|
|
70
|
+
"xlsx": "^0.18.2",
|
|
71
71
|
"xregexp": "^5.1.0",
|
|
72
72
|
"yaml": "^1.10.2"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@babel/core": "^7.
|
|
75
|
+
"@babel/core": "^7.17.2",
|
|
76
76
|
"@babel/node": "^7.16.8",
|
|
77
|
-
"@babel/plugin-transform-runtime": "^7.
|
|
77
|
+
"@babel/plugin-transform-runtime": "^7.17.0",
|
|
78
78
|
"@babel/preset-env": "^7.16.11",
|
|
79
|
-
"chai": "^4.3.
|
|
79
|
+
"chai": "^4.3.6",
|
|
80
80
|
"chai-as-promised": "^7.1.1",
|
|
81
81
|
"cross-env": "^7.0.3",
|
|
82
|
-
"eslint": "^8.
|
|
82
|
+
"eslint": "^8.9.0",
|
|
83
83
|
"eslint-config-standard": "^16.0.3",
|
|
84
84
|
"eslint-plugin-import": "^2.25.4",
|
|
85
85
|
"eslint-plugin-node": "^11.1.0",
|
|
@@ -88,10 +88,10 @@
|
|
|
88
88
|
"license-checker": "^25.0.1",
|
|
89
89
|
"license-compatibility-checker": "^0.3.5",
|
|
90
90
|
"mocha": "^9.2.0",
|
|
91
|
-
"nock": "^13.2.
|
|
92
|
-
"npm-check-updates": "^12.
|
|
91
|
+
"nock": "^13.2.4",
|
|
92
|
+
"npm-check-updates": "^12.3.0",
|
|
93
93
|
"nyc": "^15.1.0",
|
|
94
|
-
"rollup": "^2.
|
|
94
|
+
"rollup": "^2.67.2",
|
|
95
95
|
"rollup-plugin-babel": "^4.4.0",
|
|
96
96
|
"rollup-plugin-commonjs": "^10.1.0",
|
|
97
97
|
"rollup-plugin-json": "^4.0.0",
|
package/src/BotDriver.js
CHANGED
|
@@ -109,9 +109,9 @@ module.exports = class BotDriver {
|
|
|
109
109
|
|
|
110
110
|
Build () {
|
|
111
111
|
debug(`Build - Botium Core Version: ${version}`)
|
|
112
|
-
debug(`Build - Capabilites: ${
|
|
113
|
-
debug(`Build - Sources
|
|
114
|
-
debug(`Build - Envs
|
|
112
|
+
debug(`Build - Capabilites: ${JSON.stringify(_.pickBy(this.caps, (value, key) => Defaults.Capabilities[key] !== value), null, 2)}`)
|
|
113
|
+
debug(`Build - Sources: ${JSON.stringify(_.pickBy(this.sources, (value, key) => Defaults.Sources[key] !== value), null, 2)}`)
|
|
114
|
+
debug(`Build - Envs: ${JSON.stringify(_.pickBy(this.envs, (value, key) => Defaults.Envs[key] !== value), null, 2)}`)
|
|
115
115
|
this.eventEmitter.emit(Events.CONTAINER_BUILDING)
|
|
116
116
|
|
|
117
117
|
return new Promise((resolve, reject) => {
|
package/src/Capabilities.js
CHANGED
|
@@ -73,6 +73,11 @@ module.exports = {
|
|
|
73
73
|
SIMPLEREST_RESPONSE_HOOK: 'SIMPLEREST_RESPONSE_HOOK',
|
|
74
74
|
SIMPLEREST_MEDIA_JSONPATH: 'SIMPLEREST_MEDIA_JSONPATH',
|
|
75
75
|
SIMPLEREST_BUTTONS_JSONPATH: 'SIMPLEREST_BUTTONS_JSONPATH',
|
|
76
|
+
SIMPLEREST_CARDS_JSONPATH: 'SIMPLEREST_CARDS_JSONPATH',
|
|
77
|
+
SIMPLEREST_CARD_TEXT_JSONPATH: 'SIMPLEREST_CARD_TEXT_JSONPATH',
|
|
78
|
+
SIMPLEREST_CARD_SUBTEXT_JSONPATH: 'SIMPLEREST_CARD_SUBTEXT_JSONPATH',
|
|
79
|
+
SIMPLEREST_CARD_BUTTONS_JSONPATH: 'SIMPLEREST_CARD_BUTTONS_JSONPATH',
|
|
80
|
+
SIMPLEREST_CARD_ATTACHMENTS_JSONPATH: 'SIMPLEREST_CARD_ATTACHMENTS_JSONPATH',
|
|
76
81
|
SIMPLEREST_CONTEXT_JSONPATH: 'SIMPLEREST_CONTEXT_JSONPATH',
|
|
77
82
|
SIMPLEREST_CONTEXT_MERGE_OR_REPLACE: 'SIMPLEREST_CONTEXT_MERGE_OR_REPLACE',
|
|
78
83
|
SIMPLEREST_CONVERSATION_ID_TEMPLATE: 'SIMPLEREST_CONVERSATION_ID_TEMPLATE',
|
package/src/Defaults.js
CHANGED
|
@@ -31,7 +31,6 @@ module.exports = {
|
|
|
31
31
|
[Capabilities.SIMPLEREST_METHOD]: 'GET',
|
|
32
32
|
[Capabilities.SIMPLEREST_IGNORE_EMPTY]: true,
|
|
33
33
|
[Capabilities.SIMPLEREST_TIMEOUT]: 10000,
|
|
34
|
-
[Capabilities.SIMPLEREST_EXTRA_OPTIONS]: {},
|
|
35
34
|
[Capabilities.SIMPLEREST_STRICT_SSL]: true,
|
|
36
35
|
[Capabilities.SIMPLEREST_INBOUND_UPDATE_CONTEXT]: true,
|
|
37
36
|
[Capabilities.SIMPLEREST_CONTEXT_MERGE_OR_REPLACE]: 'MERGE',
|
|
@@ -309,34 +309,82 @@ module.exports = class SimpleRestContainer {
|
|
|
309
309
|
}
|
|
310
310
|
|
|
311
311
|
for (const jsonPathRoot of jsonPathRoots) {
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
312
|
+
const _retrieveMedia = (jsonPathMediaRoot, jsonPathsMedia) => {
|
|
313
|
+
const retrievedMedia = []
|
|
314
|
+
jsonPathsMedia.forEach(jsonPath => {
|
|
315
|
+
const responseMedia = jp.query(jsonPathMediaRoot, jsonPath)
|
|
316
|
+
if (responseMedia) {
|
|
317
|
+
(_.isArray(responseMedia) ? _.flattenDeep(responseMedia) : [responseMedia]).forEach(m =>
|
|
318
|
+
retrievedMedia.push({
|
|
319
|
+
mediaUri: m,
|
|
320
|
+
mimeType: mime.lookup(m) || 'application/unknown'
|
|
321
|
+
})
|
|
322
|
+
)
|
|
323
|
+
}
|
|
324
|
+
})
|
|
325
|
+
return retrievedMedia
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const _retrieveButtons = (jsonPathButtonRoot, jsonPathsButtons) => {
|
|
329
|
+
const retrievedButtons = []
|
|
330
|
+
jsonPathsButtons.forEach(jsonPath => {
|
|
331
|
+
const responseButtons = jp.query(jsonPathButtonRoot, jsonPath)
|
|
332
|
+
if (responseButtons) {
|
|
333
|
+
(_.isArray(responseButtons) ? _.flattenDeep(responseButtons) : [responseButtons]).forEach(b =>
|
|
334
|
+
retrievedButtons.push({
|
|
335
|
+
text: b
|
|
336
|
+
})
|
|
337
|
+
)
|
|
338
|
+
}
|
|
339
|
+
})
|
|
340
|
+
return retrievedButtons
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const _getCardText = (responseCardText) => {
|
|
344
|
+
if (responseCardText) {
|
|
345
|
+
const texts = _.isArray(responseCardText) ? _.flattenDeep(responseCardText) : [responseCardText]
|
|
346
|
+
if (texts.length > 1) {
|
|
347
|
+
debug(`more than one text found for card: ${util.inspect(texts)}`)
|
|
348
|
+
}
|
|
349
|
+
if (texts.length > 0) {
|
|
350
|
+
return texts[0]
|
|
351
|
+
}
|
|
326
352
|
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const media = _retrieveMedia(jsonPathRoot, getAllCapValues(Capabilities.SIMPLEREST_MEDIA_JSONPATH, this.caps))
|
|
356
|
+
debug(`found response media: ${util.inspect(media)}`)
|
|
357
|
+
const buttons = _retrieveButtons(jsonPathRoot, getAllCapValues(Capabilities.SIMPLEREST_BUTTONS_JSONPATH, this.caps))
|
|
358
|
+
debug(`found response buttons: ${util.inspect(buttons)}`)
|
|
359
|
+
const cards = []
|
|
360
|
+
|
|
361
|
+
const jsonPathsCards = getAllCapValues(Capabilities.SIMPLEREST_CARDS_JSONPATH, this.caps)
|
|
362
|
+
jsonPathsCards.forEach(jsonPath => {
|
|
363
|
+
const responseCards = jp.query(jsonPathRoot, jsonPath)
|
|
364
|
+
if (responseCards) {
|
|
365
|
+
(_.isArray(responseCards) ? _.flattenDeep(responseCards) : [responseCards]).forEach(c => {
|
|
366
|
+
const card = {}
|
|
367
|
+
|
|
368
|
+
const jsonPathsCardText = getAllCapValues(Capabilities.SIMPLEREST_CARD_TEXT_JSONPATH, this.caps)
|
|
369
|
+
jsonPathsCardText.forEach(jsonPath => {
|
|
370
|
+
card.text = _getCardText(jp.query(c, jsonPath))
|
|
371
|
+
})
|
|
372
|
+
|
|
373
|
+
const jsonPathsCardSubText = getAllCapValues(Capabilities.SIMPLEREST_CARD_SUBTEXT_JSONPATH, this.caps)
|
|
374
|
+
jsonPathsCardSubText.forEach(jsonPath => {
|
|
375
|
+
card.subtext = _getCardText(jp.query(c, jsonPath))
|
|
335
376
|
})
|
|
336
|
-
|
|
337
|
-
|
|
377
|
+
|
|
378
|
+
card.buttons = _retrieveButtons(c, getAllCapValues(Capabilities.SIMPLEREST_CARD_BUTTONS_JSONPATH, this.caps))
|
|
379
|
+
card.media = _retrieveMedia(c, getAllCapValues(Capabilities.SIMPLEREST_CARD_ATTACHMENTS_JSONPATH, this.caps))
|
|
380
|
+
|
|
381
|
+
if (_.keys(card).length > 0) {
|
|
382
|
+
cards.push(card)
|
|
383
|
+
}
|
|
384
|
+
})
|
|
338
385
|
}
|
|
339
386
|
})
|
|
387
|
+
debug(`found response cards: ${util.inspect(cards)}`)
|
|
340
388
|
|
|
341
389
|
let hasMessageText = false
|
|
342
390
|
const jsonPathsTexts = getAllCapValues(Capabilities.SIMPLEREST_RESPONSE_JSONPATH, this.caps)
|
|
@@ -351,18 +399,18 @@ module.exports = class SimpleRestContainer {
|
|
|
351
399
|
if (!messageText) continue
|
|
352
400
|
|
|
353
401
|
hasMessageText = true
|
|
354
|
-
const botMsg = { sourceData: body, messageText, media, buttons }
|
|
402
|
+
const botMsg = { sourceData: body, messageText, media, buttons, cards }
|
|
355
403
|
await executeHook(this.caps, this.responseHook, Object.assign({ botMsg, botMsgRoot: jsonPathRoot, messageTextIndex }, this.view))
|
|
356
404
|
result.push(botMsg)
|
|
357
405
|
}
|
|
358
406
|
}
|
|
359
407
|
|
|
360
408
|
if (!hasMessageText) {
|
|
361
|
-
const botMsg = { messageText: '', sourceData: body, media, buttons }
|
|
409
|
+
const botMsg = { messageText: '', sourceData: body, media, buttons, cards }
|
|
362
410
|
const beforeHookKeys = Object.keys(botMsg)
|
|
363
411
|
await executeHook(this.caps, this.responseHook, Object.assign({ botMsg, botMsgRoot: jsonPathRoot }, this.view))
|
|
364
412
|
const afterHookKeys = Object.keys(botMsg)
|
|
365
|
-
if (beforeHookKeys.length !== afterHookKeys.length || !!(botMsg.messageText && botMsg.messageText.length > 0) || botMsg.media.length > 0 || botMsg.buttons.length > 0 || !this.caps[Capabilities.SIMPLEREST_IGNORE_EMPTY]) {
|
|
413
|
+
if (beforeHookKeys.length !== afterHookKeys.length || !!(botMsg.messageText && botMsg.messageText.length > 0) || botMsg.media.length > 0 || botMsg.buttons.length > 0 || botMsg.cards.length > 0 || !this.caps[Capabilities.SIMPLEREST_IGNORE_EMPTY]) {
|
|
366
414
|
result.push(botMsg)
|
|
367
415
|
}
|
|
368
416
|
}
|
|
@@ -760,6 +760,70 @@ describe('connectors.simplerest.processBody', function () {
|
|
|
760
760
|
assert.equal(msgs[2].messageText, 'text 3')
|
|
761
761
|
assert.equal(msgs[2].media[0].mediaUri, 'http://botium.at/3.jpg')
|
|
762
762
|
|
|
763
|
+
await container.Clean()
|
|
764
|
+
})
|
|
765
|
+
it('should process card responses', async function () {
|
|
766
|
+
const myCaps = Object.assign({}, myCapsGet, {
|
|
767
|
+
[Capabilities.SIMPLEREST_RESPONSE_JSONPATH]: '$.text',
|
|
768
|
+
[Capabilities.SIMPLEREST_CARDS_JSONPATH]: '$.cards',
|
|
769
|
+
[Capabilities.SIMPLEREST_CARD_TEXT_JSONPATH]: '$.title',
|
|
770
|
+
[Capabilities.SIMPLEREST_CARD_SUBTEXT_JSONPATH]: '$.subTitle',
|
|
771
|
+
[Capabilities.SIMPLEREST_CARD_ATTACHMENTS_JSONPATH]: '$.media',
|
|
772
|
+
[Capabilities.SIMPLEREST_CARD_BUTTONS_JSONPATH]: '$.buttons[*].text'
|
|
773
|
+
})
|
|
774
|
+
const driver = new BotDriver(myCaps)
|
|
775
|
+
const container = await driver.Build()
|
|
776
|
+
assert.equal(container.pluginInstance.constructor.name, 'SimpleRestContainer')
|
|
777
|
+
|
|
778
|
+
await container.Start()
|
|
779
|
+
const msgs = await container.pluginInstance._processBodyAsyncImpl({
|
|
780
|
+
cards: [
|
|
781
|
+
{
|
|
782
|
+
title: 'card1',
|
|
783
|
+
subTitle: 'card1 sub',
|
|
784
|
+
media: 'http://botium.at/1.jpg',
|
|
785
|
+
buttons: [
|
|
786
|
+
{
|
|
787
|
+
text: 'c1b1'
|
|
788
|
+
},
|
|
789
|
+
{
|
|
790
|
+
text: 'c1b2'
|
|
791
|
+
}
|
|
792
|
+
]
|
|
793
|
+
},
|
|
794
|
+
{
|
|
795
|
+
title: 'card2',
|
|
796
|
+
subTitle: 'card2 sub',
|
|
797
|
+
media: 'http://botium.at/2.jpg',
|
|
798
|
+
buttons: [
|
|
799
|
+
{
|
|
800
|
+
text: 'c2b1'
|
|
801
|
+
}
|
|
802
|
+
]
|
|
803
|
+
}
|
|
804
|
+
]
|
|
805
|
+
}, true)
|
|
806
|
+
|
|
807
|
+
assert.exists(msgs)
|
|
808
|
+
assert.equal(msgs.length, 1)
|
|
809
|
+
assert.equal(msgs[0].cards.length, 2)
|
|
810
|
+
assert.equal(msgs[0].cards[0].text, 'card1')
|
|
811
|
+
assert.equal(msgs[0].cards[0].subtext, 'card1 sub')
|
|
812
|
+
assert.equal(msgs[0].cards[0].media.length, 1)
|
|
813
|
+
assert.equal(msgs[0].cards[0].media[0].mediaUri, 'http://botium.at/1.jpg')
|
|
814
|
+
assert.equal(msgs[0].cards[0].media[0].mimeType, 'image/jpeg')
|
|
815
|
+
assert.equal(msgs[0].cards[0].buttons.length, 2)
|
|
816
|
+
assert.equal(msgs[0].cards[0].buttons[0].text, 'c1b1')
|
|
817
|
+
assert.equal(msgs[0].cards[0].buttons[1].text, 'c1b2')
|
|
818
|
+
|
|
819
|
+
assert.equal(msgs[0].cards[1].text, 'card2')
|
|
820
|
+
assert.equal(msgs[0].cards[1].subtext, 'card2 sub')
|
|
821
|
+
assert.equal(msgs[0].cards[1].media.length, 1)
|
|
822
|
+
assert.equal(msgs[0].cards[1].media[0].mediaUri, 'http://botium.at/2.jpg')
|
|
823
|
+
assert.equal(msgs[0].cards[1].media[0].mimeType, 'image/jpeg')
|
|
824
|
+
assert.equal(msgs[0].cards[1].buttons.length, 1)
|
|
825
|
+
assert.equal(msgs[0].cards[1].buttons[0].text, 'c2b1')
|
|
826
|
+
|
|
763
827
|
await container.Clean()
|
|
764
828
|
})
|
|
765
829
|
})
|