Hero Card Display & HTML support for MSTeams - botframework

I am displaying a hero card which has several buttons. I would like to add a line break between the texts for each of the buttons. The channel that I am using is MSTeams
I have added HTML elements between the texts but that doesnt seem to help
List<CardAction> cardButtons = new List<CardAction>();
foreach (var item in items)
{
string CurrentNumber = Convert.ToString(item.number);
CardAction CardButton = new CardAction()
{
Type = "imBack",
Title = ""+CurrentNumber + "\n" + "Short Description: "+ item.short_description + "<ul><li>" + "Opened on: "+item.opened_at + "</li><li>" + "Incident state: "+myDict[item.incident_state]+ "</li></ul>"+"", //I tried this
Text = ""+CurrentNumber + "\n" + "Short Description: "+ item.short_description + "<ul><li>" + "Opened on: "+item.opened_at + "</li><li>" + "Incident state: "+myDict[item.incident_state]+ "</li></ul>"+"", //And this one too
Value = CurrentNumber
};
cardButtons.Add(CardButton);
}
HeroCard plCard = new HeroCard()
{
//Images = cardImages,
Buttons = cardButtons,
};
// Create an Attachment by calling the
// ToAttachment() method of the Hero Card
Attachment plAttachment = plCard.ToAttachment();
// Attach the Attachment to the reply
reply.Attachments.Add(plAttachment);
// set the AttachmentLayout as 'list'
reply.AttachmentLayout = "list";
While it works fine in the emulator if I add the "\n", in MS Teams, I dont get the same output.On hover, it appears that the text is appearing fine but not with MS Teams.

#Sash Sheen Teams supports formatting in cards only in the Text property. It is not supported for buttons.

Buttons are meant to be small and aren't supposed to have a lot of text on them. This is true across all channels.
My recommendation is to just include a short label on the button itself and have any additional required information elsewhere, like in the card's text. In your case, it seems like it would work out to just have the number on the button.

Related

Why does my Teams userscript have no effect?

When I paste URLs pointing to my ticketing system into other systems, I want them to look nice without a lot of manual reformatting. I have a userscript that works in GitHub taking <rootURL>/ticket/1234 and pasting it in GitHub as [#1234](<rootURL>/ticket/1234) which GitHub renders nicely.
I want to do the same thing for Teams. The Teams app for Windows has some programmability but I can't find what I need there so I've resorted to using Teams on the web and writing another userscript. (By all means, I'm happy to hear, "The way to do that in Teams is ...." but this is the best I've come up with so far.)
Whereas GitHub messages are composed in a textarea, Teams has a div that it updates as you type. I have a paste handler that creates what seem to be the right DOM elements but when my function is done, I see the original, unformatted URL in the Teams message.
My userscript is below. The logging tells me its doing the right thing but my new DOM elements don't show up in the UI. Any thoughts?
// ==UserScript==
// #name Teams Trac link
// #namespace http://tampermonkey.net/
// #version 0.1
// #description Reformat pasted link to Trac ticket to look pretty in Teams
// #author Chris Nelson, PE
// #match https://teams.microsoft.com/*
// #icon https://www.google.com/s2/favicons?sz=64&domain=microsoft.com
// #grant none
// ==/UserScript==
// Handle paste event by making custom link, when appropriate.
// If handled, suppress the browser handling of the event.
function handlePaste(event) {
console.log("Handling paste");
var target = event.target;
// Get the text that the user is trying to paste
var text = (event.clipboardData || window.clipboardData).getData('text');
try {
var url = new URL(text);
if (url.pathname.startsWith('/trac/ticket')) {
console.log("Pasting a Trac ticket link: " + text);
var parts = url.pathname.split('/');
var ticketNumber = parts[3];
// Don't let the browser also paste
event.preventDefault();
// Create a link
var link = document.createElement('a');
link.innerHTML = '#' + ticketNumber;
link.href = text;
link.title = 'Trac ticket #' + ticketNumber;
// FIXME - nothing from here on works to insert the link
// Get all divs
var divs = Array.from(document.querySelectorAll('div'));
// Filter to those with an ID that starts 'new-message-'
divs = divs.filter(d => d.id.startsWith('new-message-'));
var parent = divs[0];
console.log('Before adding, div has ' + parent.childNodes.length + ' children');
parent.appendChild(link);
console.log('After adding, div has ' + parent.childNodes.length + ' children');
}
}
catch (error) {
// Nothing, just let the browser do its thing.
}
}
(function() {
console.log("Attaching paste handler");
// Intercept a paste event anywhere on the page but
// only handle it if pasting into a new message.
document.body.addEventListener('paste', (event) => {
var target = event.target;
console.log("Got paste event for " + target);
if (target.tagName.toLowerCase() == 'br'
&& target.dataset.ckeFiller == 'true') {
handlePaste(event);
}
}, false);
})();

Is "cancel" a keyword or reserved word in Photoshop?

Is "cancel" a keyword or reserved word?
My simple dialog box:
var dlg = new Window("dialog");
dlg.text = "Proceed?";
dlg.preferredSize.width = 160;
// GROUP1
// ======
var group1 = dlg.add("group", undefined, {name: "group1"});
group1.preferredSize.width = 160;
// add buttons
var button1 = group1.add ("button", undefined);
button1.text = "OK";
var button2 = group1.add ("button", undefined);
button2.text = "Cancel";
var myReturn = dlg.show();
if (myReturn == 1)
{
// code here
}
Works fine. All is well. However replace the string "Cancel" with "Can" and the button no longer functions.
You need to add extra code in order to regain functionality.
button2.onClick = function()
{
// alert("Byas!");
dlg.close();
dialogResponse = "cancel";
}
So, what's going on, is "cancel" a keyword?
"Cancel" is not a reserved word. If you change it to can, the dialog will return "can" if clicked (and not "cancel"). Maybe you need to update your code somewhere else to reflect it.
It works with your extra code because you're forcing the return of "cancel".

V4 Botframework ActionTypes.PostBack shows selected option in chat

We are building a bot where ActionType.Postback is not working.
There are places in the Bot where it does work however the example attached does not.
The sample was build using Bot framework 4.1.5.
Any help appreciated.
if (turnContext.Activity.Type == ActivityTypes.Message)
{
if (turnContext.Activity.Text == "help")
{
var reply = turnContext.Activity.CreateReply();
reply.Text = $"Hello {turnContext.Activity.From.Name}! How can i help you today? ";
var welcomeCard = new HeroCard
{
Buttons = new List<CardAction>
{
new CardAction {Title = "option1", Value = "option1", Type = ActionTypes.PostBack},
new CardAction {Title = "option2", Value = "option2", Type = ActionTypes.PostBack},
new CardAction {Title = "option3", Value = "option3", Type = ActionTypes.PostBack}
}
}.ToAttachment();
reply.Attachments.Add(welcomeCard);
await turnContext.SendActivityAsync(reply, cancellationToken);
}
else
{
This appears to just be an error in the Bot Framework Emulator and should work fine if you publish your bot to another channel. I've gone ahead and submitted this as a bug to the development team. https://github.com/Microsoft/BotFramework-Emulator/issues/1140
Note that the PostBack Action only works in certain channels and will default to ImShow if it is not supported. In the channels where PostBack is not supported, the response text value will be visible to all participants in the conversation.

I want to create an adaptive card with buttons for email and call functionality. Whats the possible way for that?

I want to create an adaptive card with buttons for email and call functionality. I cannot find a format for call and email in adaptive cards. Is there a way to combine adaptive cards with hero cards, since hero cards have the cardAction object functionality ?
Adaptive Cards have action elements and selectactions that can be set. You would create a card with your input requirements and then use a submit action to process the input. Note on the text input elements, the format has been set to either email or tel
{"type":"AdaptiveCard","version":"1.0","id":"c2de1dd7-c916-4196-a914-0694957aff77","minVersion":"1.0","fallbackText":"","speak":"","body":[{"type":"TextBlock","id":"23af4d94-cf3b-480e-8c28-5a7988b8a26b","text":"Email Address","maxLines":1},{"type":"Input.Text","id":"4a47c737-dbf0-42d0-aa9f-10f4f38bd20f","placeholder":"enter your email here","value":"","style":"email","maxLength":250,"isRequired":false},{"type":"TextBlock","id":"b4f3bce9-2464-473f-9129-48a3740aec8b","size":"large","text":"OR","horizontalAlignment":"center","maxLines":1},{"type":"TextBlock","id":"fe2d84aa-79e7-4fdf-91a0-79a9eb264dc1","text":"Call me","maxLines":1},{"type":"Input.Text","id":"d03d538f-7ead-4959-8a8e-7703dbaf1899","placeholder":"What's your number?","value":"","style":"tel","maxLength":250,"isRequired":false}],"actions":[{"type":"Action.Submit","id":"8421a872-2c4f-4fa2-8254-b1d88503cc8a","data":"","title":"Email Me"},{"type":"Action.Submit","id":"2ccf2819-ad38-492a-80f9-7cd5152fea09","data":"","title":"Call Me"}]}
Is there a way to combine adaptive cards with hero cards, since hero cards have the cardAction object functionality ?
No, but Buttons within AdaptiveCard are not created using CardAction objects, you can use schema that is defined in AdaptiveCard instead.
There're three kinds of actions OpenUrl, Submit and ShowCard. Here Submit is what we need.
If you want to create AdaptiveCard in C#, you can for example create it and send the message like this:
AdaptiveCard card = new AdaptiveCard()
{
Body = new List<CardElement>()
{
new Container()
{
Speak = "<s>Hello!</s><s>Send Email!</s>",
Items = new List<CardElement>()
{
new TextBlock()
{
Text = "Hello!",
Weight = TextWeight.Bolder,
IsSubtle = true
},
new TextBlock()
{
Text = "Send Email!",
Wrap = true
},
new TextInput()
{
Id = "EmailAddTo",
Placeholder = "To:"
},
new TextInput()
{
Id = "EmailAddFrom",
Placeholder = "From:"
},
new TextInput()
{
Id = "Subject",
Placeholder = "Subject:"
},
new TextInput()
{
Id = "Content",
Placeholder = "Content:",
IsMultiline = true,
}
}
}
},
Actions = new List<ActionBase>()
{
new SubmitAction()
{
Title = "Send Email",
DataJson = "{\"Type\": \"EmailSend\"}"
}
}
};
Attachment attachment = new Attachment()
{
ContentType = AdaptiveCard.ContentType,
Content = card
};
var reply = context.MakeMessage();
reply.Attachments.Add(attachment);
await context.PostAsync(reply,CancellationToken.None);
When using Submit action, the Bot Framework will handle the submission and your bot will receive a new IMessageActivity with its Value, you can then handle it in your code for example like this:
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var message = await result;
if (message.Value != null)
{
// Got an Action Submit
dynamic value = message.Value;
string submitType = value.Type.ToString();
switch (submitType)
{
case "EmailSend":
/* */
return;
}
}
}
For more information, you can refer to the official Adaptive Cards Bot Sample.

Xamarin Forms complexe clickable label

I'm trying to create a string that have classic work & linked word.
I have this sentence :
I accept the terms of use and the privacy policy
In this sentence I want to have the words in bold clickable.
I already tried with an Horizontal StackLayout, Labels and Buttons but the result do not be like a simple sentence...
Any idea ?
Use a TapGestureRecognizer on a label:
var terms = new Label() { Text = "terms of use" };
var termsTapped = new TapGestureRecognizer();
termsTapped.Tapped += (o,e) =>
{
//do something
};
terms.GestureRecognizers.Add(termsTapped);
var stack = new StackLayout()
{
Orientation = StackOrientation.Horizontal
};
stack.Children.Add(new Label() { Text = "I accept the " });
stack.Children.Add(terms);
... and the same with your privacy policy.
EDIT:
If you want use this functionallity in a single lable, you could implement your own Span which is clickable and work with FormattedString.

Resources