How to Assign a Dynamic Value to a Toast Notification - c#

I am creating a toast notification for a UWP app, and I have run into a snag. I desire to send the user a message with a quote from an author;
I have a list of 137 quotes that I am reading from, so the toast notification cannot have a static quote or author value. Here's the notification structure:
// Global quote variables
static string quote;
static string author;
// Toast struct
ToastContent toastContent = new ToastContent() {
Visual = new ToastVisual() {
BindingGeneric = new ToastBindingGeneric() {
Children = {
// Bold title text
new AdaptiveText() {
Text = "Motivational Reminder"
},
// Body text
new AdaptiveText() {
Text = quote
}
},
// Small attribution text
Attribution = new ToastGenericAttributionText() {
Text = author
}
}
},
// Notification on-click
Launch = new QueryString() {
{"action", "nothing" }
}.ToString()
};
I init the quote and author variables from another function before creating the toast, of course. I've debugged the program, and I can see that the variables get initialized before I try and make the toast, but they always come out as null:
The RawValue value should resemble the quote in the above picture. How can I otherwise assign a dynamic value to my notification?
I have looked through the Microsoft notification docs, but they always have text present in the example, rather than sourcing it from an outside variable. See here.

Related

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.

Search message extension issue in a group chat

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.

Xamarin.Forms handle notification launch (UWP)

Xamarin documentation is a mess all over the internet but I cannot seem to find a solid example of how to handle my Xamarin.Forms application being launched from a notification or handling a notification being clicked while my application is already running.
So I am inside of the Xamarin.Forms.UWP application in the App.xaml.cs file that handles all the UWP launching. Within the OnActivated method I can see that my application receives a fire and gets the proper data from my toast notification. My question is how do I pass that data back into the Xamarin.Forms instance.
protected override void OnActivated(IActivatedEventArgs args)
{
base.OnActivated(args);
var _args = (args as LaunchActivatedEventArgs).Arguments;
}
Custom UWP Notification Service:
ToastContent content = new ToastContent()
{
Launch = "...",
Visual = new ToastVisual()
{
BindingGeneric = new ToastBindingGeneric()
{
Children =
{
new AdaptiveText()
{
Text = title,
HintMaxLines = 1
},
new AdaptiveText()
{
Text = body
}
}
}
},
Actions = new ToastActionsCustom()
{
Buttons =
{
new ToastButton(acceptAction.Key, $"action={acceptAction.Value}")
{
ActivationType = ToastActivationType.Foreground
},
new ToastButton(declineAction.Key, $"action={declineAction.Value}")
{
ActivationType = ToastActivationType.Background
}
}
}
};
var toast = new ToastNotification(content.GetXml());
ToastNotificationManager.CreateToastNotifier().Show(toast);
How do I go about sending this _args variable back into the running instance of my cross-platform application so that I can process the logic of navigating to a route, etc.
Furthermore if I have to write some custom code to handle this I will want the code to be easy to integrate the same functionally with the Xamarin.Forms.Android app in this project as well.

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;

Is it possible to show animation in uwp toast notification?

I'm trying to understand if it's possible to show a countdown timer for example or some sort of animation or anything dynamic in toast notification?
Take a look at this article from Microsoft
https://learn.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/toast-progress-bar
This shows how to add a progress bar to a Toast Notification in a UWP app.
First you create your Toast Notification with a specific tag
using Windows.UI.Notifications;
using Microsoft.Toolkit.Uwp.Notifications;
public void SendUpdatableToastWithProgress()
{
// Define a tag (and optionally a group) to uniquely identify the notification, in order update the notification data later;
string tag = "weekly-playlist";
string group = "downloads";
// Construct the toast content with data bound fields
var content = new ToastContent()
{
Visual = new ToastVisual()
{
BindingGeneric = new ToastBindingGeneric()
{
Children =
{
new AdaptiveText()
{
Text = "Downloading your weekly playlist..."
},
new AdaptiveProgressBar()
{
Title = "Weekly playlist",
Value = new BindableProgressBarValue("progressValue"),
ValueStringOverride = new BindableString("progressValueString"),
Status = new BindableString("progressStatus")
}
}
}
}
};
// Generate the toast notification
var toast = new ToastNotification(content.GetXml());
// Assign the tag and group
toast.Tag = tag;
toast.Group = group;
// Assign initial NotificationData values
// Values must be of type string
toast.Data = new NotificationData();
toast.Data.Values["progressValue"] = "0.6";
toast.Data.Values["progressValueString"] = "15/26 songs";
toast.Data.Values["progressStatus"] = "Downloading...";
// Provide sequence number to prevent out-of-order updates, or assign 0 to indicate "always update"
toast.Data.SequenceNumber = 1;
// Show the toast notification to the user
ToastNotificationManager.CreateToastNotifier().Show(toast);
}
Then you can use that tag to update the Toast Notification
using Windows.UI.Notifications;
public void UpdateProgress()
{
// Construct a NotificationData object;
string tag = "weekly-playlist";
string group = "downloads";
// Create NotificationData and make sure the sequence number is incremented
// since last update, or assign 0 for updating regardless of order
var data = new NotificationData
{
SequenceNumber = 2
};
// Assign new values
// Note that you only need to assign values that changed. In this example
// we don't assign progressStatus since we don't need to change it
data.Values["progressValue"] = "0.7";
data.Values["progressValueString"] = "18/26 songs";
// Update the existing notification's data by using tag/group
ToastNotificationManager.CreateToastNotifier().Update(data, tag, group);
}

Categories

Resources