Sending notifications with Corona updates to thousands of doctors

During the Corona crisis, our (Belgian) government sends out regular updates for medical professionals. I created a small UWP app that will notify all the subscribed doctors when new information is available. The doctors can download and install this application from the Microsoft Store to see the updates pop up in a toast message.

Introduction

I am working for a company specialized in software for general practitioners . The practitioners use our software to keep data about patients, and use a whole lot of (almost) mandatory services provided by the government. This is all initiated from the client.

Now we need to work in the other direction. When we receive an update (in this case typically about Corona), we must push it to all the connected doctors. This can be done using polling (every x minutes we check if there is something new), or using push notifications.

Architectural choice

For communication from the server to clients there are 2 main possibilities in Microsoft Azure: either use SignalR, or use Azure Notification hubs. My first choice was to use SignalR, but it this is mainly supported for web applications (web sockets). 

I decided to use Azure Notification Hubs.

  • In the free tier we can push 1 million messages per day to max 500 active devices. Currently this is sufficient, but when more users install this app we’ll upgrade to the basic tier. This allows for 200 000 devices and 10 million messages per day, for a wobbling 8,43€ / month. That will do!
  • But to start pushing messages to devices we first need to create and register a UWP application. For this we have to create an account, and then register our application in this account. Once this is done, we can send messages from the notification hub to this application, hence to devices where the application is installed.

Steps to register the UWP application

These are the steps to take to set up a UWP application showing popups when a notification is sent. Below are more details for each step.

  1. If  this is your first UWP application, register your company (or you personally) in Windows Store.
  2. Register the app in Windows store, to obtain the necessary IDs.
  3. Create a notification hub in MS Azure, link it with the app IDs that we just registered.
  4. Create a UWP app to receive the notifications and show Toast messages to the users.
  5. Deploy this app in the Windows Store.

Registering the company in the Windows Store

  • Go to the Windows Dev Center and sign in with your Microsoft account.
  • Now click on “Windows / XBOX” and follow the steps to register yourself or your company.
  • The registration is finalized by entering your creditcard data. At the moment of writing (March 2020) it costs 14€ for an individual developer, and 75€ for a company. There is a warning that registering a company can take some time (possibly weeks) to verify the account. Creating a personal account seems to be immediate.

Create an app in the Windows Store

Now that we have a developer account we can create a new app in that same portal. Click on “Create a new app” to start the registration.

New app button

Enter a name for your app and click on “Check Availability”. If this is OK, you can proceed by clicking on “Reserve product name”. To be able to send notifications to this application, we need to retrieve some IDs.

 

  • In the menu on the left click on “Product Management” > “WNS/MPNS”. This opens the Push notifications page.
  • In the page is a link “Live Services site”. The link opens your Notifications Registration page in a new tab.
  • On this page you find the Application Secrets and the Package SID. Either keep this page open, or take a note of the values. We will need them when setting up the Notification hub.

On this page you can also add a logo if you want.

Create a Notification Hub

To create the notification hub, you will of course need an Azure account. If you don’t have an Azure account yet, follow the steps outlined here.

Log in to the portal to create the notification hub. The easiest way to do this is by clicking on the “hamburger menu” in the top left corner and then select “Create a resource”.

 

Type “Notification Hub” in the search box and press enter. You can review the overview and the plans. Click on “Create” to start the creation of the resource.

This takes us to the Basics tab:

The main things to fill out here are

  • Resource group. You can select an existing resource group or create a new one. I usually create a resource group per application, and per environment (ACC / PROD). I also apply naming conventions to nicely separate all. The name of this resource group can be something like “myapp-rg-dev”.
  • Notification Hub Namespace. Enter a unique name here. Also apply naming conventions.
  • The same for Notification Hub.
  • Don’t change the pricing tier. You can do that later, when the application outgrows the capacity.

You can now go to the “Tags” tab to enter some tags if you want, or click “Create” directly. This will create the Notification hub namespace and the Notification hub itself.

Link the UWP app to the Notification hub

Once the notification hub is created, you can go to the “Windows (WNS)” tab to enter the package SID and the Security key from the UWP app that we just registered. Don’t forget to click “Save”!

Create a UWP app to show notifications

We will keep the app very simple, the only thing it needs to do is wait for a notification to arrive, and then display that notification as a Windows toast. The nice thing is that once the app installed via the Microsoft store, it doesn’t have to be running to receive the toasts. When the app is installed, it will be opened so all we want is some static welcome screen.

  • In Visual Studio 2019 you need to have the UWP app-development tools installed. This can be done by running the VS2019 setup. When you create a new project, you can now pick the “Blank App (Universal Windows)” project template.
  • Give the application a name, and use the defaults for the other settings. 
  • Hit F5 and admire the empty application.

MainPage.xaml

Nothing fancy here, especially given that I am “graphically handicapped.”

<Page
x:Class="****Notifications.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Width="Auto" Height="Auto"
>
<Page.Background>
<AcrylicBrush TintColor="#FF35B2A6"/>
</Page.Background>

<StackPanel>
<TextBlock Text="**** Notifier" Foreground="#FCFFFFFF" FontSize="72" HorizontalAlignment="Center"/>
<TextBlock Text="This application will show a message in the system tray when new COVID updates are avaialable." Foreground="#FCFFFFFF" FontSize="18" HorizontalAlignment="Left" TextWrapping="WrapWholeWords" />
<TextBlock Text="You can safely close this window, you will still receive the notifications." Foreground="#FCFFFFFF" FontSize="18" HorizontalAlignment="Left" TextWrapping="WrapWholeWords"/>
</StackPanel>
</Page>

Mainpage.cs is not changed at all.

App.xaml.cs

This is where the magic happens. But it is also disappointingly simple because UWP does the hard work.

I have created a new function that will hook the app to the events sent by the notification hub:

private async void InitNotificationsAsync()
{
var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
var hub = new NotificationHub("****-notifications-hub", "Endpoint=sb://****-notifications-ns.servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=3aqps-secret stuff=");
var result = await hub.RegisterNativeAsync(channel.Uri);
}

Of course it would be wise to obtain the connection string from a config file, I didn’t do this for the sake of simplicity.

This function is called from the OnLauched function, and that’s it.

/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
InitNotificationsAsync();
Frame rootFrame = Window.Current.Content as Frame;
// ...
}

Testing the application

Run your application (F5 or ctrl+F5). The main window will appear.

No go to the notification hub and in the overview click on “Test Send”. Set the parameters as in the screenshot and click on Send. If all goes well, you will see a toast appearing on your desktop. 

This notification is only sent to 10 users (as it is only used to verify that your app is working properly).

 

 

Deploying the app to the Microsoft Store

There are some settings to be verified before deploying your app.

  • Right-click your project > Properties to open the properties window.
  • Click the “Package Manifest” button. This is where you can set all the information about your app to make it valid for the store. There is some work to be done here, but it is all straightforward.
  • Once this is all done, you can deploy your project by Build > Deploy.  
  • Go back to the application overview in the Windows Dev Center, open Products on the left and click on your application. In the “Application overview tab” you will see the new submission under (you guessed it right) “Submissions.”
    • Click on the “Update” button next to it and follow the instructions. You can enter the price, age ratings, … here and start making money!

Sending a notification from an application

We can send notifications from any type of application, it doesn’t need to be a UWP app. Here is the Toaster class that will do the work. 

internal class Toaster
{
private const string _secret = "hub secret";
private const string _sid = "ms-app://app id";
private const string _uri = "https:// hub uri";
private const string _notificationType = "wns/toast"; // wns/toast | wns/tile | wns/badge / wns/raw
private const string _contentType = "application/xml";

public async Task PostToWns(string xml)
{
var client = NotificationHubClient.CreateClientFromConnectionString("Endpoint=sb://hdmp-notifications-ns.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=ijztkVtbIDtELzAJQKIkcwLy8Ru6d+tM3k7K/33yrA4=",
"hdmp-notifications-hub");

await client.SendWindowsNativeNotificationAsync(xml);
}
}

This will generate a toast message from the xml that is passed. The format of the xml must be correct of course. This format is documented here: https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/toast-xml-schema. 

In the store you can also find a great app, called “Notifications Visualizer”. This app allows you to edit notifications and test them locally. This allows to rapidly compose and test your messages. 

References

https://docs.microsoft.com/en-us/azure/notification-hubs/

https://docs.microsoft.com/en-us/azure/notification-hubs/notification-hubs-windows-store-dotnet-get-started-wns-push-notification 

https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/toast-xml-schema

Publishing your app to the store

 

About Gaston

MCT, MCSD, MCDBA, MCSE, MS Specialist
This entry was posted in .Net, Architecture, Azure, Cloud, Codeproject, Development and tagged , , , . Bookmark the permalink.

1 Response to Sending notifications with Corona updates to thousands of doctors

  1. Pingback: Today’s Best Practices for Migrating Windows apps to Windows on Arm | Tech Programing

Leave a comment