Microsoft Teams Adaptive Card Input.ChoiceSet Apostrophe Rendered Differently - microsoft-teams

When I create an Adaptive Card for Microsoft Teams with an Input.ChoiceSet value and that value contains an apostrophe, Microsoft Teams OS X and web clients show ', the iOS and Android clients show the apostrophe (correct).
What can I do differently to get the Input.ChoiceSet value to render the apostrophe in every case?
Here's the card schema and a render below.
{
"type": "message",
"attachments": [
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "Container",
"items": [
{
"type": "TextBlock",
"text": "Command Center",
"size": "large",
"weight": "bolder"
},
{
"type": "TextBlock",
"text": "Please choose a scenario to submit."
},
{
"type": "Input.ChoiceSet",
"id": "scenario-id",
"style": "compact",
"isMultiSelect": false,
"value": "71ae62b1-f04e-11e9-b862-577308a243ca",
"choices": [
{
"value": "71ae62b1-f04e-11e9-b862-577308a243ca",
"title": "Foo's Bar"
},
{
"value": "16db3124-f42d-11e9-bde7-819811d8b810",
"title": "Second"
}
]
}
]
}
],
"actions": [
{
"type": "Action.Submit",
"id": "popup",
"title": "Continue...",
"data": {
"msteams": {
"type": "task/fetch"
}
}
}
]
}
}
]
}
Teams OS X and Teams Android Render

#MarkSingleWire Thanks for reporting this. We have raised a bug for this and we are looking into this internally.

Related

Microsoft Teams Bot Crash when using ImageSet

We had previously a Microsoft Bot using C# and adaptive cards. We have some templates stored. Suddenly Microsoft Teams starts to freeze and crash whenever a button is clicked on an adaptive card.
After some investigation, I found that the ImageSet in the adaptive card is causing the crash. By removing it, everything works fine, and when adding it, it crashes again.
Here's a preview of the adaptive card I'm using:
{
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.4",
"body": [
{
"type": "ColumnSet",
"wrap": true,
"columns": [
{
"type": "Column",
"width": "auto",
"wrap": true,
"items": [
{
"type": "TextBlock",
"text": "Text",
"weight": "Bolder",
"size": "Medium",
"color": "Accent",
"wrap": true
},
{
"type": "TextBlock",
"text": "Random Text",
"weight": "Bolder",
"color": "Default",
"wrap": true
},
{
"type": "ColumnSet",
"$data": "${modules}",
"width": "stretch",
"columns": [
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "ImageSet",
"images": [
{
"type": "Image",
"size": "Medium",
"url": "${ModuleImage}"
}
]
}
]
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "FactSet",
"facts": [
{
"type": "TextBlock",
"text": "**${ModuleTitle}**",
"value": "**${ModuleTitle}**",
"wrap": true
},
{
"type": "TextBlock",
"text": "${ModuleDescription}",
"value": "${ModuleDescription}",
"wrap": true
},
{
"type": "TextBlock",
"text": "${ModuleDuration}",
"value": "${ModuleDuration}",
"wrap": true
}
]
}
]
}
]
}
],
"verticalContentAlignment": "Center"
}
]
}
],
"actions": [
{
"type": "Action.OpenUrl",
"title": "Go To Google",
"url": "https://www.google.com"
},
{
"type": "Action.Submit",
"title": "Click me for messageBack",
"data": {
"msteams": {
"type": "messageBack",
"displayText": "I want to schedule a date.",
"text": "text to bots",
"value": "{\"buttonValue\": \"ScheduleDate\"}"
}
}
}
]
}
So what's wrong with this template? Is it a bug or what?

Disable Submit Actions and Inputs for adaptive cards in BotFramework-Webchat

I am trying to find a way to disable the Action.Submit action type and all inputs of adaptive cards that are not the most recent message in the conversation. I found this option of using the attachmentMiddleware of the BotFramework-Webchat used in React.
const attachmentMiddleware = () => next => ({ activity, attachment, ...others }) => {
if (attachment.contentType === "application/vnd.microsoft.card.custom") {
attachment.contentType = "application/vnd.microsoft.card.adaptive"
}
const { activities } = store.getState()
const messageActivities = activities.filter(
activity =>
activity.type === "message" &&
typeof activity.suggestedActions === "undefined" // to filter out suggested actions
)
const recentBotMessage = messageActivities.pop() === activity
const AdaptiveCardContent = Components.AdaptiveCardContent
switch (attachment.contentType) {
case "application/vnd.microsoft.card.adaptive":
return (
<AdaptiveCardContent
actionPerformedClassName="card__action--performed"
content={
attachment.content
}
disabled={!recentBotMessage}
/>
)
default:
return next({ activity, attachment, ...others })
}
}
This solution sets the disabled property in the AdaptiveCardContent Component for not recent messages by the bot and works really well except for Action.OpenUrl actions on containers.
Any Action.OpenUrl will have no functionality, but will look like it is still an enabled button. Example Screenshot:
As seen in the screenshot, the "primary" actions at the bottom of type Action.Submit are disabled correctly. Now the Action.ToggleVisibility ("Toggle", which changes the visibility of an text) and the Action.OpenUrl ("Open in new tab") are not disabled. The Action.ToggleVisibility ("Toggle") works as it did before, which is our intended behavior and fine. But the Action.OpenUrl which looks like it is still clickable, is in fact not.
I think it is because of the following line #107 and #108 in botframework-webchat\src\adaptiveCards\Attachment\AdaptiveCardRenderer.tsx:
// Only listen to event if it is not disabled and have "tapAction" prop.
const handleClickAndKeyPressForTapAction = !disabled && tapAction ? handleClickAndKeyPress : undefined;
But I do not understand why the Action.ToggleVisibility actions work just fine and the Action.OpenUrl actions, which html elements are not disabled and have no aria-disabled="true" properties, have no handling for clicking them.
I tried a completely different way of achieving this behavior by modifying the card, that is given to the AdaptiveCardContent, but this way leads to not wanted effects like loosing the inputted values of users after disabling the inputs, since it seems the usePersistValuesModEffect is overwritten or something, or like some unwanted effects from re-rendering the changed adaptive card.
Does anybody know if this is a bug or intended behavior of the disabled property and if so if there is a good working solution to disable inputs and only Action.Submit actions of adaptive cards?
EDIT:
This is the attachment.content value, meaning the adaptive card that is given to the <AdaptiveCardContent> component:
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"type": "AdaptiveCard",
"version": "1.3",
"speak": "",
"body": [
{
"type": "Container",
"id": "content",
"items": [
{
"type": "TextBlock",
"weight": "bolder",
"text": "A title",
"wrap": true
},
{
"type": "Container",
"items": [
{
"type": "TextBlock",
"id": "descriptionPreview",
"text": "Some Content",
"wrap": true
}
],
"spacing": "medium",
"separator": true
},
{
"type": "Container",
"items": [
{
"type": "Container",
"items": [
{
"type": "ColumnSet",
"id": "nonBlocking3",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"id": "toggleKCostDown",
"weight": "bolder",
"text": "Cost",
"wrap": true
},
{
"type": "TextBlock",
"id": "toggleCostUp",
"weight": "bolder",
"text": "Cost",
"wrap": true,
"isVisible": false
}
],
"verticalContentAlignment": "center"
}
],
"style": "accent",
"selectAction": {
"type": "Action.ToggleVisibility",
"targetElements": [
"toggleCostDown",
"toggleCostDownChevron",
"toggleCostUp",
"toggleCostUpChevron",
"contentCost"
]
},
"bleed": true
},
{
"type": "TextBlock",
"id": "contentCost",
"text": "Some info about costs.",
"wrap": true,
"isVisible": false
}
]
}
],
"bleed": true
},
{
"type": "Container",
"id": "nonBlocking4",
"items": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "50px",
"items": [
{
"type": "Column",
"width": "70",
"items": [
{
"type": "TextBlock",
"weight": "bolder",
"text": "Open in new tab",
"wrap": true
}
]
}
]
}
]
}
],
"style": "accent",
"selectAction": {
"type": "Action.OpenUrl",
"url": "https://google.com",
"title": "Open in new tab"
},
"spacing": "medium"
}
]
},
{
"type": "TextBlock",
"weight": "bolder",
"text": "Have you found what you are looking for?",
"wrap": true
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Submit",
"data": "No",
"title": "No",
"style": "destructive"
}
]
}
]
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Submit",
"data": "Yes",
"title": "Yes",
"style": "positive"
}
]
}
]
}
],
"spacing": "medium",
"separator": true
}
]
}
}

MS Teams Bot App - How to display main menu with buttons?

I'm developing a one-on-one Bot App (Azure Bot Framework) for MS Teams. A use case is simple: a user installs the Bot and Bot sends him with a welcome message plus a bunch of available functions (a menu).
My questions:
What is the best practice to display the main menu for the Bot if we speak about MS Teams?
Is it possible to have the main menu for Bot with buttons? And how to create it?
As I found Microsoft suggests using a dropdown menu (https://learn.microsoft.com/en-us/microsoftteams/platform/resources/bot-v3/bots-menus) for this purpose. But it doesn't work on mobile devices and a user has to write the command to the Bot manually - it is not the best option from UX point of view.
When I try to use buttons then I struggle with another problem: in the Adaptive Card buttons show in one line. If I separate buttons in the different column sets then:
In the desktop app everything is fine (but anyway buttons have different width).
In the iOS app everything is fine (but anyway buttons have different width).
In the Android app buttons are displayed glued to each other (without any vertical margin between them)
JSON for main menu that I used:
{
"type": "AdaptiveCard",
"version": "1.2",
"id": "main_menu",
"body": [
{
"type": "TextBlock",
"wrap": true,
"text": "%%0"
},
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Submit",
"title": "Use enhanced password policy",
"style": "positive",
"data": {
"id": "services/pw_policy"
}
}
],
"spacing" : "Medium"
},
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Submit",
"title": "Reset HPA password",
"style": "positive",
"data": {
"id": "services/hpa_reset_pswd"
}
}
],
"spacing" : "Medium"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
}
Use Colmn Set
{
"type": "AdaptiveCard",
"version": "1.2",
"id": "main_menu",
"body": [
{
"type": "TextBlock",
"wrap": true,
"text": "%%0"
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Submit",
"title": "Use enhanced password policy",
"style": "positive",
"data": {
"id": "services/pw_policy"
}
}
],
"spacing": "Medium"
}
]
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Submit",
"title": "Reset HPA password",
"style": "positive",
"data": {
"id": "services/hpa_reset_pswd"
}
}
],
"spacing": "Medium"
}
]
}
]
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
}

Microsoft Teams - multiselect in ms teams bot

How to implement multiselect in drop down list through adaptive cards to fill a form which contains the name of employees to select.
If not what are the other ways to implement multiselect in Ms Teams through bot.
Multiselect like this.
Check and build samples.
Check this sample Adaptive card
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.2",
"speak": "<s>Your meeting about \"Adaptive Card design session\"<break strength='weak'/> is starting at ${formatDateTime(start.dateTime, 'HH:mm')}pm</s><s>Do you want to snooze <break strength='weak'/> or do you want to send a late notification to the attendees?</s>",
"body": [
{
"type": "TextBlock",
"text": "${summary}",
"size": "Large",
"weight": "Bolder"
},
{
"type": "TextBlock",
"text": " ${location} ",
"isSubtle": true
},
{
"type": "TextBlock",
"text": "${formatDateTime(start.dateTime, 'HH:mm')} - ${formatDateTime(end.dateTime, 'hh:mm')}",
"isSubtle": true,
"spacing": "None"
},
{
"type": "TextBlock",
"text": "Snooze for"
},
{
"type": "Input.ChoiceSet",
"id": "snooze",
"value": "${reminders.overrides[0].minutes}",
"choices": [
{
"$data": "${reminders.overrides}",
"title": "${hours} hours",
"value": "${hours}"
},
{
"$data": "${reminders.overrides}",
"title": "${minutes} minutes",
"value": "${minutes}"
},
{
"$data": "${reminders.overrides}",
"title": "${seconds} seconds",
"value": "${seconds}"
}
],
"isMultiSelect": true
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Snooze",
"data": {
"x": "snooze"
}
},
{
"type": "Action.Submit",
"title": "I'll be late",
"data": {
"x": "late"
}
}
]
}

A certain adaptive card crashes my webchat

I'm currently working on making some dynamically generated cards, but for some reason when I try to add this one as an adaptive card the whole webchat crashes.
I've tried passing the JSON as an object without double quotes, as a string with double quotes, and as an object with double quotes.
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "Container",
"id": "header",
"items": [
{
"type": "ColumnSet",
"id": "headerColSet",
"columns": [
{
"type": "TextBlock",
"id": "actionTextCol",
"items": [
{
"type": "TextBlock",
"id": "actionText",
"text": "Action Here!",
"horizontalAlignment": "Right"
}
],
"width": "stretch"
},
{
"type": "TextBlock",
"id": "actionTextCol",
"items": [
{
"type": "TextBlock",
"id": "actionText",
"text": "Action Here!",
"horizontalAlignment": "Right"
}
],
"width": "stretch"
}
]
}
]
},
{
"type": "ColumnSet",
"id": "columnSet1",
"columns": [
{
"type": "Column",
"id": "columnIndex0",
"items": [
{
"type": "TextBlock",
"id": "textOne1",
"text": "Test text One"
}
],
"width": "stretch"
},
{
"type": "Column",
"id": "columnIndex0",
"items": [
{
"type": "TextBlock",
"id": "textTwo1",
"text": "Sec Text One"
}
],
"width": "stretch"
}
]
},
{
"type": "ColumnSet",
"id": "columnSet2",
"columns": [
{
"type": "Column",
"id": "columnIndex1",
"items": [
{
"type": "TextBlock",
"id": "textOne2",
"text": "Test text 2"
}
],
"width": "stretch"
},
{
"type": "Column",
"id": "columnIndex1",
"items": [
{
"type": "TextBlock",
"id": "textTwo2",
"text": "Sec Text 2"
}
],
"width": "stretch"
}
]
},
{
"type": "Container",
"id": "footer",
"items": [],
"separator": true
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
}
This JSON should be able to be attached to an adaptive card in the web chat, but instead the whole screen goes white and throws these errors
card-elements.js:2330 Uncaught TypeError: Cannot read property 'internalValidateProperties' of null
index.js:1375 uncaught at observeActivity TypeError: Cannot read property 'internalValidateProperties' of null
There seems to be a lot of things wrong with your Adaptive Card, most notably ColumnSet is supposed to have an array of objects with the type property set to Column. Also, TextBlocks do not have an items attribute. I would highly recommend that you use the Adaptive Card Designer to create your cards. Also take a look at the Adaptive Card Schema Explorer.
{
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "Container",
"id": "header",
"items": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "New TextBlock"
}
]
}
]
}
]
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json"
}
Hope this helps!

Resources