Caliopen
Notifications
Objectif de ce document :
Décrire le format des messages échangés entre le frontend et le backend
Décrire le protocole utilisé pour l'échange de ces messages
Lister les fonctionnalités de notification exposées par le backend pour le frontend (API)
Décrire le mode de gestion de la file d'attente des notifications côté backend
Format des messages de notification :
format de la réponse retournée par le backend sur /api/v2/notifications :
notifications:
- emitter: string // backend entity that's emitting the message. (contacts facility, email facility, etc.)
notif_id: string // universally unique id to unambiguously identify a notification message.
type: string // a single word to describe message's type and give indication of importance level (event, info, feedback, warning, teaser, error, alert, etc.)
reference: string // (optional) a reference number previously sent by frontend to link current notification to a previous action/event.
timestamp: int // unix timestamp at which backend created the notification
body: string // could be a simple word or a more complex structure like a json, depending of the notification. The structure can include other notifications, see new_message examples.
Les messages de notification comportent des 'headers' et un 'body'.
les 'headers' (emitter
, notif_id
, type
, references
) permettent d'identifier la notification et de la classifier.
le body
comporte le message/payload de la notification
le header emitter
sert à identifier le composant du backend qui a émis la notification.
le header type
permet d'identifier immédiatement le type de notification : event, info, feedback, warning, teaser, error, alert, etc.
le header reference
pourrait servir à lier une notification à un évènement ou une action initiée par le front afin que celui identifie le feedback du backend sur le déroulement de cette action.
le header timestamp
est le timestamp unix du moment où la notification a été créée par le backend. Il pourrait permettre au frontend d'indiquer une fourchette horaire lors du GET /v2/nofications?from=00000000&to=000000000
Exemples de notifications :
notification générique de réception de messages :
total: 1
notifications:
- emitter: <notifier>(imap_worker|…)
notif_id: xxxxx-xxxxx-xxxxx
type: new_message
timestamp: 1518691674517
body:
size: <nb>
elements:
- body:
message_id: xxxxxx-xxxxx-xxxxx
discussion_id: yyyyy-yyyy-yyyyy
notification de réception d'un grand nombre de message :
{
"total": 1,
"notifications": [
{
"body": { "size": 646 },
"emitter": "imap_worker",
"notif_id": "e23fdf95-9750-11e9-a402-0242ac13000a",
"type": "new_message"
}
]
}
notification de fin d'import de vCards :
le frontend a initié un import avec un POST sur /v1/imports
lors de son prochain call sur GET /v2/notifications, il pourrait recevoir la notification suivante :
notifications:
- emitter: contacts
notif_id: xxxxxx-xxxxx-xxxxx
type: import_result
reference: xxxxxxxxx // could be a hash of the initial call to the API (POST /v1/imports + timestamp (+ headers ?))
timestamp: 1518691674517
body:
- body:
contact_id: xxx
status: imported
- body:
contact_id: yyy
status: error
error_msg: "something went wrong"
- body:
contact_id: zzz
status: ignored
notification d'échec d'envoi de email :
l'utilisateur a envoyé un email (POST /messages/{message_id}/actions
)
lors de son prochain call sur GET /v2/notifications, le frontend pourrait recevoir la notification suivante :
notifications:
- emitter: email-broker
notif_id: xxxxx-xxxxx-xxxxx
type: warning
reference: xxxxxx-xxxxx-xxxx // uuid of email sent
timestamp: 1518691674517
body:
warning: sending email failed
code: 23
message: MTA timeout
notification que l'index est à jour (suite à create/update de document)
l'utilisateur a modifié un contact (PATCH /contacts/{contact_id}
)
lors de son prochain call sur GET /v2/notifications, le frontend pourrait recevoir la notification suivante :
notifications:
- emitter: contacts
notif_id: xxxxx-xxxxx-xxxxx
type: info
reference: xxxxxx-xxxxx-xxxx // uuid of contact modified
timestamp: 1518691674517
body: indexed
notification de ludification:
notifications:
- emitter: notification-center
notif_id: xxxxx-xxxxx-xxxxx
type: teaser
timestamp: 1518691674517
body: Pour améliorer votre PI vous pourriez faire ceci…
En l'absence de filtre lors du call sur /api/v2/notifications
, toutes les notifications en instance sont envoyées dans la réponse :
notifications:
- emitter: lmtp
notif_id: xxxxx-xxxxx-xxxxx
type: event
timestamp: 1518691674517
body:
- emailReceived: xxxxxx-xxxxx-xxxxx
- emitter: contacts
notif_id: xxxxxx-xxxxx-xxxxx
type: feedback
reference: xxxxxxxxx
timestamp: 1518691674517
body: success
- emitter: lmtp
notif_id: xxxxx-xxxxx-xxxxx
type: event
timestamp: 1518691674517
body:
emailReceived: xxxxxx-xxxxx-xxxxx // uuid of new email
- emitter: lmtp
notif_id: xxxxx-xxxxx-xxxxx
type: event
timestamp: 1518691674517
body:
emailReceived: xxxxxx-xxxxx-xxxxx // uuid of new email
- emitter: notification-center
notif_id: xxxxx-xxxxx-xxxxx
type: teaser
timestamp: 1518691674517
body: Pour améliorer votre PI vous pourriez faire ceci…
Protocole :
Le frontend fait des requêtes HTTP (GET ou DELETE) sur /api/v2/notifications.
Le serveur répond avec un payload en JSON et ferme la connexion.
Endpoint et API :
endpoint : …/api/v2/notifications
méthodes :
GET
pour obtenir des notifications en file d'attente :
- sans params dans la query, toutes les notifications de la file d'attente sont retournées dans un seul document.
- 2 params optionnels :
from
etto
pour filtrer les notifications par timestamp ou par IDs de notifications (en effet les IDs des notifs sont des séquences alphanumériques qui grandissent avec le temps)
DELETE
pour supprimer des notifications de la file d'attente
- 1 param obligatoire :
until
pour indiquer jusqu'à quel timestamp les notifications doivent être supprimées.
spécifications (swagger) : voir /src/backend/defs/rest-api/paths/notifications.yaml
Principe de fonctionnement :
Backend :
Le backend gère une pile de notifications pour chaque utilisateur.
- De nouvelles notifications sont créées et ajoutées à la pile par le backend en fonction d'actions de l'utilisateur (création d'un contact par ex.), d'événements extérieurs (arrivée d'un nouvel email par ex.),de traitements batch, etc.
Chaque notification à une durée de vie (TTL) prédéfinie dans la pile, en fonction de son niveau d'importance.
Par conséquent, la pile de notifications est automatiquement purgée.
Frontend:
Lors d'un call GET
du frontend, la pile de toutes les notifications en instance est envoyée.
Le frontend peut refaire un GET
xx secondes plus tard, il aura la même pile de notifications +/- les notifications arrivées entre-temps et celles qui ont expirées.
Le frontend peut refaire un GET
xx secondes plus tard en ajoutant le param from=xxxxxxx pour ne recevoir que les dernières notifications arrivées depuis son dernier call (ou depuis le timestamp de la notification la plus récente qu'il a reçu lors du dernier call)
Le frontend peut explicitement purger la pile de notifications côté backend en faisant un call DELETE
avec le param until
ou un numéro de notification
Modèle de données :
La table des notifications est stockées dans cassandra.
Chaque INSERT
se fera avec la directive USING TTL xx
pour gérer le nettoyage automatique de la table
CREATE TABLE user_notification (
user_id uuid,
timestamp_ timestamp,
notif_id uuid,
type ascii,
emitter text,
reference text,
body blob,
primary key(user_id, timestamp, id));
Ces primary keys
permettent de retrouver/supprimer toutes les notifications d'un utilisateur, ou celles d'un utilisateur dans un range de timestamp.