I'm building a Microsoft Teams app with the botbuilder in typescript. Everything is working fine except the UI is not matching exactly what I want. Im using an adaptive card to render my responses to the user and typically the adaptive card has a top border (seen below is black) but mine doesnt have it and i'm trying to figure out how i can make it work.
I want my card to have the black border on top as shown here for in github's bot:
See image
This is what mine currently shows:
see image
below is my code to render the card. What i'm i doing wrong?
await context.sendActivity({ attachments: [
CardFactory.adaptiveCard({
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0",
"msteams": {
"width": "Full"
},
"body": [
{
"type": "TextBlock",
"text": "My card doesnt have the border.",
"wrap": true
}
]
})
] });
I figured it out and it was a simple fix. The code now looks like this.
"body": [
{
"type": "TextBlock",
"text": "My card doesnt have the border.",
"wrap": true,
"style": {
"borderTopWidth": 1,
"borderTopColor": "#000"
}
}
] });
I finally figured out the solution. I had to the office 365 connector card to get that color strip. FINALLY!
Here's the code sample for Nodejs/typescript:
CardFactory.o365ConnectorCard({
"title": "card title",
"text": "card text",
"summary": "O365 card summary",
"themeColor": "#E67A9E",
"sections": [
{
"text": "This is some <strong>bold</strong> text"
},
{
"text": "This is some <em>italic</em> text"
},
{
"text": "This is some <strike>strikethrough</strike> text"
},
{
"text": "<h1>Header 1</h1>\r<h2>Header 2</h2>\r <h3>Header 3</h3>"
},
{
"text": "bullet list <ul><li>text</li><li>text</li></ul>"
},
{
"text": "ordered list <ol><li>text</li><li>text</li></ol>"
},
{
"text": "hyperlink Bing"
},
{
"text": "embedded image <img src=\"https://aka.ms/Fo983c\" alt=\"Duck on a rock\"></img>"
},
{
"text": "preformatted text <pre>text</pre>"
},
{
"text": "Paragraphs <p>Line a</p><p>Line b</p>"
},
{
"text": "<blockquote>Blockquote text</blockquote>"
}
]
})
Related
I recently made my first Slack app - a sort of Tech Support FAQs tool for my workplace workspace.
I originally wanted the responses to be much more complex using the Slack Block Kit, and having trawled the documentation on the Slack API site it looked like I could simply exchange Attachments for Blocks:
function respondWithFaq(text, callbackId, respond, choice) {
frequentlyAskedQuestions.callback_id = callbackId
frequentlyAskedQuestions.text = 'What are you trying to do?'
respond({
text: text,
attachments: [frequentlyAskedQuestions[choice]], //All different choices are saved in a .json array and then saved at the top in a variable called frequentlyAskedQuestions
replace_original: true
})
}
However, when I swap that tag out the messages never print. I have used the Block Kit builder to try and construct more complex and useful responses using multiple sections but it doesn't seem to like more than 1 section in it's responses.
My .json files are structured in arrays depending on which choice was made in the previous select menu like so:
[
{
"fallback": "Upgrade your Slack client to use messages like these.",
"color": "#3AA3E3",
"attachment_type": "default",
"callback_id" : "slack_help",
"actions": [
{
"name": "subject_list",
"text": "Select one",
"type": "select",
"options": [
{
"text": "Add somebody to a channel",
"value": "addToChannel"
},
{
"text": "Find an old message",
"value": "oldMessageThread"
},
{
"text": "Fix my camera",
"value": "cameraBroken"
},
{
"text": "Fix my audio",
"value": "audioBroken"
},
{
"text": "Add a new workspace",
"value": "addWorkspace"
},
{
"text": "Submit a support ticket",
"value": "submitTicket"
}
]
}
]
},
{
"fallback": "Upgrade your Slack client to use messages like these.",
"color": "#3AA3E3",
"attachment_type": "default",
"callback_id" : "box_help",
"actions": [
{
"name": "subject_list",
"text": "Select one",
"type": "select",
"options": [
{
"text": "Fix Box Tools",
"value": "boxTools"
},
{
"text": "Unable to open a file from Box",
"value": "microsoftOnline"
},
{
"text": "Find a file or folder",
"value": "findFile"
},
{
"text": "Edit a file that has been shared with me",
"value": "editFile"
},
{
"text": "Merge my Box accounts",
"value": "accountMerge"
},
{
"text": "Submit a support ticket",
"value": "submitTicket"
}
]
}
]
},
and so on...
I wondered if this was something to do with the Response URL formatting but having read that documentation it appears that Blocks can be used within that.
Any advice or documentation that could help me with this?
I recognise that I am quite new to coding and perhaps I've done something really obvious - please point it out so I can learn!
I followed this tutorial online to create the app, and as they used attachments so did I. Then I tried to adapt from there.
I have the following JSON code for an Adaptive Card. I put this into a "Compose" Data operation, and then used the "Post your own adaptive card as the Flow bot to a user" and it successfully works. However, using this REST API doesn't work when you want to wait for a response. So I tried to use "Post an Adaptive Card to a Teams user and wait for a response", but when I try to use the following JSON code below, it is giving me an error of... "[Validation] An Input.ChoiceSet must have at least one choice defined."
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.2",
"body": [
{
"type": "TextBlock",
"size": "Medium",
"weight": "Bolder",
"text": "Input.Text elements",
"horizontalAlignment": "Center",
"wrap": true
},
{
"type": "TextBlock",
"text": "Part #",
"wrap": true
},
{
"type": "Input.ChoiceSet",
"id": "choiceSelect",
"choices": #{variables('ArrayTest')}
},
{
"type": "TextBlock",
"text": "Due Date",
"wrap": true
},
{
"type": "Input.Date",
"id": "DateVal"
},
{
"type": "TextBlock",
"text": "Start time",
"wrap": true
},
{
"type": "Input.Time",
"id": "TimeVal"
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Submit"
}
]
}
So after receiving this error, I tried to manipulate the code and I ended up changing the ChoiceSet to this
{
"type": "Input.ChoiceSet",
"id": "choiceSelect",
"choices": [
{
"title": "#{variables('ArrayTest')}",
"value": "#{variables('ArrayTest')}"
}
]
}
And I did not receive in a error in the Adaptive Card, but rather a Power Automate error of...
"The request failed. Error code: 'InvalidJsonInBotAdaptiveCard'. Error Message: 'Microsoft.Azure.ProcessSimple.Data.Entities.Exceptions.ProcessSimpleDataException: The specified Teams flowbot adaptive card request is missing or invalid. The tracking Id is '{0}'. ---> Newtonsoft.Json.JsonReaderException: After parsing a value an unexpected character was encountered: t. Path 'body[2].choices[0].title', line 1, position 356."
My question is... How can I use a dynamic ChoiceSet while also utilizing the "wait for a response"? I successfully can get it in a "Post your own adaptive card as the Flow bot to a user" but not a "Post an Adaptive Card to a Teams user and wait for a response"
I am developing BOT where I am sending some files to bot which seems working but the icon that is appearing in the chat window during send is just the file name rather then icon/logo of respective file extension.
So this is how its looking currently.
I want it to look like a rectangle kind of shape with respective icon effect like how any other char platform works.
This is not something that is native to the bot framework, mainly because all the channels handle it differently. For example, uploading a document on Teams shows the icon you're looking:
but webchat does not:
If you want the icon like the one that appears in Teams to appear in webchat, you're going to have to do it manually. The easiest way to do this is to have a check in your code for a successful upload, and then create a card with the icon, the file name, and an 'upload successful!' message.
Here's a rough idea:
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0",
"type": "AdaptiveCard",
"speak": "<s>Your flight is confirmed for you and 3 other passengers from San Francisco to Amsterdam on Friday, October 10 8:30 AM</s>",
"body": [
{
"type": "TextBlock",
"text": "Upload Successful!",
"weight": "Bolder"
},
{
"type": "ColumnSet",
"separator": true,
"columns": [
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "TextBlock",
"text": " "
},
{
"type": "Image",
"url": "https://lh3.googleusercontent.com/proxy/gg1rCqkRVyyJ_wt67HExRIjYf4NvaRYVUXpg3crwUK7joCyVSeYmEJ3EgnLI3QbtX-1ulZYPF_6THsjituT2OG2z",
"size": "Small",
"spacing": "None"
}
]
},
{
"type": "Column",
"width": 1,
"items": [
{
"type": "TextBlock",
"horizontalAlignment": "Right",
"size": "ExtraLarge",
"color": "Accent",
"text": "cat-2.5.gcode",
"spacing": "None"
}
]
}
]
}
]
}
I don't want to use builder.Prompts.choicesince i want to allow user type answer not only click buttons. So i use sourceEvent, works great with facebook messenger but know i don't have ability to test my bot in emulator, since buttons not appear.
replyMessage.sourceEvent({
facebook: {
quick_replies: [
{
"content_type": "text",
"title": "Money Management",
"payload": "Money Management"
},
{
"content_type": "text",
"title": "Retirement Plans",
"payload": "Retirement Plans"
}
]
},
});
How to show buttons with sourceEvent in emulator?
Ok screenshot we see that buttons get to bot emulator as attachments.
let replyMessage = new builder.Message(session).text("hi");
replyMessage.addAttachment(
{
"contentType": "application/vnd.microsoft.card.hero",
"content": {
"buttons": [ {"type": "postBack", "title": "Your title", "value": "your value"} ]
}
}
);
I'm trying to mention a user from an incoming webhook.
I tried a few iterations via Postman of
{
"text": "test #user"
}
or
{
"text": "test #user#email.com"
}
but none of these seem to work.
Is this simple but very important thing just not possible?
Thanks.
I'm afraid this isn't possible yet - the only way to do # mentions is by using the full Bot Framework APIs.
You're not the only one to have asked for this though, so I'll get it on the backlog.
This is now supported and documented here (https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-format?tabs=adaptive-md%2Cconnector-html#user-mention-in-incoming-webhook-with-adaptive-cards).
Sample:
{
"type": "message",
"attachments": [
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"size": "Medium",
"weight": "Bolder",
"text": "Sample Adaptive Card with User Mention"
},
{
"type": "TextBlock",
"text": "Hi <at>Adele UPN</at>, <at>Adele AAD</at>"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0",
"msteams": {
"entities": [
{
"type": "mention",
"text": "<at>Adele UPN</at>",
"mentioned": {
"id": "AdeleV#contoso.onmicrosoft.com",
"name": "Adele Vance"
}
},
{
"type": "mention",
"text": "<at>Adele AAD</at>",
"mentioned": {
"id": "87d349ed-44d7-43e1-9a83-5f2406dee5bd",
"name": "Adele Vance"
}
}
]
}
}
}]
}
If it helps anybody, after looking in to this and seeing it couldn't be done (still!?), a workaround for me was to change the channel notification settings to banner + feed for all new posts for relevant users in the channel. This eliminates the need to use the tag (if tagging the team).
It is supported in Teams now, however the sample code does not work in Microsoft card playground, I didn't know the code actually worked until I tried in Postman.