Notifiche push#
Supponiamo di avere un’applicazione creata con Clickable e pubblicata su OpenStore. Ma ora volete essere in grado di inviare notifiche push ai vostri utenti. Prima di tutto, è necessario capire come funziona:
Ogni app che utilizza le notifiche push ha un token unico. Questo token identifica l’utente, il dispositivo e l’app stessa. Il token è generato dal servizio Push di UBports.
Il token è necessario per inviare una notifica push. Quindi l’applicazione invia il proprio token al server dello sviluppatore dell’applicazione.
Con il token è possibile inviare una richiesta HTTP al server UBports Push che inoltrerà la notifica al dispositivo dell’utente.
Esercitiamoci passo dopo passo.
Nota
Nell’esempio che segue non implementeremo un server. Anche la comunicazione tra la vostra applicazione e il vostro server dipende da voi. Si prega di informare l’utente sulla comunicazione con il server fornendo un’informativa sulla privacy!
Preparare l’app per le notifiche push#
Implementazione del PushClient#
Per prima cosa è necessario aggiungere il gruppo di criteri «push-notification-client». Il file di apparmor potrebbe essere simile a questo:
{
"policy_groups": [
"networking",
"push-notification-client"
],
"policy_version": 16.04
}
Nel passo successivo dobbiamo modificare le parti Qml. Dobbiamo aggiungere un componente pushclient:
//...
import Ubuntu.PushNotifications 0.1
//...
PushClient {
id: pushClient
appId: "myapp.yourname_hookname"
onTokenChanged: console.log("👍", pushClient.token)
}
È necessario impostare l’appId corretto! Se il nome dell’applicazione nel file manifest è myapp.yourname e il nome dell’hook principale (quello che gestisce il file .desktop) è hookname, allora l’appId è: myapp.yourname_hookname. Quando ora si avvia l’applicazione, questa otterrà un token e lo stamperà nei log. Con i log cliccabili, saremo in grado di copiare questo token dal terminale. Ma l’applicazione non è ancora pronta a ricevere una notifica push. Per questo abbiamo bisogno di qualcosa chiamato pushhelper!
Implementazione del pushhelper#
Il pushhelper è una parte dell’applicazione che riceve tutte le notifiche push e le elabora prima di inviarle al centro notifiche del sistema. Riceverà un file json e dovrà produrre un altro file json nel formato corretto. Il pushhelper è separato dall’applicazione. Quindi abbiamo bisogno di un nuovo hook nel manifest. Potrebbe essere così:
{
//...
"title": "myapp",
"hooks": {
"myapp": {
"apparmor": "myapp.apparmor",
"desktop": "myapp.desktop"
},
"push": {
"apparmor": "push-apparmor.json",
"push-helper": "push.json"
}
},
//...
}
Dovrebbe essere chiaro che ora abbiamo bisogno di un file apparmor diverso e di un file eseguibile diverso. Il file push-apparmor.json deve contenere solo il gruppo di policy push-notification-client e deve avere questo aspetto:
{
"template": "ubuntu-push-helper",
"policy_groups": [
"push-notification-client"
],
"policy_version": 16.04
}
Il file push.json serve a reindirizzare al file eseguibile:
{
"exec": "pushexec"
}
Nel nostro tutorial useremo python per creare un eseguibile chiamato pushexec che inoltrerà la notifica senza modificare nulla:
#!/usr/bin/python3
import sys
f1, f2 = sys.argv[1:3]
open(f2, "w").write(open(f1).read())
È inoltre necessario aggiungere questi nuovi file a CMakeLists.txt e rendere eseguibile pushexec:
[…]
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})
[…]
Ora l’applicazione è pronta a ricevere ed elaborare le notifiche push!
Utilizzo dell’API del servizio Push#
Ora si dispone del token e l’applicazione è pronta a ricevere ed elaborare le notifiche push. Per inviare una notifica, occorre inviare una richiesta HTTP a questo indirizzo: https://push.ubports.com/notify Il tipo di contenuto deve essere application/json e deve essere nel formato corretto. Un esempio in javascript potrebbe essere questo:
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
}
}
}));
Oggetto di notifica push#
Parametro |
Tipo |
Descrizione |
---|---|---|
appid |
stringa |
Richiesto. ID dell’applicazione che riceverà la notifica,
come descritto nella documentazione del lato client.
|
scadere_il |
stringa |
Richiesto. Data/ora di scadenza per questo messaggio, in
|
token |
stringa |
Richiesto. Il token che identifica l’utente+dispositivo a cui il messaggio è
diretto, come descritto nella documentazione lato cliente.
|
clear_pending |
bool |
Scarta tutte le notifiche in sospeso precedenti. Di solito in risposta a
ottenere un errore «too-many-pending». Predefinisce il falso.
|
sostituire_tag |
stringa |
Se c’è una notifica in sospeso con lo stesso tag, cancellalo prima
in coda a questo nuovo.
|
dati |
Dati |
Un oggetto JSON. Il contenuto del campo dati è arbitrario. Si può usare
per inviare qualsiasi dato all’applicazione.
|
Dati#
Parametro |
Tipo |
Descrizione |
---|---|---|
Notifica |
Notifica |
Un oggetto JSON che definisce come verrà presentata questa notifica. |
messaggio |
oggetto |
Un oggetto JSON che viene trasmesso come-è all’applicazione tramite PopAll. |
Notifica#
Parametro |
Tipo |
Descrizione |
---|---|---|
etichetta tag |
stringa |
Il tag della notifica push.
|
suono |
bool o stringa |
Si tratta di un booleano (riprodurre un suono predeterminato) o dell’elemento
percorso di un file audio. L’utente può disabilitarlo, quindi non fare affidamento su
esclusivamente su di esso. Il valore predefinito è vuoto (nessun suono). Il percorso è
relativo, e sarà cercato in (a) dell’applicazione
.local/share/<pkgname> , e (b) le directory xdg standard. |
vibrare |
bool o Vibrare |
La notifica può contenere un campo di vibrazione, provocando un effetto tattile
feedback, che può essere un booleano (se vero, fa vibrare un
modo predeterminato) o un oggetto Vibrare.
|
emblema-contatore |
Emblema-contatore |
Un oggetto JSON, che definisce come visualizzare l’emblema
contatore.
|
carta |
Carta |
Un oggetto JSON con informazioni sulla carta di notifica.
|
Carta#
Parametro |
Tipo |
Descrizione |
---|---|---|
sommario |
stringa |
Richiesto. Un titolo. La carta non verrà presentata se questo è
mancante.
|
corpo |
stringa |
Testo più lungo, predefinito vuoto.
|
azioni |
array |
Se vuoto (il predefinito), una notifica bolla è
non cliccabile. Se si aggiunge un URL, allora le notifiche a bolla
sono cliccabili e lanciano quell’URL. Un uso di questo tipo è l’utilizzo di
un URL come
appid://com.ubuntu.developer.ralsina.hello che passerà all’applicazione o la avvierà.
|
icona |
stringa |
Un’icona relativa all’evento notificato. Predefiniti per
vuoto (non icona); icona secondaria relativa all’applicazione
sarà mostrato anche, indipendentemente da questo campo.
|
timestamp |
integro |
Secondi dall’epoca unix, utilizzato solo per persistere per ora.
Se zero o unset, si predefinisce il timestamp corrente.
|
persistere |
bool |
Se mostrare in centro di notifica; default a falso.
|
popup |
bool |
Che si mostri in una bolla. Gli utenti possono disattivare questo, e possono
facilmente perdere, quindi non fare affidamento su di esso esclusivamente. Predefiniti
a false.
|
Vibrazione#
Parametro |
Tipo |
Descrizione |
---|---|---|
pattern |
array |
Un elenco di interi che descrive un modello di vibrazione (durata dell’alternanza
tempi di vibrazione/senza vibrazioni, in millisecondi).
|
ripeti |
integro |
Numero di volte che il modello deve essere ripetuto (default a 1, 0 è il
come 1).
|
Emblema-Contatore#
Parametro |
Tipo |
Descrizione |
---|---|---|
conto |
integro |
Un numero da visualizzare sull’icona dell’applicazione nel launcher. |
visibile |
bool |
Impostare a true per mostrare il contatore, o falso per nasconderlo. |