Dynamisez vos notifications push Azure pour Cordova

Apache_Cordova1

Comme promis, voici le troisième et dernier article sur mon retour d'expérience de l'intégration des notifications push Azure dans le cadre d'un projet Cordova pour Android, IOS et Windows 8.

Cette fois, je vais parler des "tags" et du paramétrage de notifications afin de rendre votre push un peu plus dynamique.

Pour démarrer

Si vous n'avez pas de projet Cordova ou que votre projet Cordova n'est pas configuré pour fonctionner avec le push Azure, je vous encourage à parcourir mes deux précédents articles :  ici et ici où vous trouverez toutes les étapes nécessaires pour démarrer avec cet article.

Utilisations des tags

Par défaut une notification n'a pas de tags et elle est reçue par toutes les personnes étant abonnées au hub Azure.Les tags permettent de cibler vos destinataires, il suffit au moment de l'enregistrement du mobile auprès de la plateforme Azure de donner une liste de mots auxquels votre utilisateur sera notifié. Cela permet par exemple de gérer des préférences de notifications pour des actualités sur lesquelles l'utilisateur souhaite être informé. Côté plateforme Azure il s'agit d'ajouter un ou des mots clés pour donner la règle de diffusion. A cette page "https://msdn.microsoft.com/en-us/library/azure/dn530749.aspx" vous trouver les différentes combinaisons possibles pour associer un tag à vos notifications.

Modification du plugin Cordova

Le plugin Cordova pour les notifications Azure "https://github.com/sgrebnov/cordova-plugin-azure-notificationhub" que nous avons utilisé dans les deux premiers articles ne permet pas de communiquer à la plateforme Azure les tags auxquels les utilisateurs doivent être abonnés. Pour ma part j'ai fait un fork de ce plugin, ce qui m'a permis d'une part d'utiliser les tags mais également :

  • [IOS] :  mise à jour de la librairie "Azure Mobile Services" pour IOS avec sa version 64bits, problème évoqué dans le précédent article
  • [IOS] : possibilité d'interagir avec les notifications reçues quand l'application est en tâche de fond
  • [WP8] : prise en charge de la propriété "param" pour le passage de paramètres aux notifications

En vous positionnant à la racine de votre projet, il vous faut donc désinstaller l'ancien plugin :

cordova plugin remove msopentech.azure.NotificationHub

Et installer le fork

cordova plugin add https://github.com/dboujot/cordova-plugin-azure-notificationhub.git

ATTENTION!

Pour IOS n'oubliez pas de modifier le fichier "AppDelegate.m" comme indiqué dans la documentation "https://github.com/dboujot/cordova-plugin-azure-notificationhub#platform-quirks'.

Côté application Cordova

Maintenant que vous avez modifié votre plugin pour pouvoir transmettre les tags à votre plateforme Azure, il faut communiquer les tags au plugin depuis votre application. C'est très simple, quand vous faites l'appel pour enregistrer le mobile de votre utilisateur sur votre hub Azure il suffit de donner une chaîne de caractères contenant  les noms des tags séparés par des points virgule :

hub.registerApplicationAsync('sport;concert').then(
	function (result) 
	{
		$scope.registrationOk = result.registrationId;
		$scope.$apply();
	},
	function(error)
	{
		$scope.registrationKo = error;
		$scope.$apply();
	}
);

Ici notre utilisateur ne recevra que les notifications qui seront taguées "sport" ou "concert" et toutes les autres ne lui seront pas transmises.

Si vous souhaitez mettre à jour les tags de l'abonnement il faut d'abord faire un dés-enregistrement puis un enregistrement :

hub.unregisterApplicationAsync().then(
	function(result) {
		hub.registerApplicationAsync('traffic;meteo').then(
			function (result) 
			{
				$scope.registrationOk = result.registrationId;
				$scope.$apply();
			},
			function(error)
			{
				$scope.registrationKo = error;
				$scope.$apply();
			}
		);
	},
	function(error) {
		console.log("UnRegistration failed: " , error);
	});

Votre abonnement est modifié.

Test du tag

Pour voir que tout fonctionne bien, rendez-vous sur votre console Azure dans l'écran "DEBOGUER". Quelque soit la plateforme que vous testez, il vous suffit dans l'option "diffusion aléatoire" de cliquer sur "inactif", le champ "envoyer à la balise" devient actif et vous pouvez soit donner un simple nom de tag de diffusion par exemple "sport" ou une expression de tag comme décrit sur cette page "https://msdn.microsoft.com/en-us/library/azure/dn530749.aspx". Sachez que si vous envoyez une notification en laissant l'option "diffusion aléatoire" "actif" tout le monde la recevra même si les utilisateurs ne sont abonnés qu'à certains tags.

Cette fonctionnalité est très simple à mettre en oeuvre et permet de créer des systèmes de notifications personnalisés, je vous laisse le soin de consulter les tutoriaux de la plateforme Azure qui donne des cas concrets d'utilisations.

Utilisations des paramètres

Là on aborde un sujet qui n'est pas vraiment expliqué sur le site de la plateforme Azure, mais qui est pourtant fort utile : c'est la possibilité de transmettre des paramètres dans le contenu de votre notification. Une utilisation concrète c'est  d'accéder directement à une vue de votre application Cordova pour lire un article. Comme indiqué précédemment dans cet article, dans mon fork du plugin Cordova Azure, j'ai modifié l'implémentation de la version WP8 pour pouvoir communiquer mes paramètres via un attribut nommé "param".

Côté Hub Azure

Cette fois je commence par les impacts du point de vue de vos notifications envoyées par la plateforme Azure. En fonction de la cible de votre notification la structure de cette dernière change :

{"data":
	{"message":"Le message de ma notification", 
	"title": "Notification avec paramètres",
	"monParam1" : 0, 
	"monParam2" : "Un petit message en plus"
	}
}
Pour android
{"aps":{"alert":{
				"title" : "Notification avec paramètres", 
				"body" : "Le message de ma notification"},
				"sound" : "default", 
				"monParam1" : 0, 
				"monParam2" : "Un petit message en plus"
	}
}
Pour IOS
<?xml version="1.0" encoding="utf-8"?>
	<wp:Notification xmlns:wp="WPNotification">
	<wp:Toast>
	<wp:Text1>Notification avec paramètres</wp:Text1>
	<wp:Text2>Le message de ma notification</wp:Text2>
	<wp:Param>?monParam1=0&amp;monParam2=Un petit message en plus</wp:Param>
	</wp:Toast>
</wp:Notification>
Pour WP8

Vous avez les trois versions d'ajouts de paramètres et il n'y a rien de plus à faire côté Azure.

Côté application Corodova

Autant la partie Azure était simplissime, autant la version application mobile demande un peu plus de boulot, surtout qu'il faut une implémentation différente par plateforme.

Pour Android

Dans mon premier article j'ai utilisé un deuxième plugin, PushPlugin, pour permettre à l'application de recevoir les notifications quand l'application est arrêtée ou en tâche de fond. Si vous ne l'avez pas dans votre projet Cordova, utilisez la commande suivante à la racine de votre projet :

cordova plugin add https://github.com/dboujot/PushPlugin.git

Dans votre contrôleur AngularJS, il faut configurer l'objet pushNotification pour capter les notifications :

pushNotification.register(
	notificationHandler.successHandler,
	notificationHandler.errorHandler, {
		"senderID": AZURE_GCM_KEY,
		"ecb": "notificationHandler.onNotification"
	}
);

La variable AZURE_GCM_KEY contient votre clé google, obtenue lors de la configuration de votre projet de Google (cf mon premier post dans la rubrique "Mise en place du Hub Azure").

La chaîne "onNotification" correspond au nom de la fonction Javascript que le  plugin de push appellera à chaque événement de notification.

onNotification: function(e) {        
	switch (e.event) {
		case 'registered':
			console.log("registered");
			if (e.regid.length > 0) {
				console.log("regID = " + e.regid);
			}
			break;

		case 'message':
			// if this flag is set, this notification happened while we were in the foreground.
			// you might want to play a sound to get the user's attention, throw up a dialog, etc.
			if (e.foreground) {
				console.log("foreground");
			} else { // otherwise we were launched because the user touched a notification in the notification tray.
					var params = (typeof e.payload === 'object') ? e.payload : JSON.parse(e.payload);			
					var id = e.from;
					var monParam1 = parseInt(params.monParam1);
					var monParam2 = parseInt(params.monParam1)
					console.log("mon message en paramètre ", monParam2);
					this.state.go('article.details', {
					id: monParam1
					});

			}
			break;

		case 'error':
			console.log('ERROR -> MSG:' + e.msg + '');
			break;

		default:
			console.log('EVENT -> Unknown, an event was received and we do not know what it is');
			break;
	}
}
Exemple d'implémentation de la fonction onNotification

Cette fonction doit être accessible depuis le plugin de Push, je vous conseille de la déclarer en dehors de votre contrôleur AngularJS.

Pour IOS

Pour IOS nous allons utiliser encore un autre plugin pour créer des notifications locales. Pourquoi un plugin pour des notifications locales? Pour répondre au problème que nous avons constaté dans mon deuxième article qui était que les notifications ne sont pas visibles quand l'application est en cours d'utilisation.

Exécutez cette commande à la racine de votre projet

cordova plugin add https://github.com/katzer/cordova-plugin-local-notifications.git

Dans votre contrôleur AngularJS, il faut modifier le listerner "onPushNotificationReceived" :

hub.onPushNotificationReceived = function(notification) {
	console.log("onPushNotificationReceived: ", notification);                        
	if (!notification.fromForeground && !notification.ColdStart) 
	{
		notification.fromForeground = true;
		sendLocalNotification(notification);
	} else if (notification.ColdStart == true){

		var monParam1 = notification.monParam1;
		var monParam2 = notification.monParam1;

        console.log("click sur la notification ", notification);
		console.log("mon message en paramètre " , monParam2);

        this.state.go('ma_vue', {
            id: monParam1
        });

	} else {
		console.log("problème sur la réception des notifications azure.");
	}
};

Ce nouveau listener écoute les notifications en background et celles quand l'application est en cours d'utilisation "foreground". Dans ce dernier cas nous appelons une nouvelle méthode qui va déclencher  une notification locale "sendLocalNotification".

sendLocalNotification: function(notification) {        
	var params = {};
	var message = '';

	if (notification.alert && notification.alert.body) {
		message = notification.alert.body;
	} else if (notification.alert) {
		message = notification.alert;
	}
	params.monParam1 = parseInt(notification.monParam1 || 0);
	params.monParam2 = notification.monParam2 || '';

	var showNotification = function () {

		notificationHandler.localNotification.schedule({
			id: notifId, // A unique id of the notification            
			message: message, // The message that is displayed
			title: null, //sur ios la notification prend pour titre le nom de l'application
			json: params, // Data to be passed through the notification
			autoCancel: true
		}, function (data) {
			console.log('sendLocalNotification callback', data);
		});

	};

	this.localNotification.isPresent(notifId, function (present) {
		if (present) {
			notificationHandler.localNotification.clear(1, function () {
				showNotification();
			});
		} else {
			showNotification();
		}
	});

}

Votre application IOS est maintenant capable d'intercepter les notifications dans les différents stades de fonctionnement, d'afficher une notification et de récupérer les paramètres de cette dernière.

Pour Windows Phone

Enfin l'implémentation pour Windows Phone.

Premièrement si vous souhaitez que votre application s'ouvre directement sur une vue particulière quand l'utilisateur effectue un tap sur une notification, vous allez devoir modifier le fichier "MainPage.xaml.cs" qui se trouve dans le répertoire "platforms/wp8".

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            try
            {
                var queryString = this.NavigationContext.QueryString;
                if (queryString != null 
                    && queryString.Count > 0
                {
                    var monParam1 = queryString["monParam1];
                    this.CordovaView.StartPageUri = new Uri("//www/index.html#/ma_vue/" + monParam1, UriKind.Relative);
                }
            }
            catch (KeyNotFoundException ex) {
                Debug.WriteLine("OnNavigatedTo Error = " + ex);
            }
        }

Cette surcharge de méthode récupère les paramètres de la notification sous forme de querystring et change la vue d'ouverture de l'application pour accéder directement à une page précise.

Quand j'ai utilisé la solution Azure avec Cordova sur Windows Phone 8, les notifications ne s'affichaient pas quand l'application était en premier plan en cours d'utilisation et le plugin de NotificationLocal de Cordova ne fonctionnait pas pour Windows Phone.

Après un petit passage sur le GitHub du projet https://github.com/katzer/cordova-plugin-local-notifications il semble que la situation ait évolué et qu'une version stable soit disponible depuis peu.

Conclusion

Ceci clôture ma série d'articles sur mon retour d'expérience du push Azure avec Cordova. Nous avons balayé les grandes fonctionnalités qu'offre la plateforme Azure. L'implémentation avec Cordova n'est pas toujours des plus triviale, tout dépend du nombre de plateformes ciblées par votre application et des besoins d'utilisations. Mais si vous avez quelques connaissances en développement natif vous pouvez arriver à vos fins sans trop de difficulté.

En espérant que cette série d'articles vous ait plu, et n'hésitez pas à faire des commentaires, poser des questions et apporter des corrections. Le contenu n'en sera que plus complet.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.