Skip to content

Commit 5e9d2c4

Browse files
author
Botium
authored
Merge pull request #40 from codeforequity-at/feature/BOT-1013-core-support-nested-cards
BOT-1013 core support nested cards
2 parents ec4a9fa + 6a5ba1b commit 5e9d2c4

File tree

3 files changed

+44
-22
lines changed

3 files changed

+44
-22
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ This is a [Botium](https://github.com/codeforequity-at/botium-core) connector fo
1010

1111
__Did you read the [Botium in a Nutshell](https://medium.com/@floriantreml/botium-in-a-nutshell-part-1-overview-f8d0ceaf8fb4) articles ? Be warned, without prior knowledge of Botium you won't be able to properly use this library!__
1212

13-
## How it works ?
13+
## How it works?
1414
The Direct Line API 3.0, part of the Microsoft Bot Framework, enables Botium to talk to a chatbot deployed and running with the Microsoft Bot Framework.
1515

1616
The Direct Line version number does not correspond to the Microsoft Bot Framework version number. So this connector actually supports __Microsoft Bot Framework v3 as well as v4__.
@@ -20,7 +20,10 @@ It can be used as any other Botium connector with all Botium Stack components:
2020
* [Botium Bindings](https://github.com/codeforequity-at/botium-bindings/)
2121
* [Botium Box](https://www.botium.at)
2222

23-
This connector extracts form contents from adaptive cards. You can assert them with [Forms Asserter](https://botium.atlassian.net/wiki/spaces/BOTIUM/pages/48627713/Forms+Asserter).
23+
24+
## Features
25+
* Button, Media, Card, Form extraction. Accordingly it is possible to use a corresponding [Botium Asserter](https://botium.atlassian.net/wiki/spaces/BOTIUM/pages/2293815/Botium+Asserters).
26+
* Adaptive Card support.
2427

2528
## Requirements
2629

index.js

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,32 @@ class BotiumConnectorDirectline3 {
133133
mimeType: mime.lookup(m.url) || 'application/unknown',
134134
altText: m.profile
135135
})
136-
136+
const mapAdaptiveCardRecursive = (c) => {
137+
const textBlocks = this._deepFilter(c.body, (t) => t.type, (t) => t.type === 'TextBlock')
138+
const imageBlocks = this._deepFilter(c.body, (t) => t.type, (t) => t.type === 'Image')
139+
const buttonBlocks = this._deepFilter(c.body, (t) => t.type, (t) => t.type.startsWith('Action.'))
140+
const actions = (c.actions || []).concat((buttonBlocks && buttonBlocks.map(mapButton)) || [])
141+
const subcards = actions.filter(a => (a.type === 'Action.ShowCard' && a.card)).map(a => mapAdaptiveCardRecursive(a.card))
142+
const inputs = this._deepFilter(c.body, (t) => t.type, (t) => t.type.startsWith('Input.'))
143+
const forms = []
144+
for (const input of inputs) {
145+
forms.push({
146+
name: input.id,
147+
label: input.label,
148+
type: input.type.substring('Input.'.length),
149+
options: input.choices
150+
})
151+
}
152+
return {
153+
text: textBlocks && textBlocks.map(t => t.text),
154+
image: imageBlocks && imageBlocks.length > 0 && mapImage(imageBlocks[0]),
155+
buttons: actions.map(mapButton),
156+
media: imageBlocks && imageBlocks.length > 1 && imageBlocks.slice(1).map(mapImage),
157+
forms: forms.length ? forms : null,
158+
cards: subcards.length ? subcards : null,
159+
sourceData: c
160+
}
161+
}
137162
message.attachments && message.attachments.forEach(a => {
138163
if (a.contentType === 'application/vnd.microsoft.card.hero') {
139164
botMsg.cards.push({
@@ -146,25 +171,9 @@ class BotiumConnectorDirectline3 {
146171
sourceData: a
147172
})
148173
} else if (a.contentType === 'application/vnd.microsoft.card.adaptive') {
149-
const textBlocks = this._deepFilter(a.content.body, (t) => t.type, (t) => t.type === 'TextBlock')
150-
const imageBlocks = this._deepFilter(a.content.body, (t) => t.type, (t) => t.type === 'Image')
151-
const buttonBlocks = this._deepFilter(a.content.body, (t) => t.type, (t) => t.type.startsWith('Action.'))
152-
153-
botMsg.cards.push({
154-
text: textBlocks && textBlocks.map(t => t.text),
155-
image: imageBlocks && imageBlocks.length > 0 && mapImage(imageBlocks[0]),
156-
buttons: ((a.content.actions && a.content.actions.map(mapButton)) || []).concat((buttonBlocks && buttonBlocks.map(mapButton)) || []),
157-
media: imageBlocks && imageBlocks.length > 1 && imageBlocks.slice(1).map(mapImage),
158-
sourceData: a
159-
})
160-
const inputs = this._deepFilter(a.content.body, (t) => t.type, (t) => t.type.startsWith('Input.'))
161-
for (const input of inputs) {
162-
botMsg.forms.push({
163-
name: input.id,
164-
label: input.label,
165-
type: input.type.substring('Input.'.length),
166-
options: input.choices
167-
})
174+
// if is send 'card inputs please' instead of 'card inputs' then there is an empty card in attachments
175+
if (a.content) {
176+
botMsg.cards.push(mapAdaptiveCardRecursive(a.content))
168177
}
169178
} else if (a.contentType === 'application/vnd.microsoft.card.animation' ||
170179
a.contentType === 'application/vnd.microsoft.card.audio' ||
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
subcards
2+
3+
#me
4+
BUTTON card inputs
5+
6+
#bot
7+
Showing inputs
8+
FORMS SimpleVal|UrlVal|EmailVal|CommentVal|..
9+
BUTTONS Submit|Show Card|Ok
10+
MEDIA https://www.bing.com/th?id=AR_3934aff63dd6ff941034090a4b9d12e1&w=50&h=50&dpr=2&pid=AppEx

0 commit comments

Comments
 (0)