Search message extension issue in a group chat - c#

We have a Microsoft Teams message extension app. If I search in a group chat and select one item in the result the chat input disappears and the "New conversation" button is shown again. This was working correctly earlier when there was no "New conversation" button in group chats only the chat input directly. This was working in earlier version of Teams, when there was no "New conversation" button.
This happens only if the result ThumbnailCards have "invoke" Tap CardAction. If I remove the "invoke" Tap CardAction, then the selected item in the result is inserted into the chat input correctly.
In private chat it is working correctly with the "invoke" Tap CardAction.
This is the ThumbnailCard for each search result item:
...
var card = new ThumbnailCard
{
Title = title,
Text = cardContent,
Images = new System.Collections.Generic.List<CardImage> { new CardImage(iconUrl) },
Buttons = new List<CardAction> { new CardAction(ActionTypes.OpenUrl, downloadText, null, itemLink, downloadText, itemLink) },
Tap = new CardAction
{
Type = "invoke",
Value = new JObject
{
["Id"] = GetItemPermanentId(item["Link"].ToString()),
["Title"] = title,
["Text"] = cardContent,
["IconUrl"] = iconUrl,
["DownloadText"] = downloadText,
["DownloadLink"] = itemLink
}
}
};
var attachment = card
.ToAttachment()
.ToMessagingExtensionAttachment();
return attachment;
...
The OnTeamsMessagingExtensionSelectItemAsync method is called correctly after I click on a result, but as described above, the chat input disappears and the "New conversation" button is shown again.
Target framework: .NET Core 2.1,
AdaptiveCards: 2.1.0,
Microsoft.Bot.Builder.Azure: 4.9.2,
Microsoft.Bot.Builder.Integration.AspNet.Core: 4.7.0.
Is this a Microsoft Teams bug or I need to change something on the code?

We are able to repro the issue at our end raised a bug. We don't have ETA to share when it will be fixed.

Teams update fixed this issue.

Related

C# WTelegramClient Telegram-API How to programmatically click a button in a message from Telegram-Bot

The program communicates with Telegram-Bot. A text message is sent to the bot. The bot responds to the message. The answer contains 3 buttons. Question: How to click on a button programmatically?
Create a Telegram client:
_client = new WTelegram.Client(Config):
_user = await _client.LoginUserIfNeeded();
Finding a bot:
var contacts = await _client.Contacts_Search("#Search_bot", 20);
contacts.users.TryGetValue(1911124859, out peerBot));
Sending a request (message) to the Bot:
var message = await _client.SendMessageAsync(peerBot, "REQUEST");
We get an answer:
var differenceMessages = await _client.Updates_GetDifference(state.pts, state.date, state.qts);
We understand the answer. We find a button.
How to send a message to the Bot that we clicked on the button?
TL.Message tLMessage = null;
if (differenceMessages != null)
{
if(differenceMessages.NewMessages != null)
{
foreach (var difference in differenceMessages.NewMessages)
{
tLMessage = difference as TL.Message;
if(tLMessage != null && tLMessage.peer_id.ID == peerBot.ID )
{
if (!(tLMessage.reply_markup is ReplyMarkup replyMarkup)) continue;
TL.ReplyInlineMarkup replyInlineMarkup = (ReplyInlineMarkup)replyMarkup;
if (replyInlineMarkup.rows[2].buttons[0].Text == "Check text on Button")
{
***//TODO We want to click on this button!***
}
}
}
}
}
An inline button can be one of several types.
Let's assume you're talking about a Callback button (that sends its callback to the bot)..
Searching through the full list of API methods available, you would quickly find that the right method to proceed to clicking on that button is messages.getBotCallbackAnswer (so Messages_GetBotCallbackAnswer in WTelegramClient naming)
Therefore, in your case, you would write something like this:
if (replyInlineMarkup.rows[ROW].buttons[COLUMN] is KeyboardButtonCallback btnCallback)
{
var answer = await client.Messages_GetBotCallbackAnswer(peerBot, tLMessage.id, data: btnCallback.data);
}

Bot mentions to meetings groups are blank on Desktop/Web chat view

We're developing a bot that proactively messages people in a group chat.
Bot mentions are showing blank on Desktop/Web chat view. Interestingly, on mobile and in the notification bar on the left, the full text does show correctly.
This issue may apply to other chats, but I have not tested.
I'm using similar code to the following Microsoft guide by constructing the mention object:
https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/channel-and-group-conversations?tabs=dotnet#add-mentions-to-your-messages
Yes, I have tried using XMLConvert on the name as in the example, however, that does not make a difference, in fact, it puts the XML verbatim into the message sent by the bot.
I've also submitted a bug report here, as I suspect it's a bug in Teams itself (although, I could not find any other mentions of this or other similar example code):
https://microsoftteams.uservoice.com/forums/555103-public/suggestions/43922577-bot-mentions-to-meetings-groups-are-blank-on-deskt
Relevant C# code:
...
using (ConnectorClient _client = new ConnectorClient(new Uri(groupChat.ServiceUrl), GetMicrosoftAppCredentials(), new HttpClient()))
{
var theMessage = Activity.CreateMessageActivity();
theMessage.Text = messageDto.Message;
// Process the message text for <at>mentions</at>
var textMentions = System.Text.RegularExpressions.Regex.Matches(theMessage.Text, "<at>(.*?)</at>");
var mentionObjects = new List<Entity>(); // For storing the mentions
foreach (var textMention in textMentions)
{
// The mentioned person should be between the tags
var theName = textMention.ToString().Split(new string[] { "<at>", "</at>" }, StringSplitOptions.RemoveEmptyEntries)[0];
if (!String.IsNullOrEmpty(theName))
{
// Find the teamsUser based on their name
var teamsUser = _botContext.Users.FirstOrDefault(u => u.Name.Equals(theName));
if (teamsUser != null)
{
var mention = new Mention
{
Mentioned = new ChannelAccount(teamsUser.TeamsUserId),
Text = textMention.ToString()
};
mentionObjects.Add(mention);
}
}
}
theMessage.Entities = mentionObjects;
try
{
var response = await _client.Conversations.SendToConversationAsync(groupChat.GroupChatId, (Activity)theMessage);
return Ok(response.Id);
}
catch (Exception e)
{}
}
...
Desktop Teams Chat:
Activity shows name OK:
Mobile app looks OK:
Images edited for privacy
Try passing "User Name" also in ChannelAccount() like below:
var mention = new Mention
{
Mentioned = new ChannelAccount(
turnContext.Activity.From.Id,
**turnContext.Activity.From.Name,**
role: null,
aadObjectId: null),
Text = textMention.ToString()
};
I tried above code and it's working for me.

How can I get user response from adaptive card using Adaptive Dialogs methodology from Microsoft Bot Framework?

The idea here is pretty simple. I have written a code to display an adaptive card (with the command - new SendActivity("${AdaptiveCard()}")) asking for user's name and email. After the user submit those inputs I just want to retrieve those for future implementations, but I'm not being able to do so.
I have found several implementations of this using Waterfall dialog, but none using adaptive dialogs.
Here, it can be found a stack overflow post How to retrieve user entered input in adaptive card to the c# code and how to call next intent on submit button click - about How to retrieve user entered input in adaptive card to the c# code and how to call next intent on submit button click. However, if you check the anwser the user says it is for Waterfall Dialogs, perhaps the code is alike, but I wasn't able to convert it to Adaptive Dialogs implementation.
There is another reference, that may be useful. https://blog.botframework.com/2019/07/02/using-adaptive-cards-with-the-microsoft-bot-framework/. Although this tutorial shows how to implement adaptive cards using waterfall dialog, the code might look similar. More specifically, the implementation in this tutorial to retrieve user input, can be seen below. It is crucial to note that this implementation uses turnContext.Activity.Text to access user response from the Adaptive Card, however how can I access such a variable turnContext in Adaptive Dialogs?
var txt = turnContext.Activity.Text;
dynamic val = turnContext.Activity.Value;
// Check if the activity came from a submit action
if (string.IsNullOrEmpty(txt) && val != null)
{
// Retrieve the data from the id_number field
var num = double.Parse(val.id_number);
// . . .
}
Here, we can see the code for my RootDialog class from Adaptive Dialog implementation. Where in my code can I retrieve the user information as in the example above?
public class RootDialog : ComponentDialog
{
private readonly IConfiguration configuration;
public RootDialog(IConfiguration configuration)
: base(nameof(RootDialog))
{
this.configuration = configuration;
string[] paths = { ".", "Dialogs", $"{nameof(RootDialog)}.lg" };
string fullPath = Path.Combine(paths);
// Create instance of adaptive dialog.
var rootDialog = new AdaptiveDialog(nameof(AdaptiveDialog))
{
// These steps are executed when this Adaptive Dialog begins
Triggers = new List<OnCondition>()
{
// Add a rule to welcome user
new OnConversationUpdateActivity()
{
Actions = WelcomeUserSteps()
},
// Respond to user on message activity
new OnUnknownIntent()
{
Actions = OnBeginDialogSteps()
}
},
Generator = new TemplateEngineLanguageGenerator(Templates.ParseFile(fullPath))
};
// Add named dialogs to the DialogSet. These names are saved in the dialog state.
AddDialog(rootDialog);
// The initial child Dialog to run.
InitialDialogId = nameof(AdaptiveDialog);
}
private static List<Dialog> WelcomeUserSteps()
{
return new List<Dialog>()
{
// Iterate through membersAdded list and greet user added to the conversation.
new Foreach()
{
ItemsProperty = "turn.activity.membersAdded",
Actions = new List<Dialog>()
{
// Note: Some channels send two conversation update events - one for the Bot added to the conversation and another for user.
// Filter cases where the bot itself is the recipient of the message.
new IfCondition()
{
Condition = "$foreach.value.name != turn.activity.recipient.name",
Actions = new List<Dialog>()
{
new SendActivity("Hi there, I'm here to help you!")
}
}
}
}
};
}
private static List<Dialog> OnBeginDialogSteps()
{
return new List<Dialog>()
{
new SendActivity("${AdaptiveCard()}"),
};
}
}

Application name in Windows 10's timeline - WinForms

I have the following code:
UserActivitySession _currentActivity;
private async Task GenerateActivityAsync()
{
// Get the default UserActivityChannel and query it for our UserActivity. If the activity doesn't exist, one is created.
UserActivityChannel channel = UserActivityChannel.GetDefault();
UserActivity userActivity = await channel.GetOrCreateUserActivityAsync("Test");
// Populate required properties
userActivity.VisualElements.DisplayText = ActivityName.Text; //ActivityName is textbox
userActivity.ActivationUri = new Uri(ActivityUri.Text); //ActivityUri is also textbox
userActivity.VisualElements.Description = "This is test item";
userActivity.VisualElements.Attribution =
new UserActivityAttribution(new Uri("http://via.placeholder.com/16x16"))
{ AlternateText = "Test123" };
//Save
await userActivity.SaveAsync(); //save the new metadata
// Dispose of any current UserActivitySession, and create a new one.
_currentActivity?.Dispose();
_currentActivity = userActivity.CreateSession();
}
And it results in something like on the screenshot: https://imgur.com/a/LK0NHAa
I want my app's name to be displayed after the dash character (the dash is inserted there by Windows).
You code specifies this:
userActivity.VisualElements.DisplayText = ActivityName.Text;
tried changing the DisplayText to the value you want?
Getting app name:
var pack = Package.Current.Id.Name;

How to implement the button click functionality in bots with respective cards

Hi I am working on Bot in that I have a requirement like when an user click the button I want to display the related content in next card like this below.
Can anyone please tell me how to implement the above scenario in bots by using any cards like adaptive cards, rich cards or Thumbnail cards?
With Adaptive Cards, you can use AdaptiveSubmitAction for that:
new AdaptiveSubmitAction()
{
Data = "show me the next card"
};
This produces a new incoming message with message.Text being the value of Data and you can process it the same way as a regular message from user.
You can achieve the same with other rich cards / Thumbnail cards, using ImBack and PostBack actions:
new CardAction()
{
Type = ActionTypes.ImBack,
Value = "show me the next card"
}
The AdaptiveSubmitAction also has DataJson property that you can use instead of Data (the DataJson has no effect if you use both). You can put a json structure there, that will end up in message.Value of the incoming message, while message.Text will be null in that case.
This can be handy when you need to pass more details, e.g. DataJson = "{ \"CardName\": \"City\", \"Name\": \"New York\" }" could mean you want to open some City card for New York. Then you can retrieve the structure like this:
protected override async Task MessageReceived(IDialogContext context, IAwaitable<IMessageActivity> item)
{
var message = await item;
if (string.IsNullOrEmpty(message.Text))
{
dynamic value = message.Value;
if (value == null)
{
// empty message - show help, error etc.
}
dynamic cardName = value.CardName;
// check the name, respond with the wanted card ...
}
else
{
// process as usual
await base.MessageReceived(context, item);
}
}
Here is a sample project that uses the json approach.

Categories

Resources