Les Push Notifications des différentes plateformes mobiles (Android, iOS, Windows 8, Windows Phone 8) sont un excellent moyen de fidéliser les utilisateurs d’applications mobiles. Certaines applications ne sont ouvertes qu’à travers ce biais, lorsqu’un message est broadcasté à l’ensemble des utilisateurs, ou que celui-ci est ciblé en fonction des préférences de tel ou tel groupe d’utilisateurs. Voici quelques exemples :

  • Application d’actualités publiant une alerte information à tous les utilisateurs intéressés par les actualités sportives
  • Application d’une municipalité désirant informer les habitants d’une période de stationnement gratuit

D’autres applications se basent sur ce type de fonctionnalités pour délivrer des messages hautement personnalisés, pour tels ou tels utilisateurs. Voici d’autres exemples :

  • Application bancaire informant à un client que ses relevés mensuels sont disponibles sur son portail
  • Application d’une compagnie aérienne informant un usager d’un retard sur son prochain vol

Les apports fonctionnels sont donc indéniables mais les problématiques techniques associées ne sont malheureusement pas triviales.

En effet, la multiplication des familles de périphériques mobiles vient avec la multiplication des plateformes de notifications propres à chacune de ces familles. On parle de Platform Notification Systems ou PNS, dont les représentants principaux sont aujourd’hui :

  • GCM : Google Cloud Messaging pour Android
  • APNS : Apple Push Notification Service pour iOS et Mac OS
  • WNS : Windows Push Notification Service pour Windows 8
  • MPNS : Microsoft Push Notification Service pour Windows Phone

Malheureusement, chaque plateforme vient avec son API, et avec des capacités différentes (mise à jour d’une tuile, affichage d’un toast, utilisation d’un badge, …)

De plus, la plupart de ces plateformes ne supportent pas le broadcasting (envoi simultané à plusieurs périphériques). Envoyer un message à plusieurs milliers, voir dizaines de millions de périphériques requiert autant d’appels à ces plateformes. Pouvoir le faire en un temps relativement court implique donc des infrastructure techniques conséquentes implémentant une parallélisation efficace. Cela implique également le besoin de stocker l’ensemble des handles (ou liens) vers tous ces périphériques, avec potentiellement la relation avec différentes catégories de notifications, ainsi que la maintenance de cette liste nécessaire pour gérer les périphériques qui ne sont plus utilisés.

Enfin, plus le besoin fonctionnel est poussé (personnalisation des messages en fonction de la langue de l’utilisateur, envoi ciblé à telle ou telle catégorie d’utilisateur, envoi ciblé à un utilisateur en particulier, …), plus le code nécessaire à l’envoi de ces notifications est complexe.

Fonctionnalités de Windows Azure Notification Hubs

Windows Azure Notification Hubs, disponible en version finale depuis le 12 août 2013, simplifie énormément le travail nécessaire à la mise en place de cette mécanique, en fournissant une plateforme centralisée communiquant directement avec les PNS majeurs, hautement scalable (utilisable pour quelques centaines à plusieurs centaines de millions de notifications), performant (ordre de grandeur de quelques secondes pour plusieurs millions de notifications) et fournissant un certain nombre de fonctionnalités que le développeur n’a ainsi plus à gérer comme le broadcast, la catégorisation et la personnalisation des notifications.

Voici les grandes étapes de sa mise en place. Vous trouverez ci-dessous des liens vers des tutoriaux détaillés pour aller plus loin.

image

Création du service et configuration des PNS

A travers le portail Windows Azure, la première chose à faire est de créer un nouveau concentrateur de notification (Notification Hub).

image_thumb3

Ce service sera ensuite disponible dans la section "Service Bus" du portail, dans un espace de nom qui aura été créé par la même occasion.

Dans l’onglet "Configurer" de votre service (benjattest dans mon cas), vous pouvez configurer les différents PNS que vous souhaitez utiliser en fonction des applications que vous avez développé.
Vous devez au préalable retrouver ces éléments dans les différents portails des PNS concernés. Pour Windows 8 par exemple, cela se passe sur le Windows Dev Center, où se trouve le SID du package de votre application et la question secrète associée.

image_thumb7

Enregistrement du handle propre à chaque périphérique

Afin de pouvoir recevoir des notifications du PNS correspondant à chaque périphérique, le périphérique doit au préalable récupérer un handle du PNS en question (Notification channel pour une application Windows 8, token pour une application iOS, …). Cette étape est donc propre à chaque plateforme mais le principe est similaire pour toutes.

Une fois le handle récupéré, vous pouvez l’enregistrer sur votre nouveau service Notification Hub, qui se chargera de maintenir la liste pour vous.
Vous devez pour cela utiliser le nom de votre concentrateur (<hub name> ci-dessous) et la chaine de connexion associée (<connection string> ci-dessous), informations disponibles dans l’onglet “Tableau de bord” de votre service sur le portail Windows Azure.

Deux choses importantes sont à noter :

  • Vous devez utiliser la chaine de connexion "DefaultListenSharedAccessSignature" dans cette étape. En effet, elle donne seulement l’autorisation d’enregistrer des périphériques et peut donc être déployée sans risque avec votre application pour des notifications non sensibles.
  • Les handles des différents services expirent au bout d’un certain temps, et il est donc nécessaire de les enregistrer régulièrement, généralement au lancement de l’application.
    Le service Windows Azure Notification Hub s’occupe pour vous d’effectuer le nettoyage nécessaire au maintien d’une liste à jour. Vous n’avez donc qu’à gérer les enregistrements.

Voici quelques exemples :

Enregistrement d’un périphérique Android

via le Android Notification Hub SDK

NotificationHub hub = new NotificationHub("<hub name>", "<connection string>", context);
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
String regid = gcm.register(SENDER_ID);
hub.register(regid);

Enregistrement d’un périphérique iOS

via le Service Bus iOS Preview SDK

(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)
  deviceToken {
    
    SBNotificationHub* hub = [[SBNotificationHub alloc] initWithConnectionString:
      @"<connection string>" notificationHubPath:@"mynh"];
    [hub registerNativeWithDeviceToken:deviceToken tags:nil completion:^(NSError* error) {
        if (error != nil) {
            NSLog(@"Error registering for notifications: %@", error);
        }
    }];
}

Enregistrement d’un périphérique Windows 8

via le package Nuget "Windows Azure Service Bus managed client library for Windows 8 and Windows Phone 8" ou le dossier suivant Windows Store SDK

var hub = new NotificationHub("<hub name>", "<connection string>");
var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync(); 
await hub.RegisterNativeAsync(channel.Uri);

Envoi d’une notification et passage à l’échelle

Une fois les périphériques de vos utilisateurs enregistrés dans votre Notification Hub Windows Azure, vous pouvez commencer à broadcaster des notifications à l’ensemble de ceux-ci, via l’appel à seulement une méthode du SDK Notification Hub par plateforme supportée, quelque soit le nombre de périphériques concernés.

Cette opération est généralement réalisée dans une application dédiée, connectée ou non à votre système d’information. A l’heure actuelle, le seul SDK disponible est en .NET (via le package Nuget "Windows Azure Service Bus"). Les opérations sont également disponibles en REST, donc sont accessibles à toute application pouvant communiquer en HTTP.

Voici un exemple, broadcastant tour à tour les périphériques Windows, iOS et Android :

var hubClient = NotificationHubClient.CreateClientFromConnectionString("<connection string>", "<hub name>"); 
// Broadcast périphériques Android 
var toastForAndroid = @"<notification payload>"; hubClient.SendGcmNativeNotificationAsync(toastForAndroid); 
// Broadcast périphériques iOS 
var toastForIos = @"<notification payload>"; hubClient.SendAppleNativeNotificationAsync(toastForIos); 
// Broadcast périphériques Windows 
var toast = @"<notification payload>"; hubClient.SendWindowsNativeNotificationAsync(toast);

Le <hub name> est le même que celui que vous avez utilisé du côté applicatif. La chaine de connexion <connection string> est par contre différente. Il s’agit de la chaine ayant tous les droits sur votre service et qui est donc une information sensible à ne pas utiliser dans vos applications mobiles. Elle est disponible dans le portail Windows Azure et porte le nom DefaultFullSharedAccessSignature.

Le champ <notification paylod> est à remplacer par la chaine de caractères décrivant la notification que vous souhaitez utiliser en fonction du type de périphériques. Par exemple, pour afficher un Toast contenant une image et du texte sur Windows, vous pouvez utiliser la chaine de caractères suivante décrivant la notification souhaitée :

<toast>
<visual>
<binding template="ToastImageAndText01">
<image id="1" src="World" />
<text id="1">Hello</text>
</binding>
</visual>
</toast>

Voici un autre exemple dans le cas de l’envoi d’une une notification au format texte à un périphérique iOS :

{ "aps": { "alert" : "Hello!" } } 

Au fur et à mesure du déploiement de vos applications, le nombre de périphériques enregistrés va normalement augmenter, et il sera nécessaire de choisir la bonne formule pour votre Notification Hub.
Trois formules vous sont proposées, avec les caractéristiques suivantes à ce jour :

  • Le tiers Gratuit vous permet d’enregistrer 500 périphériques, pour 100 000 opérations par mois (une opération consistant à l’envoi d’une notification ou l’appel à une méthode de l’API du service).
    Cette formule est parfaite lors de la phase de développement de votre application. A noter qu’il n’y a pas d’engagement de la part de Microsoft sur le niveau de service associée à cette formule gratuite.
  • Le tiers De base vous permet d’enregistrer 100 000 périphériques, pour 1 million d’opérations par mois.
  • Le tiers Standard fonctionne différemment, en vous permettant de définir un nombre d’unités souhaitées.
    Pour chaque unité, vous pouvez enregistrer 100 000 périphériques et effectuer 5 millions d’opérations. Il est possible d’activer entre 1 et 50 unités dans le même service, et ainsi d’envoyer par exemple plus de 200 millions de notifications par mois.
    L’avantage de ce découpage en unité est de pouvoir mettre en place un mécanisme de mise à l’échelle, en indiquant le nombre minimal (ou réservé) d’unités, afin de garantir une capacité minimale, et en indiquant un nombre maximal d’unités que le système peut utiliser pour absorber la charge que vous lui fournissez. Voici un aperçu de la configuration de ce mécanisme dans le portail, onglet "Mettre à l’échelle” :

image31_thumb

Utilisation des catégories

Plutôt que d’envoyer la même notification à l’ensemble des utilisateurs, il est également possible de cibler un groupe de périphériques donnés.

Une application d’actualités peut ainsi publier une alerte à tous les utilisateurs intéressés par les actualités sportives par exemple.
Autre exemple, une application d’alerte Météo peut ainsi envoyer des alertes aux utilisateurs habitant une région spécifique.

Tout la mécanique nécessaire à la mise en place de ce ciblage est incluse dans Windows Azure Notification Hub. Il devient donc très simple de mettre en place ce genre de fonctionnalité.

Pour cela, au moment où le handle d’un périphérique est enregistré, il suffit de spécifier un certain nombre de mots clés, ou "tags", pour lesquels le périphérique doit être enregistré. Il est nécessaire pour cela de passer par l’autre signature de la méthode RegisterNativeAsync() de l’objet NotificationHub, en lui passant un tableau de chaines de caractères correspondant aux mots clés, comme dans l’exemple suivant :

await notificationHub.RegisterNativeAsync(channel.Uri, new string[] { "Sport", "Musique" });

Au moment de l’envoi de la notification, il est ainsi possible de spécifier à quel mot clé cette notification correspond et le concentrateur s’occupera de cibler les bons périphériques, donc les bons utilisateurs. De la même façon que pour l’enregistrement, il faut passer par l’autre signature des différentes méthodes Send(), comme dans l’exemple suivant pour une notification Windows 8 :

hubClient.SendWindowsNativeNotificationAsync(toast, "Wailers");

image_thumb[1]

Le nombre de catégories utilisables n’est pas limité. Il est donc tout à fait possible de créer une catégorie par utilisateur si besoin, en soumettant un identifiant utilisateur comme mot clé.
A noter que ce scénario requiert potentiellement plus d’effort si vous souhaitez restreindre l’enregistrement à des utilisateurs authentifiés, pour pouvoir leur envoyer des informations non publiques. En effet, la chaine de connexion Windows Azure Notification Hub utilisée pour enregistrer des appareils n’implémente aucun mécanisme de sécurité, ce qui est problématique pour envoyer des informations sensibles à tel ou tel utilisateur.
Dans ce cas, l’enregistrement d’un périphérique doit être réalisé via un back-end implémentant un mécanisme d’authentification, et non depuis l’application cliente directement.

Utilisation des modèles

Windows Azure Notification Hub permet également de répondre à deux besoins importants : la possibilité de personnaliser le format des messages en fonction de différents critères comme la langue de l’utilisateur ou le format des données (devise, format de date ou de mesures, …) ainsi que la possibilité d’envoyer une notification à l’ensemble des périphériques, sans avoir besoin d’utiliser un format de notification en fonction du type de périphérique, et ainsi rendre votre application d’envoi de notifications indépendante du format de présentation.

Pour cela, lors de l’enregistrement d’un périphérique, il est possible de spécifier en plus des éventuelles catégories le format de notification attendu, via l’utilisation d’un modèle ou "template". Cela se réalise en utilisant la méthode RegisterTemplateAsync() en lieu et place de la méthode RegisterNativeAsync().

Voici un exemple d’enregistrement utilisant un modèle pour localiser un message en fonction de la langue, pour un toast Windows 8. Notez le champ $(txt_fr), qui sera utilisé lors de l’envoi de la notification pour choisir quel message doit être envoyé.

// Définition du modèle 
var template = @"<toast><visual><binding template=""ToastImageAndText01""> <image id=""1"" src=""World"" /><text id=""1"">$(txt_fr)</text> </binding></visual></toast>";
// Enregistrement du handle
var hub = new NotificationHub("<hub name>","<connection string>");
var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
await hub.RegisterTemplateAsync(channel.Uri, template, "nom_du_template");

Pour une application iOS, d’un utilisateur anglophone, le modèle équivalent pourrait ressembler à cela :

{ "aps": { "alert": "$(txt_en)" } } 

Côté serveur, vous devez donc commencer par construire les différents messages en fonction des différentes valeurs possibles pour le champ utilisé. Une fois ces différents messages stockés dans un dictionnaire, vous pouvez envoyer une demande d’envoi de notifications au concentrateur, sans avoir besoin d’effectuer un appel par PNS, avec le format spécifique à chaque type de périphériques. En effet, les différences ont déjà été gérées dans chaque modèle au moment de l’enregistrement.

Voici la partie serveur pouvant correspondre à l’exemple utilisé ci-dessus :

var txt = new Dictionary<string, string>() { {"txt_fr", "Bonsoir"}, {"txt_en", "Hello"} };
var hubClient = NotificationHubClient.CreateClientFromConnectionString("<connection string>", "<hub name>");
hubClient.SendTemplateNotificationAsync(txt);

Pour aller plus loin, ce mécanisme de modèles peut être combiné au mécanisme des mots clés pour une personnalisation vraiment évoluée.

Différences avec la fonctionnalité Notifications de Windows Azure Mobile Services

Windows Azure Mobile Services, un autre service de Windows Azure, vient également avec la possibilité d’envoyer des notifications à des périphériques mobiles.
Les principales différences entre ces deux possibilités sont les suivantes :

  • Windows Azure Notification Hubs peut passer à l’échelle afin d’envoyer des dizaines de millions de notifications par mois.
  • Windows Azure Mobile Services gère pour vous la liste des handles des périphériques concernés et vous permet d’utiliser les catégories et les modèles.
  • Windows Azure Mobile Services sera donc approprié pour envoyer des notifications à des utilisateurs spécifiques, en fonction d’évènements déclenchés lors de l’utilisation du stockage Windows Azure Mobile Services

Ressources complémentaires

Vous voulez tester par vous-mêmes et vous n’avez pas encore de compte Windows Azure ? Ouvrez un compte de test gratuit: 150 € de ressources pendant 1 mois.

Pour aller plus loin dans la découverte puis dans la mise en place du service Windows Azure Notification Hub, nous vous conseillons les ressources suivantes :

Que pensez-vous de Windows Azure Notification Hub ? Va t-il vous aider dans le développement de vos applications mobiles ?

Benjamin (@benjiiim