Reach 360: Eventos de webhook

Artículo actualizado el

Este artículo se aplica a:

Tipos de eventos

  • course.completed- Se activa cuando un alumno completa un curso.
  • course.submitted- Se activa cuando un autor envía un curso para que lo revise un administrador para su publicación.
  • enrollments.created- Se activa cuando los usuarios o grupos se inscriben en un curso o en una ruta de aprendizaje.
  • user.created- Se activa cuando se añade un usuario a tu cuenta de Reach 360.

Carga útil del evento Webhook

La carga útil de cada solicitud de webhook tiene una estructura común que comparten todos los eventos de webhook. El cuerpo de la solicitud contiene las siguientes propiedades:

  • id(cadena): el identificador único del evento
  • createdAt(cadena): hora a la que ocurrió el evento
  • type(string): el tipo de evento de webhook
  • webhookId(cadena): el identificador del webhook que provocó el envío del evento
  • apiVersion(string): versión de API utilizada al enviar el evento webhook. También se enviará como API-Version encabezado en la solicitud
  • data(objeto): específico para el tipo de evento de webhook (ver ejemplos)

Ejemplos de carga útil de solicitudes

Cada ejemplo de evento de webhook que aparece a continuación muestra un ejemplo del aspecto que tendría una solicitud de webhook a la URL de destino de tu servidor.

course.completed

Se activa cuando un alumno completa un curso.

Propiedades de los datos de carga útil del evento:

  • curso (objeto): el objeto del curso para el curso relacionado o nulo si las inscripciones son para una ruta de aprendizaje. Este objeto del curso también tiene un objeto de cuestionario con dos propiedades: aprobado y puntuación. Si no hay ningún cuestionario asociado al curso, el objeto estará vacío.

  • usuario (objeto): el objeto de usuario del usuario relacionado.

 

{
«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»: {«curso»: {«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»: «Curso de ejemplo», 
 «url»:» 
 
 
 
 https://api.reach360.com/courses/example-course-id «, 
 «contentType»: «RISE» 
 «cuestionario»: {
«aprobado»: true, «score»: 80
}
}, 
 «user»: {
«email»: "foo@example.com «, «firstName»: «Ejemplo de nombre», «groupUrl»: "https://api.reach360.com/users/example-user-id/groups «, 
 «id»: «example-user-id», «lastName»: 
 «Ejemplo de apellido», «lastActiveAT»: 
 «2021-10-28T 20:39:52 .659 Z», 
 «URL del informe del alumno»: "https://api.reach360.com/reports/learners/example-user-id «, 
 
«rol»: «alumno», 
 «url»: "https://api.reach360.com/users/example-user-id «, 
 «Articulate360User»: false
}
}
}

course.submitted

Se activa cuando un autor envía un curso para que lo revise un administrador para su publicación.

{
  "id": "example-course-submitted-event-id",
  "createdAt": "2020-09-14T05:47:28.951Z",
  "type": "course.submitted",
  "webhookId": "example-webhook-id",
  "apiVersion": "04-04-2022 «Articulate360User",
  "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>"
»: falso «Articulate360User»: falso 
    },
    "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

Se activa cuando los usuarios o grupos se inscriben en un curso o en una ruta de aprendizaje.

La carga útil de este evento siempre contiene los mismos nombres de propiedad, pero las propiedades que tienen valores varían según el tipo de inscripciones que se hayan creado.

Por ejemplo, si uno o más usuarios están inscritos en un curso, la data parte de la carga que se envíe a su controlador incluirá una propiedad de matriz (una users matriz de objetos de usuario) y una propiedad. course En este escenario, la groups propiedad será una matriz vacía y se learningPath establecerá en. null

Del mismo modo, si uno o más grupos están inscritos en una ruta de aprendizaje, el data objeto tendrá una groups propiedad de matriz (una matriz de objetos de grupo) y una learningPath propiedad, mientras que users será una matriz vacía y course seránull.

dataPropiedades de la carga útil del evento:

{
  "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»: falso «Articulate360User»: falso 
    },
    "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»: falso 
      },
      {
        "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»: falso 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

Nota: user.created los eventos se retrasarán de 5 a 10 minutos para los usuarios de SSO.

Nota: user.created los eventos NO se activan para los usuarios de SAML que se eliminan de tu IDP y se vuelven a añadir, a menos que también se eliminen de tu cuenta de Reach.

Se activa cuando se añade un usuario a tu cuenta de Rise.

{
  "id": "example-user-created-event-id",
  "createdAt": "2020-08-24T01:36:18.982Z",
  "type": "user.created",
  "webhookId": "example-webhook-id",
  "apiVersion": "4 de abril de 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  
 
    }
  }
}

Verificación de solicitudes

Cuando se cree un webhook con un sharedSecret Rise, se incluirá un X-Hook-Signature encabezado en cada solicitud, lo que te permitirá verificar que proviene de Reach. Para calcular la firma, Reach usa un compendio hexadecimal del HMAC-SHA1 junto con el cuerpo de la sharedSecret  solicitud.

Este es un ejemplo del aspecto que tendría el código de verificación de firma si utilizas Node.js (Nota: las especificaciones pueden variar según el marco que utilices, la versión de Node en la que te encuentres y otros factores)

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
}

Gestión de errores y reintentos

Rise enviará una solicitud POST con datos JSON al configurado targetUrl  cada vez que events se produzca una de las configuraciones. Su servidor reconoce que ha recibido la carga útil al enviar una respuesta de 200. Cualquier respuesta fuera del rango de 200 indica un error. En ese caso, Rise volverá a intentar enviar la solicitud 14 veces más en las próximas 48 horas.