Implementación de referencia de ejemplos de webhooks de SharePoint
La implementación de referencia de modelos y prácticas (PnP) de SharePoint muestra cómo puede usar los webhooks de SharePoint en su aplicación. Los webhooks se implementan de una manera destinada a empresas mediante varios componentes de Microsoft Azure como Azure Web Jobs, Azure SQL Server y Azure Storage Queues para obtener un control de notificaciones de trabajo web asincrónico.
La implementación de referencia solo funciona con webhooks de lista de SharePoint.
También puede seguir estos pasos viendo el vídeo en el canal de YouTube de La comunidad de plataformas de Microsoft 365 (PnP):
Se aplica a Office 365 multiempresa (MT).
Microsoft Azure se usa para hospedar los diversos componentes necesarios para implementar los webhooks de SharePoint.
El código fuente y otros materiales de la implementación de referencia están disponibles en dos versiones:
- Una versión de aplicación hospedada por el proveedor de SharePoint
- Una aplicación de Azure AD de Office 365, que se encuentra en los ejemplos para desarrolladores de SharePoint del repositorio de GitHub.
Implementar la implementación de referencia
La aplicación le muestra cómo administrar webhooks, específicamente para una lista de SharePoint. También contiene una implementación de referencia de un punto de conexión de servicio de webhook que puede volver a usar en sus proyectos de webhook.
Guías de implementación
- La guía de implementación de referencia de webhooks de SharePoint enumera los pasos de implementación que se han usado para aplicar la implementación de referencia hospedada por el proveedor de SharePoint.
- Para implementar la aplicación de Azure AD de Office 365, siga los pasos descritos en la Guía de aplicación de la implementación de referencia de Azure AD de webhooks de SharePoint, que muestra cómo usar una función de la API web como servicio de webhook.
- Si le interesa más usar Azure Functions, vea la Guía de Azure Functions para obtener más información sobre cómo usar Azure Functions en esta implementación de referencia.
Introducción a los webhooks
Los webhooks notifican a su aplicación los cambios en SharePoint que la aplicación necesita supervisar. Su aplicación ya no necesita sondear periódicamente los cambios. Con los webhooks, a su aplicación se le notifica (modelo push) siempre que haya un cambio. Los webhooks no son exclusivos de Microsoft. Son un estándar web universal que también han adoptado otros proveedores (por ejemplo, WordPress, GitHub y MailChimp entre otros).
Agregar un webhook a la lista de SharePoint
La implementación de referencia funciona con una lista de SharePoint. Para agregar un webhook a una lista de SharePoint, su aplicación primero crea una suscripción de webhook mediante el envío de una solicitud POST /_api/web/lists('list-id')/subscriptions
. La solicitud incluye los siguientes elementos:
- Una carga que identifica la lista para la que está agregando el webhook.
- La ubicación de su dirección URL de servicio del webhook para enviar las notificaciones.
- La fecha de expiración del webhook.
Después de solicitar a SharePoint que agregue su webhook, este valida que el punto de conexión de servicio del webhook existe. Envía una cadena de validación al punto de conexión de servicio. SharePoint espera que su punto de conexión de servicio devuelva la cadena de validación en 5 segundos. Si se produce un error en este proceso, la creación del webhook se cancela. Si ha implementado su servicio, esto funciona y SharePoint devuelve un mensaje HTTP 201 en la solicitud POST que la aplicación ha enviado inicialmente. La carga de la respuesta contiene el identificador de la nueva suscripción del webhook.
Consulte la implementación de referencia y verá que todas las operaciones CRUD del webhook se consolidan en la clase WebHookManager del proyecto SharePoint.WebHooks.Common. Para agregar un webhook, se usa el método AddListWebHookAsync:
/// <summary>
/// This method adds a webhook to a SharePoint list. Note that you need your webhook endpoint being passed into this method to be up and running and reachable from the internet
/// </summary>
/// <param name="siteUrl">Url of the site holding the list</param>
/// <param name="listId">Id of the list</param>
/// <param name="webHookEndPoint">Url of the webhook service endpoint (the one that will be called during an event)</param>
/// <param name="accessToken">Access token to authenticate against SharePoint</param>
/// <param name="validityInMonths">Optional webhook validity in months, defaults to 3 months, max is 6 months</param>
/// <returns>subscription ID of the new webhook</returns>
public async Task<SubscriptionModel> AddListWebHookAsync(string siteUrl, string listId, string webHookEndPoint, string accessToken, int validityInMonths = 3)
{
// webhook add code...
}
Al realizar una llamada a SharePoint, necesita proporcionar información de autenticación y, en este caso, está usando un encabezado de autenticación de portador con un token de acceso. Para obtener el token de acceso, intercepte el token mediante un controlador de eventos ExecutingWebRequest:
ClientContext cc = null;
// Create SharePoint ClientContext object...
// Add ExecutingWebRequest event handler
cc.ExecutingWebRequest += Cc_ExecutingWebRequest;
// Capture the OAuth access token since we want to reuse that one in our REST requests
private void Cc_ExecutingWebRequest(object sender, WebRequestEventArgs e)
{
this.accessToken = e.WebRequestExecutor.RequestHeaders.Get("Authorization").Replace("Bearer ", "");
}
SharePoint llama a su servicio de webhook
Cuando SharePoint detecta un cambio en la lista para la que ha creado una suscripción de webhook, este llama a su punto de conexión de servicio. Cuando mire la carga de SharePoint, tenga en cuenta que las siguientes propiedades son importantes:
Propiedad | Descripción |
---|---|
El identificador de la suscripción de webhook. Si quiere actualizar la suscripción de webhook (por ejemplo, para prolongar la expiración de este), necesita este identificador. | |
El identificador de la lista en la que se ha producido el cambio. | |
La dirección URL relativa del servidor del sitio que contiene el recurso en el que se ha producido el cambio. |
Nota:
SharePoint solo envía una notificación de que se ha producido un cambio, pero la notificación no incluye la información de lo que ha cambiado realmente. Como obtiene información sobre la web y la lista que han cambiado, esto significa que puede usar el mismo punto de conexión de servicio para controlar los eventos de webhook desde varios sitios y listas.
Cuando se llame al servicio, es importante que su servicio responda con un mensaje HTTP 200 en menos de 5 segundos. Más adelante en este artículo obtendrá más información sobre el tiempo de respuesta, pero principalmente necesita que controle las notificaciones asincrónicamente. En esta implementación de referencia, realizará esto mediante trabajos web de Azure y colas de Azure Storage.
Captar los cambios en los que su servicio necesita actuar
En el paso anterior, se ha llamado a su punto de conexión de servicio, pero SharePoint solo ha proporcionado información sobre dónde se ha producido el cambio, no sobre lo que ha cambiado realmente. Para entender lo que ha cambiado, necesitará usar la API GetChanges()
de SharePoint, como se muestra en la siguiente imagen.
Puede obtener más información sobre la implementación de GetChanges()
en el método ProcessNotification de la clase ChangeManager del proyecto SharePoint.WebHooks.Common.
Para evitar obtener el mismo cambio repetidamente, es importante que informe a SharePoint desde qué punto quiere los cambios. Esto se realiza pasando un changeToken, que también implica que su punto de conexión de servicio necesita conservar el changeToken que se ha usado por última vez de forma que pueda usarse la próxima vez que se llame al punto de conexión de servicio.
A continuación se muestran algunos conceptos clave que se deben tener en cuenta sobre los cambios:
- SharePoint no llama a su servicio en tiempo real: cuando se produce un cambio en una lista que tiene un webhook, SharePoint pone en cola una llamada de webhook. Una vez por minuto, se lee esta cola y se llama a los puntos de conexión de servicio adecuados. Este procesamiento por lotes de solicitudes es importante. Por ejemplo, si se ha producido una carga masiva de 1000 registros a la vez, el procesamiento por lotes evita que SharePoint llame 1000 veces al punto de conexión. De esta manera, solo se llama una vez a su punto de conexión, pero, cuando llame al método
GetChanges()
, obtiene 1000 eventos de cambio que necesita procesar. - Para garantizar una respuesta inmediata, independientemente del número de cambios, es importante que la carga de trabajo de su punto de conexión de servicio se ejecute asincrónicamente. En la implementación de referencia, hemos aprovechado la energía de Azure: el servicio serializa la carga entrante y la almacena en una cola de Azure Storage mientras exista un trabajo web de Azure que se ejecute continuamente y compruebe la existencia de mensajes en la cola. Cuando hay mensajes en la cola, el trabajo web los procesa y también ejecuta la lógica de manera asincrónica.
Completar el flujo de un extremo a otro
En el siguiente diagrama se describe el flujo de webhook de un extremo a otro completo.
- Su aplicación crea una suscripción de webhook. Después, obtiene el changeToken actual de la lista para la que ha creado el webhook.
- Su aplicación conserva el changeToken en un almacenamiento persistente, como SQL Azure en este caso.
- Se produce un cambio en SharePoint y este llama a su punto de conexión de servicio.
- Su punto de conexión de servicio serializa la solicitud de notificación y la almacena en una cola de almacenamiento.
- Su trabajo web ve el mensaje en la cola e inicia la lógica de procesamiento de mensajes.
- La lógica de procesamiento de mensajes recupera el token de cambio que se ha usado por última vez del almacenamiento persistente.
- Su lógica de procesamiento de mensajes usa la API
GetChanges()
para determinar qué ha cambiado. - Los cambios devueltos se procesan y, ahora, su aplicación realiza lo que necesita hacer en función de los cambios.
- Por último, la aplicación conserva el changeToken que se ha recuperado por última vez para que la próxima vez no reciba los cambios que ya se han procesado.
Trabajar con la renovación de webhook
Las suscripciones de webhook se establecen para que expiren en 6 meses de manera predeterminada o en la fecha especificada cuando se crearon. A menudo, necesita que el webhook esté disponible más tiempo. Los modelos que se describen a continuación son buenos para aumentar la duración de una suscripción de webhook. El primer modelo es ligero y el segundo es algo más complejo, y requiere hospedar un trabajo web adicional.
Modelo básico
Cuando su servicio recibe una notificación, también obtiene información sobre la duración de la suscripción. Si la suscripción está a punto de expirar, dentro de la lógica de procesamiento de notificaciones simplemente amplía la duración de la suscripción. Este modelo se implementa en esta implementación de referencia y funciona correctamente en la mayoría de los casos. En cambio, en un caso donde no haya ningún cambio durante 6 meses en la lista para la que ha creado una suscripción de webhook, esta suscripción nunca se prolonga y se elimina.
Modelo fiable pero más complejo
Cree un trabajo web que semanalmente lea todos los identificadores de suscripción del almacenamiento persistente. Extienda una por una las suscripciones que encuentre cada vez.
Nota:
Este trabajo web no forma parte de esta implementación de referencia.
La renovación real de un webhook de lista de SharePoint puede realizarse mediante una llamada de REST PATCH /_api/web/lists('list-id')/subscriptions(‘subscriptionID’)
.
En la implementación de referencia, la actualización de webhooks se implementa en la clase WebHookManager del proyecto SharePoint.WebHooks.Common.
Para actualizar un webhook, se usa el método UpdateListWebHookAsync:
/// <summary>
/// Updates the expiration datetime (and notification URL) of an existing SharePoint list webhook
/// </summary>
/// <param name="siteUrl">Url of the site holding the list</param>
/// <param name="listId">Id of the list</param>
/// <param name="subscriptionId">Id of the webhook subscription that we need to update</param>
/// <param name="webHookEndPoint">Url of the webhook service endpoint (the one that will be called during an event)</param>
/// <param name="expirationDateTime">New webhook expiration date</param>
/// <param name="accessToken">Access token to authenticate against SharePoint</param>
/// <returns>true if successful, exception in case something went wrong</returns>
public async Task<bool> UpdateListWebHookAsync(string siteUrl, string listId, string subscriptionId, string webHookEndPoint, DateTime expirationDateTime, string accessToken)
{
// webhook update code...
}
Depurar webhooks
Como SharePoint llama a su punto de conexión de servicio de webhook, este necesita estar accesible para SharePoint. Esto hace que el desarrollo y la depuración sean ligeramente más complejos. A continuación se muestran algunas estrategias que puede usar para facilitarle el proceso:
- Durante la implementación inicial, proporcione su propia carga serializada a su lógica de procesamiento de servicios. Esto hace que sea posible probar completamente la lógica de procesamiento sin implementar el punto de conexión de servicio (e incluso sin configurar un webhook).
- Si tiene acceso a los recursos de Azure, puede implementar su punto de conexión en Azure al usar una compilación de depuración y configurar Azure App Service para la depuración. Por lo tanto, esto permite que establezca un punto de interrupción remoto y realice una depuración remota con Visual Studio.
- Si no quiere implementar su servicio durante el período de implementación, debe usar un túnel seguro para su servicio. La idea es que indique a SharePoint que el servicio de notificación se ubica en un punto de conexión público compartido. En el cliente, instale un componente que se conecte a ese servicio público compartido y, cuando se realice una llamada al punto de conexión público, el componente de cliente recibe una notificación y traspasa la carga a su servicio que se ejecuta en localhost. ngrok es una implementación de esa herramienta de túnel seguro que puede usar para depurar su servicio de webhook de forma local.