Notifications poussées#

Supposons que vous ayez une appli créée avec Clickable et publiée sur l’OpenStore. Mais vous souhaitez maintenant pouvoir envoyer des notifications push à vos utilisateurs. Tout d’abord, vous devez comprendre comment tout cela fonctionne :

../../_images/Diagram.png
  1. Chaque appli qui utilise les notifications push dispose d’un jeton unique. Ce jeton identifie l’utilisateur, l’appareil et l’application elle-même. Le jeton est généré par le service Push de UBports.

  2. Vous aurez besoin du jeton pour envoyer une notification push. Ceci pour que l’appli puisse l’envoyer au serveur du développeur.

  3. Avec le jeton, vous pouvez envoyer une requête HTTP au serveur Push de UBports qui transmettra la notification à l’appareil de l’utilisateur.

Faisons-le donc étape par étape.

Note

Dans l’exemple suivant, nous n’implémenterons pas de serveur. C’est vous qui gérez la communication entre votre appli et votre serveur. Veuillez informer l’utilisateur à ce sujet en fournissant une politique de confidentialité !

Préparons l’application pour les notifications push#

Implémentation du client push#

Tout d’abord, nous devons ajouter la stratégie de groupe « push-notification-client ». Votre fichier apparmor pourrait ressembler à ceci :

    {
        "policy_groups": [
            "networking",
            "push-notification-client"
        ],
        "policy_version": 16.04
    }

Dans l’étape suivante, nous devons modifier la partie Qml. Nous devons ajouter un composant pushclient :

//...

import Ubuntu.PushNotifications 0.1

//...

PushClient {
        id: pushClient
        appId: "myapp.yourname_hookname"
        onTokenChanged: console.log("👍", pushClient.token)
}

Vous devez définir le bon appId ! Si le nom de l’application dans votre fichier manifeste est myapp.yourname et que le nom du hook principal (celui qui gère le fichier .desktop) est hookname, alors l’appId est : myapp.yourname_hookname. Lorsque nous démarrons l’application, elle obtient un jeton et l’inscrit dans les journaux. Avec les journaux cliquables, nous serons en mesure de copier ce jeton à partir du terminal. Mais l’application n’est pas encore prête à recevoir une notification push. Pour cela, nous avons besoin de quelque chose appelé pushhelper !

Implémentation du pushhelper#

Le pushhelper est une partie de l’application qui va recevoir toutes les notifications push et les traiter avant de les envoyer au centre de notification du système. Il recevra un fichier json et devra produire un autre fichier json formaté correctement. Le pushhelper est séparé de l’appli. Nous avons donc besoin d’un nouveau hook dans le manifeste. Cela pourrait ressembler à ceci :

    {
        //...

        "title": "myapp",
        "hooks": {
            "myapp": {
                "apparmor": "myapp.apparmor",
                "desktop":  "myapp.desktop"
            },
            "push": {
                "apparmor": "push-apparmor.json",
                "push-helper": "push.json"
            }
        },

        //...
    }

Il est clair que nous avons maintenant besoin d’un fichier apparmor et d’un fichier executable différents. Le fichier push-apparmor.json doit uniquement contenir la stratégie de groupe push-notification-client et doit ressembler à ceci :

{
    "template": "ubuntu-push-helper",
    "policy_groups": [
        "push-notification-client"
    ],
    "policy_version": 16.04
}

push.json sert à la redirection vers le fichier exécutable :

{
    "exec": "pushexec"
}

Dans notre tutoriel, nous allons utiliser le langage python pour créer un exécutable nommé pushexec qui transmettra la notification sans rien changer :

#!/usr/bin/python3

import sys

f1, f2 = sys.argv[1:3]

open(f2, "w").write(open(f1).read())

Nous devons également ajouter ces nouveaux fichiers à CMakeLists.txt et rendre le fichier pushexec exécutable : :

[…]

install(FILES pushexec PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ DESTINATION ${DATA_DIR})
install(FILES push.json DESTINATION ${DATA_DIR})
install(FILES push-apparmor.json DESTINATION ${DATA_DIR})

[…]

L’appli est maintenant prête à recevoir et à traiter les notifications push !

Utilisation de l’API Push Service#

A ce stade, vous avez le jeton et l’application est prête à recevoir et à traiter les notifications push. Pour envoyer une notification, vous devez envoyer une requête HTTP à cette adresse : https://push.ubports.com/notify. La valeur de l’entête http content-type doit être application/json et doit aussi être au bon format. Un exemple en javascript pourrait ressembler à ceci :

var req = new XMLHttpRequest();
req.open("post", "https://push.ubports.com/notify", true);
req.setRequestHeader("Content-type", "application/json");
req.onreadystatechange = function() {
        if ( req.readyState === XMLHttpRequest.DONE ) {
                        console.log("✍ Answer:", req.responseText);
        }
}
var approxExpire = new Date ();
approxExpire.setUTCMinutes(approxExpire.getUTCMinutes()+10);
req.send(JSON.stringify({
        "appid" : "appname.yourname_hookname",
        "expire_on": approxExpire.toISOString(),
        "token": "aAnqwiFn§DF%2",
        "data": {
                "notification": {
                        "card": {
                                "icon": "notification",
                                "summary": "Push Notification",
                                "body": "Hello world",
                                "popup": true,
                                "persist": true
                        },
                "vibrate": true,
                "sound": true
                }
        }
}));

L’objet notification push#

Paramètre

Type

Description

appid

chaîne

Requis. ID de l’application qui recevra la notification,
comme décrit dans la documentation partie client.

expire_on

chaîne

Requis. Date et heure d’expiration du message, au format

token

chaîne

Requis. Le jeton identifiant utilisateur+dispositif auxquels le message est
destiné, comme décrit dans la documentation partie client.

clear_pending

booléen

Abandonne toutes les précédentes notifications en attente. Généralement en réponse
à une erreur « too-many-pending ». La valeur par défaut est false.

replace_tag

chaîne

Si il y a une notification avec le même tag, elle sera effacée avant de
mettre la nouvelle dans la file d’attente.

data

données

Un objet JSON. Le contenu du champ de données est arbitraire. On peut l’utiliser
pour envoyer tout type de données à l’appli.

données#

Paramètre

Type

Description

notification

Notification

Un objet JSON qui définit comment cette notification sera présentée.

message

objet

Un objet JSON qui est transmis tel quel à l’application via PopAll.

Notification#

Paramètre

Type

Description

tag

chaîne

Le tag de la notification push.

sound

booléen ou chaîne

Il s’agit soit d’un booléen (lecture d’un son prédéterminé), soit du
chemin vers un fichier son. L’utilisateur peut le désactiver, donc ne pas se baser
exclusivement sur celui-ci. Vide par défaut (pas de son). Le chemin est
relatif et sera recherché dans (a) le dossier .local/share/<pkgname>
de l’application, (b) les dossiers xdg standards.

vibrate

booléen ou vibrate

La notification peut contenir un champ vibration, pour déclencher le dispositif de
vibration, ce champ peut être soit un booléen (si vrai, vibre
d’une façon prédéterminée) ou un objet vibrate.

emblem-counter

Emblem-counter

Un objet JSON qui définit comment afficher le compteur
sur l’icône de l’appli.

card

Card

Un objet JSON contenant des informations sur la carte de la notification.

Card#

Paramètre

Type

Description

summary

chaîne

Requis. Un titre. La carte ne sera pas affichée si il est
manquant.

body

chaîne

Description plus longue, vide par défaut.

actions

tableau

si vide (par défaut), une bulle de notification est
non cliquable. Si vous ajoutez une URL, alors ces bulles de notifications
sont cliquables et lancent cette URL. Une utilisation possible est d’utiliser
une URL comme appid://com.ubuntu.developer.ralsina.hello
qui permet de basculer sur l’application ou de la lancer.

icon

chaîne

Une icône relative à l’événement qui est notifié. Est vide par défaut
(pas d’icône); une icône secondaire en lien avec l’application
sera également affiché, indépendamment de ce champ.

timestamp

entier

En secondes (heure Unix), pour le moment seulement utilisé pour persist.
si à zéro ou non définit, l’horodatage courant sera la valeur par défaut.

persist

booléen

Si on veut l’afficher dans le centre de notification; la valeur par défaut est false.

popup

booléen

Si on veut montrer la notification dans une bulle. Les utilisateurs peuvent le désactiver,
et peuvent aisément la manquer, donc ne pas compter exclusivement dessus.
Prend la valeur false par défaut.

Vibration#

Paramètre

Type

Description

pattern

tableau

Une liste d’entiers décrivant un motif de vibration (alternances de périodes
avec/sans vibration, en millisecondes).

repeat

entier

Nombre de répétition du motif (1 est la valeur par défaut, 0 est considéré
de la même façon que 1).

Compteur sur l’Icône#

Paramètre

Type

Description

Comptes en ligne

entier

Un nombre qui sera affiché sur l’icône de l’appli dans le lanceur.

visible

booléen

Positionné à true pour montrer le compteur, false pour le cacher.