Reach 360 : événements Webhook
Dernière mise à jour de l’article le
Cet article s'applique à :
Types d'événements
course.completed
- Déclenché lorsqu'un apprenant termine un module.course.submitted
- Déclenché lorsqu'un auteur soumet un module à réviser par un administrateur en vue de sa publication.enrollments.created
- Déclenché lorsque des utilisateurs ou des groupes sont inscrits à un module ou à un chemin d'apprentissage.user.created
- Déclenché lorsqu'un utilisateur est ajouté à votre compte Reach 360.
Charge utile de l'événement Webhook
La charge utile de chaque demande de webhook possède une structure commune partagée par tous les événements de webhook. Le corps de la demande contient les propriétés suivantes :
id
(chaîne) - l'identifiant unique de l'événementcreatedAt
(chaîne) - l'heure à laquelle l'événement s'est produittype
(string) - le type d'événement webhookwebhookId
(string) - l'identifiant du webhook qui a entraîné l'envoi de l'événementapiVersion
(string) - Version de l'API utilisée lors de l'envoi de l'événement webhook. Sera également envoyé sous forme d'API-Version
en-tête dans la demandedata
(objet) - spécifique au type d'événement webhook (voir exemples)
Demandez des exemples de charge utile
Chaque exemple d'événement de webhook ci-dessous montre à quoi ressemblerait une demande de webhook envoyée à l'URL cible sur votre serveur.
course.completed
Déclenché lorsqu'un apprenant termine un module.
Propriétés des données de charge utile des événements :
-
course (objet) : l'objet du cours associé ou nul si les inscriptions concernent un chemin d'apprentissage. Cet objet de module possède également un objet de quiz doté de deux propriétés : réussite et score. Si aucun quiz n'est associé au module, l'objet sera vide.
-
user (object) - l'objet utilisateur pour l'utilisateur associé.
{ « id » : « example-course-completed-event-id », « createdAt » : « 2020-07-02T 03:39:18.991 Z », « type » : « course.completed », « webhookId » : « example-webhook-id », « apiVersion » : « 2023-04-04", « data » : {« module » : {« authorURL » : "https://api.reach360.com/users/example-author-id «, « coverImageURL » : null, « id » : « example-course-id », « courseReportURL » : "https://api.reach360.com/reports/courses/example-course-id «, « title » : « Exemple de cours », « url » : » https://api.reach360.com/courses/example-course-id «, « ContentType » : « RISE », « quiz » : {« passed » : true, « score » : 80 } }, « user » : {« email » : "foo@example.com «, « FirstName » : « Exemple de prénom », « groupsURL » : "https://api.reach360.com/users/example-user-id/groups «, « id » : « example-user-id », « LastName » : « Exemple de nom de famille », « LastActiveat » : « 2021-10-28T 20:39:52.659 Z », « LearnerReportURL » : « https://api.reach360.com/reports/learners/example-user-id », « role » : « apprenant », « url » : "https://api.reach360.com/users/example-user-id «, « Articulate360User » : false}}}
course.submitted
Déclenché lorsqu'un auteur soumet un module pour qu'il soit révisé par un administrateur en vue de sa publication.
{ "id": "example-course-submitted-event-id", "createdAt": "2020-09-14T05:47:28.951Z", "type": "course.submitted", "webhookId": "example-webhook-id", "apiVersion": "
2023-04-04", "data": { "isInitialSubmission": true, "course": { "authorUrl": "<https://api.reach360.com/users/example-author-id>", "coverImageUrl": null, "id": "example-course-id", "courseReportUrl": "<https://api.reach360.com/reports/courses/example-course-id>", "title": "Example Course", "url": "<https://api.reach360.com/courses/example-course-id>", "contentType": "RISE" }, "submitter": { "email": "author@example.com", "firstName": "Example", "groupsUrl": "<https://api.reach360.com/users/example-author-id/groups>", "id": "example-author-id", "lastName": "Author", "lastActiveAt": "2021-10-28T20:39:52.659Z", "learnerReportUrl": "<https://api.reach360.com/reports/learners/example-author-id>", "role": "author", "url": "<https://api.reach360.com/users/example-author-id>"
« Articulate360User » : faux « Articulate360User » : faux}, "reviewer": { "email": "admin@example.com", "firstName": "Example", "groupsUrl": "<https://api.reach360.com/users/example-admin-id/groups>", "id": "example-admin-id", "lastName": "Admin", "lastActiveAt": "2021-10-28T20:39:52.659Z", "learnerReportUrl": "<https://api.reach360.com/reports/learners/example-admin-id>", "role": "admin", "url": "<https://api.reach360.com/users/example-admin-id>"
} } }
enrollments.created
Déclenché lorsque des utilisateurs ou des groupes sont inscrits à un module ou à un chemin d'apprentissage.
La charge utile de cet événement contient toujours les mêmes noms de propriétés, mais les propriétés ayant des valeurs varient en fonction du type d'inscription créé.
Par exemple, si un ou plusieurs utilisateurs sont inscrits à un module, la data
partie de la charge utile envoyée à votre gestionnaire comprendra une propriété de users
tableau (un tableau d'objets utilisateur) et une course
propriété. Dans ce scénario, la groups
propriété sera un tableau vide et learningPath
sera définie surnull
.
De même, si un ou plusieurs groupes sont inscrits à un chemin d'apprentissage, l'data
objet aura une propriété de type groups
tableau (un tableau d'objets de groupe) et une learningPath
propriété, tandis que ce users
sera un tableau vide et le course
seranull
.
data
Propriétés de la charge utile de l'événement :
- cours (objet) : l'objet du cours associé ou
null
si les inscriptions concernent un chemin d'apprentissage. - LearningPath (object) : objet du parcours de formation correspondant au parcours de formation associé ou
null
si les inscriptions concernent un module. - EnrolledBy (object) - Objet utilisateur de l'utilisateur qui a créé les inscriptions ou
null
si l'inscription a été créée via l'API d'inscription aux modules ou l'API d'inscription au parcours de formation. - groupes (liste d'objets) : liste des objets de groupe inscrits (peut-être vide).
- utilisateurs (liste d'objets) : liste des objets utilisateur inscrits (peut-être vide).
{ "id": "example-enrollments-created-event-id", "type": "enrollments.created", "createdAt": "2020-09-16T19:59:55.912Z", "data": { "course": { "authorUrl": "<https://api.reach360.com/users/example-author-id>", "coverImageUrl": null, "id": "example-course-id", "courseReportUrl": "<https://api.reach360.com/reports/courses/example-course-id>", "title": "Example Course", "url": "<https://api.reach360.com/courses/example-course-id>" "source": "rise" }, "enrolledBy": { "email": "admin@example.com", "firstName": "Example", "groupsUrl": "<https://api.reach360.com/users/example-admin-id/groups>", "id": "example-admin-id", "lastName": "Admin", "lastActiveAt": "2021-10-28T20:39:52.659Z", "learnerReportUrl": "<https://api.reach360.com/reports/learners/example-admin-id>", "role": "admin", "url": "<https://api.rise.com/users/example-admin-id>"
« Articulate360User » : faux « Articulate360User » : faux}, "groups": [], "learningPath": null, "users": [ { "email": "learner1@example.com", "firstName": "Foo", "groupsUrl": "<https://api.reach360.com/users/example-learner-1/groups>", "id": "example-learner-1", "lastName": "Learner", "lastActiveAt": "2021-10-28T20:39:52.659Z", "learnerReportUrl": "<https://api.reach360.com/reports/learners/example-learner-1>", "role": "learner", "url": "<https://api.reach360.com/users/example-learner-1>"
« Articulate360User » : faux}, { "email": "learner2@example.com", "firstName": "Bar", "groupsUrl": "<https://api.reach360.com/users/example-learner-2/groups>", "id": "example-learner-2", "lastName": "Learner", "lastActiveAt": "2021-10-28T20:39:52.659Z", "learnerReportUrl": "<https://api.reach360.com/reports/learners/example-learner-2>", "role": "learner", "url": "<https://api.reach360.com/users/example-learner-2>"
« Articulate360User » : faux 2023-04-04
}, { "email": "learner3@example.com", "firstName": "Baz", "groupsUrl": "<https://api.reach360.com/users/example-learner-3/groups>", "id": "example-learner-3", "lastName": "Learner", "lastActiveAt": "2021-10-28T20:39:52.659Z", "learnerReportUrl": "<https://api.reach360.com/reports/learners/example-learner-3>", "role": "learner", "url": "<https://api.reach360.com/users/example-learner-3>"
}, ] }, "apiVersion": "
", "webhookId": "example-webhook-id" }
user.created
Remarque : user.created
les événements seront retardés de 5 à 10 minutes pour les utilisateurs du SSO.
Remarque : les user.created
événements ne sont PAS déclenchés pour les utilisateurs SAML qui sont supprimés de votre IDP puis ajoutés à nouveau, sauf s'ils sont également supprimés de votre compte Reach.
Déclenché lorsqu'un utilisateur est ajouté à votre compte Rise.
{ "id": "example-user-created-event-id", "createdAt": "2020-08-24T01:36:18.982Z", "type": "user.created", "webhookId": "example-webhook-id", "apiVersion": "
04/04/2023", "data": { "user": { "email": "foo@example.com", "firstName": "Example First Name", "groupsUrl": "<https://api.reach360.com/users/example-user-id/groups>", "id": "example-user-id", "lastName": "Example Last Name", "lastActiveAt": "2021-10-28T20:39:52.659Z", "learnerReportUrl": "<https://api.reach360.com/reports/learners/example-user-id>", "role": "learner", "url": "<https://api.reach360.com/users/example-user-id>" "articulate360User": false
} } }
Vérification des demandes
Lorsqu'un webhook est créé avec un sharedSecret
Rise, un X-Hook-Signature
en-tête sera inclus dans chaque demande, vous permettant de vérifier qu'elle provient de Reach. Pour calculer la signature, Reach utilise un condensé hexadécimal HMAC-SHA1 avec le corps sharedSecret
et le corps de la demande.
Voici un exemple de ce à quoi peut ressembler le code de vérification de signature si vous utilisez Node.js (Remarque : les détails peuvent varier en fonction du framework que vous utilisez, de la version de Node que vous utilisez et d'autres facteurs)
const crypto = require('crypto')
const signatureDigest = crypto.createHmac('sha1', process.env.WEBHOOK_SHARED_SECRET)
.update(Buffer.from(JSON.stringify(request.body)))
.digest('hex')
if (request.headers['x-hook-signature'] === signatureDigest) {
// OK: request came from Reach
} else {
// Error: request didn't come from Reach
}
Gestion des erreurs et nouvelles tentatives
Rise enverra une requête POST avec des données JSON au configuré à targetUrl
chaque fois que l'une des requêtes configurées events
se produit. Votre serveur reconnaît avoir reçu la charge utile en renvoyant une réponse 200. Toute réponse en dehors de la plage de 200 indique une erreur. Dans ce cas, Rise essaiera à nouveau d'envoyer la demande 14 fois au cours des prochaines 48 heures.