Reducir la falta de suscripciones y notificaciones para recursos de Outlook (versión preliminar)Reduce missing subscriptions and notifications for Outlook resources (preview)

Las aplicaciones suscritas a notificaciones para recursos de Outlook pueden perder sus suscripciones o no recibir algunas notificaciones.Apps subscribing to notifications for Outlook resources may get their subscriptions removed and miss some notifications. Deben implementar lógica para detectar y recuperarse de la pérdida y reanudar un flujo continuo de notificaciones.Apps should implement logic to detect and recover from the loss, and resume a continuous notification flow.

Algunos eventos de Outlook pueden provocar que una suscripción se quite.Certain events in Outlook can cause a subscription to be removed. Estos eventos incluyen:These events include:

  • Se ha restablecido la contraseña de usuarioUser's password has been reset
  • Dispositivo del usuario fuera del cumplimientoUser's device is out of compliance
  • Cuenta de usuario revocadaUser's account has been revoked

Cuando se produce este evento, Outlook envía una notificación de ciclo de vida especial, subscriptionRemoved.When such an event happens, Outlook sends a special lifecycle notification, subscriptionRemoved.

Outlook también envía otra notificación de ciclo de vida, missed, si no se puede entregar una notificación a una aplicación.Outlook also sends another lifecycle notification, missed, if a notification cannot be delivered to an app.

Las aplicaciones suscritas a notificaciones para recursos de Outlook, como mensaje y evento, deben atender las señales de subscriptionRemoved y missed:An app subscribing to notifications for Outlook resources, such as message and event, should listen to the subscriptionRemoved and missed signals:

  • Al recibir una notificación de subscriptionRemoved, la aplicación debe volver a crear la suscripción para mantener un flujo continuo.Upon receiving a subscriptionRemoved notification, the app should recreate the subscription in order to maintain a continuous flow.
  • Al recibir una notificación de missed, la aplicación debe volver a sincronizar los datos de recursos con Microsoft Graph.On receiving a missed notification, the app should resynchronize resource data using Microsoft Graph.

Para recibir notificaciones de ciclo de vida, puede usar el punto de conexión notificationUrl existente que ya recibe notificaciones para los recursos, o puede registrar un lifecycleNotificationUrl independiente para recibir notificaciones subscriptionRemoved y missed en un punto de conexión independiente.To receive lifecycle notifications, you can use the existing notificationUrl endpoint that already receives resource notifications, or you can register a separate lifecycleNotificationUrl to receive subscriptionRemoved and missed notifications in a separate endpoint.

Crear una suscripciónCreating a subscription

Al crear una suscripción, puede especificar un punto de conexión de notificaciones independientes utilizando la propiedad lifecycleNotificationUrl.When creating a subscription, you can specify a separate notification endpoint using the lifecycleNotificationUrl property. Si especifica el punto de conexión, todos los tipos actuales y futuros de notificaciones de ciclo de vida se entregarán allí.If you specify the endpoint, all current and future types of lifecycle notifications will be delivered there. En caso contrario, las notificaciones subscriptionRemoved y missed se entregarán a la notificationUrl existente para todas las suscripciones.Otherwise, subscriptionRemoved and missed notifications will be delivered to the existing notificationUrl for all existing subscriptions.

Nota: de momento, la propiedad lifecycleNotificationUrl solo se puede establecer o leer utilizando la versión beta de las API de Microsoft Graph.Note: At the moment, the lifecycleNotificationUrl property can only be set or read using the beta version of Microsoft Graph APIs. Sin embargo, las suscripciones creadas con beta se almacenan en el mismo entorno de producción que v1.0 por lo que puede implementar el nuevo flujo de Outlook descrito aquí, además del uso normal de v1.0 con otras suscripciones.However, subscriptions created using beta are stored in the same production environment as v1.0 so you can implement the new Outlook flow described here in addition to your regular usage of v1.0 with other subscriptions.

Ejemplo de solicitud de suscripciónSubscription request example

POST https://graph.microsoft.com/beta/subscriptions
Content-Type: application/json
{
  "changeType": "created,updated",
  "notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
  "lifecycleNotificationUrl": "https://webhook.azurewebsites.net/api/lifecycleNotifications",
  "resource": "/users/{id}/messages",
  "expirationDateTime": "2019-03-20T11:00:00.0000000Z",
  "clientState": "<secretClientState>"
}

Importante: usar el mismo nombre de host para ambas direcciones URL de notificaciones.Important: Use the same hostname for both notifications URLs.

Nota: es necesario validar ambos puntos de conexión de notificación, como se describe en el artículo de notificación genérico .Note: You need to validate both notification endpoints as described in the generic notification article. Si quiere usar la misma dirección URL para los dos puntos de conexión, recibirá y responderá a las dos peticiones de validación.If you choose to use the same URL for both endpoints you will receive and respond to two validation requests.

Nota: no puede actualizar las suscripciones existentes (PATCH) para agregar la propiedad lifecycleNotificationUrl.Note: You cannot update (PATCH) the existing subscriptions to add the lifecycleNotificationUrl property. Debe quitar estas suscripciones y crear otras nuevas y especificar la propiedad lifecycleNotificationUrl.You should remove such existing subscriptions, and create new subscriptions and specify the lifecycleNotificationUrl property. Las suscripciones existentes sin la propiedad lifecycleNotificationUrl recibirán las notificaciones subscriptionRemoved y missed por la notificationUrl.Existing subscriptions without lifecycleNotificationUrl property will receive the subscriptionRemoved and missed notifications via the notificationUrl.

Responder a las notificaciones subscriptionRemovedResponding to subscriptionRemoved notifications

La notificación subscriptionRemoved le informa de que una suscripción se ha eliminado y debe reconstruirse, si desea seguir recibiendo notificaciones.The subscriptionRemoved notification informs you that a subscription has been removed and should be recreated, if you want to continue receiving notifications.

Puede crear una suscripción de larga duración (por ejemplo, 3 días) y las notificaciones de datos de recursos se desplazarán a la notificationUrl.You can create a long-lived subscription (e.g. 3 days), and resource data notifications will start flowing to the notificationUrl. Sin embargo, pueden cambiar las condiciones de acceso a los datos de recursos más adelante.However, the conditions of access to the resource data may change over time. Por ejemplo, puede producirse un evento en el servicio de Outlook que requiera que la aplicación vuelva a autenticar al usuario.For example, an event in the Outlook service may occur that requires the app to re-authenticate the user. En este caso, el flujo tiene el siguiente aspecto:In such a case, the flow looks as follows:

  1. Outlook detecta que tiene que quitar una suscripción de Microsoft Graph.Outlook detects that a subscription needs to be removed from Microsoft Graph.

    1. No hay ninguna cadencia establecida para estos eventos.There is no set cadence for these events. Puede producirse con frecuencia para algunos recursos y casi nunca para otros.They may occur frequently for some resources, and almost never for others.
  2. Microsoft Graph envía una notificación subscriptionRemoved a la lifecycleNotificationUrl (si se especificó), o a la notificationUrl.Microsoft Graph sends a subscriptionRemoved notification to the lifecycleNotificationUrl (if specified), or the notificationUrl.

  3. Puede responder a esta notificación creaando una nueva suscripción para el mismo recurso.You can respond to this notification by creating a new subscription for the same resource. Para ello, deberá presentar un token de acceso válido; en algunos casos, esto significa que la aplicación debe volver a autenticar al usuario para obtener un nuevo token de acceso válido.To do this, you need to present a valid access token; in some cases this means the app needs to re-authenticate the user to obtain a new valid access token.

  4. Si crea una nueva suscripción correctamente, las notificaciones de recursos iniciarán el flujo de nuevo.If you successfully create a new subscription, resource notifications will start flowing again. Sin embargo, si se produce un error (por ejemplo, la aplicación no puede obtener un token de acceso válido), no se enviarán notificaciones de recursos.However, if you fail (for example, the app could not obtain a valid access token), resource notifications will not be sent.

  5. Después de crear la nueva suscripción, puede sincronizar los datos de recursos para identificar los cambios que faltan.After creating the new subscription, you can sync the resource data to identify any missing changes.

Ejemplo de notificación subscriptionRemovedsubscriptionRemoved notification example

{
  "value": [
    {
      "subscriptionId":"<subscription_guid>",
      "subscriptionExpirationDateTime":"2019-03-20T11:00:00.0000000Z",
      "tenantId": "<tenant_guid>",
      "clientState":"<secretClientState>",
      "lifecycleEvent": "subscriptionRemoved"
    }
  ]
}

Algunas cosas a tener en cuenta sobre este tipo de notificación:A few things to note about this type of notification:

  • El campo "lifecycleEvent": "subscriptionRemoved" designa esta notificación como relacionada con la eliminación de la suscripción.The "lifecycleEvent": "subscriptionRemoved" field designates this notification as related to subscription removal. También son posibles otros tipos de notificaciones de ciclo de vida y se presentarán en el futuro.Other types of lifecycle notifications are also possible, and new ones will be introduced in the future.
  • La notificación no contiene información sobre un recurso específico, porque no está relacionada con un cambio de recursos, sino con el cambio de estado de la suscripción.The notification does not contain any information about a specific resource, because it is not related to a resource change, but to the subscription state change.
  • Igual que las notificaciones de recursos, las notificaciones de ciclo de vida se pueden agrupar (en la matriz value), cada una con otro valor lifecycleEvent posiblemente diferente.Similar to resource notifications, lifecycle notifications may be batched together (in the value array), each with a possibly different lifecycleEvent value. Procese cada notificación del lote consecuentemente.Process each notification in the batch accordingly.

Acciones a tomarActions to take

  1. Confirme la recepción de la notificación, respondiendo a la llamada POST con 202 - Accepted.Acknowledge the receipt of the notification, by responding to the POST call with 202 - Accepted.
  2. Valide la autenticidad de la notificación.Validate the authenticity of the notification.
  3. Asegúrese de que la aplicación tiene un token de acceso válido para dar el siguiente paso.Ensure the app has a valid access token to take the next step.

Nota: si usa una de las bibliotecas de autenticación, controlará esto para que pueda reutilizar un token en caché válido u obtener un nuevo token, incluyendo pedir al usuario que inicie sesión de nuevo (por ejemplo, con una contraseña nueva).Note: If you are using one of the authentication libraries they will handle this for you by either reusing a valid cached token, or obtaining a new token, including asking the user to login again (e.g. with a new password). Tenga en cuenta que obtener un nuevo token puede fallar, ya que pueden haber cambiado las condiciones de acceso y el autor de la llamada puede que no esté autorizado ya para acceder a los datos de recursos.Note that obtaining a new token may fail, since the conditions of access may have changed, and the caller may no longer be allowed access to the resource data.

  1. Crear una nueva suscripción utilizando el proceso estándar descrito aquí.Create a new subscription using the standard process described here.

Nota: esta acción puede fallar, porque las comprobaciones de autorización realizadas por el sistema pueden denegar a la aplicación o al usuario el acceso al recurso.Note: This action may fail, because the authorization checks performed by the system may deny the app or the user access to the resource. Puede ser necesario que la aplicación obtenga un nuevo token de acceso del usuario para autorizar correctamente una suscripción.It may be necessary for the app to obtain a new access token from the user to successfully reauthorize a subscription. Puede repetir estas acciones en cualquier momento, por ejemplo, si cambian las condiciones de acceso.You may retry these actions later, at any time, for example when the conditions of access have change. Cualquier cambio de recurso realizado en el período de tiempo desde que la notificación de ciclo de vida se ha enviado hasta que la aplicación crea correctamente la suscripción se perderá.Any resource changes in the time period from when the lifecycle notification was sent, to when the app re-creates the subscription successfully, will be lost. La aplicación necesita capturar dichos cambios por sí misma.The app will need to fetch those changes on its own.

  1. Después de crear la nueva suscripción, sincronice los datos de recursos que faltan desde la última hora conocida en la que ha recibido una notificación para este recurso; por ejemplo: GET https://graph.microsoft.com/v1.0/users/{id}/messages?$filter=createdDateTime+ge+{LastTimeNotificationWasReceived}After creating the new subscription, sync any missing resource data from the last known time you received a notification for this resource; for example: GET https://graph.microsoft.com/v1.0/users/{id}/messages?$filter=createdDateTime+ge+{LastTimeNotificationWasReceived}

Responder a las notificaciones perdidasResponding to missed notifications

Estas señales informan de que algunas notificaciones todavía no se han entregado.These signals inform you that some notifications may have not been delivered. Debe decidir si ignorar o manejar estas señales.You should decide if you ignore or handle these signals.

Ejemplo de notificaciónNotification example

{
  "value": [
    {
      "subscriptionId":"<subscription_guid>",
      "subscriptionExpirationDateTime":"2019-03-20T11:00:00.0000000Z",
      "tenantId": "<tenant_guid>",
      "clientState":"<secretClientState>",
      "lifecycleEvent": "missed"
    }
  ]
}

Algunas cosas a tener en cuenta sobre este tipo de notificación:A few things to note about this type of notification:

  • El campo "lifecycleEvent": "missed" designa esto como una señal sobre notificaciones perdidas.The "lifecycleEvent": "missed" field designates this as a signal about missed notifications. También son posibles otros tipos de notificaciones de ciclo de vida y se presentarán en el futuro.Other types of lifecycle notifications are also possible, and new ones will be introduced in the future.
  • La notificación no contiene información sobre un recurso específico, porque no está relacionada con un cambio de recursos, sino con el cambio de estado de la suscripciónThe notification does not contain any information about a specific resource, because it is not related to a resource change, but to the subscription state change
  • Igual que las notificaciones de recursos, las notificaciones de ciclo de vida se pueden agrupar (en la matriz value), cada una con otro valor lifecycleEvent posiblemente diferente.Similar to resource notifications, lifecycle notifications may be batched together (in the value array), each with a possibly different lifecycleEvent value. Procese cada notificación del lote consecuentemente.Process each notification in the batch accordingly.

Acciones a tomarActions to take

  1. Confirme la recepción de la notificación, respondiendo a la llamada POST con 202 - Accepted.Acknowledge the receipt of the notification, by responding to the POST call with 202 - Accepted.
  • Si ignora estas señales, no haga nada más.If you ignore these, signals, do nothing else. En caso contrario:Otherwise, YES.
  1. Valide la autenticidad de la notificación.Validate the authenticity of the notification.
  2. Realice una nueva sincronización de todos los datos del recurso para identificar los cambios que no se distribuyen como notificaciones.Perform a full data resync of the resource to identify the changes that were not delivered as notifications.

Prepare el código para el futuro al controlar las notificaciones de ciclo de vidaFuture-proof the code handling lifecycle notifications

En el futuro, Microsoft Graph agregará más tipos de notificaciones de ciclo de vida de suscripción.In the future Microsoft Graph will add more types of subscription lifecycle notifications. Publicaremos al mismo punto de conexión: lifecycleNotificationUrl, pero tendrá un valor diferente en lifecycleEvent y puede contener propiedades y un esquema ligeramente distintos, específicos para el escenario para el que se emite.They will be posted to the same endpoint: lifecycleNotificationUrl, but they will have a different value under lifecycleEvent and may contain a slightly different schema and properties, specific to the scenario for which they will be issued.

Implemente el código de forma que en el futuro no se interrumpa cuando se presenten los nuevos tipos de notificaciones de ciclo de vida de Microsoft Graph.You should implement your code in a future-proof way so it does not break when Microsoft Graph introduces new types of lifecycle notifications. Se recomienda el siguiente método:We recommend the following:

  1. Identificar explícitamente cada notificación como un evento compatible, con la propiedad lifecycleEvent.Explicitly identify each notification as an event that you support, using the lifecycleEvent property. Por ejemplo, busque la propiedad "lifecycleEvent": "subscriptionRemoved" para identificar un evento específico y controlarlo.For example, look for the "lifecycleEvent": "subscriptionRemoved" property to identify a specific event, and handle it.

  2. Manténgase atento a anuncios de notificaciones para nuevos escenarios, ya que puede que haya más tipos de notificaciones de ciclo de vida en el futuro.Watch for announcements of notifications for new scenarions, as there may be more types of lifecycle notifications in the future.

  3. En la aplicación, omita los eventos de ciclo de vida que la aplicación no reconoce y anótelos para obtener información.In your app, ignore any lifecycle events that the app does not recognize, and log them to gain awareness.

  4. Si lo desea, busque la documentación relacionada con nuevas notificaciones de ciclo de vida e implemente la compatibilidad con ellas según corresponda.At your discretion, look up the related documentation for new lifecycle notifications and implement support for them as appropriate.

Ver tambiénSee also