Categorías: ASP.NET

Introducción a WebHooks

Los tiempos en el desarrollo van cambiando y junto a ello naturalmente las herramientas de desarrollo, los patrones y la forma en la que se hacen las cosas.

Un claro ejemplo son los Event Receiver y los WebHook. Hasta hace unos años nuestro pensamiento era que nuestra aplicación tenía que estar esperando determinados cambios para realizar determinadas acciones. En caso de que esto fuera una aplicación de terceros, tendríamos bien que implementar un proceso o «demonio» que estuviera permanentemente comprobando si se cumple una determinada condición para hacer determinada acción.

Ahora bien, esto está claro que en un modelo de desarrollo basado en el cloud dónde tenemos que simplificar el tiempo de proceso (y por lo tantos los costes). A raíz de esto surge el concepto de WebHook. Podemos definirlo como:

Realizar llamadas «CallBacks» que hacen las aplicaciones Web, pudiendo ser esta llamada por nuestra aplicación o bien por terceras aplicaciones que nada tiene que ver la aplicación original.

Aplicaciones como GitHub, Slack, WordPress, etc. las pusieron de moda.  Nosotros en ENCAMINA, en nuestro Slack, tenemos varios WebHooks contra Visual Studio Team Services porque nos interesa saber cuál es el resultado de la Build o cuándo finalizamos tareas.

 

 

Dado que cambió la pauta del funcionamiento, cuando hay un evento que nuestra aplicación necesita saber, la aplicación origen notifica a dicha aplicación. En este post, vamos a ver una introducción de cómo montar un WebHook en ASP.NET.

 

 

Cuando trabajamos con los WebHooks tenemos dos opciones que implementar:

  • Sending. Es  la parte encargada de enviar los postback a los subscriptores cuando se produce la acción a la que se han subscrito. Por ejemplo: Visual Studio Team Services se encarga de notificar a sus subscriptores que una compilación a terminado.
  • Receivers. Esta parte es un handler/servicio web que está permanentemente a la escucha para poder obtener la notificación por parte del «sending». Un ejemplo seria Slack, tiene unos puertos a la escucha que por ejemplo cuando se notifica que hay una compilación, este lo escribe en el canal de Slack correspondiente.

 

Manos a la obra

Para empezar nos creamos un proyecto  MVC + Web API  utilizando autenticación con Cuentas Individuales tal y como se muestra en la siguiente imagen:

 

 

A continuación, en nuestra solución añadiremos los siguientes paquetes Nugget:

 

Una vez añadido esto dentro de la clase WebApiConfig.Register añadimos las siguientes líneas:

        config.InitializeCustomWebHooks();      
        config.InitializeCustomWebHooksApis();

 

Los WebHooks los podemos bien guardar en memoria, en una tabla de SQL Server o bien en un BlobStorage de Azure. Por este motivo, hay dos paquetes de Nugget idóneos para administrar estos WebHooks según la opción que decidamos:

 

 

Definición del conjunto de filtros de eventos

Ahora vamos a ver la definición del conjunto de filtros de eventos que estarán disponibles para los consumidores de sus WebHooks. Los filtros indican qué eventos se pueden subscribir. Por defecto, el sistema registra un filtro comodín que permite subscribirse a todos los eventos que se exponen. Para ello tendremos que implementar la interfaz IWebHookFilterProvider. Interfaz que solamente expone el método GetFiltersAsync.

 public class BlogsEncaminaFilter: IWebHookFilterProvider
    {
        private readonly Collection<WebHookFilter>; filters = new Collection<WebHookFilter>;
    {
        new WebHookFilter { Name = "DesarrollandoSobreSharePoint", Description = "Nuevo Post."},
        new WebHookFilter { Name = "PorUnaNubeSostenible", Description = "Nuevo Post."},
    };
        public Task<Collection<WebHookFilter>> GetFiltersAsync()
        {
            return Task.FromResult(this.filters);
        }
    }

Enviando notificaciones

Una vez implementados los filtros, lo que vamos a hacer es crear diversos controladores que al invocarlos serán los encargados de enviar dicho evento a todos los subscriptores de dicho WebHook.

Añadiremos un controlador MVC vacío que en la acción del Summit generará un evento utilizando el método NotifyAsync.

  [Authorize]
    public class NotifyController : Controller
    {
        [HttpPost]
        public async Task<ActionResult> Submit()
        {
            // Create an event with action 'event1' and additional data
            await this.NotifyAsync("DesarrollandoSobreSharePoint", new { Titulo = "Nuevo post" });

            return new EmptyResult();
        }
    }

 

Para poder llamar a este método, se debe realizar con un usuario autenticado. En caso de que no lo pongamos, no se realizará la petición.

Para el caso de una WebAPi el código es muy similar:

 [Authorize]
    public class NotifyApiController : ApiController
    {
        public async Task Post()
        {
            // Create an event with 'event2' and additional data
            await this.NotifyAsync("PorUnaNubeSostenible", new { Titulo = "Nuevo articulo" });
        }
    }

Creando un Receptor

Una vez tenemos creado el Sending, en nuestra aplicación crearemos un Receptor para comprobar el correcto funcionamiento del mismo. Para ello, en primer lugar agregaremos el siguiente paquete Nuget:

Microsoft.AspNet.WebHooks.Receivers.Custom  Dentro del fichero WebApiConfig.Register añadiremos la siguiente linea:

config.InitializeReceiveCustomWebHooks();

 

En el WebConfig también añadiremos la siguiente entrada, en la que indicamos el token key de nuestro webHook.

<appSettings>
<add key="MS_WebHookReceiverSecret_Custom" value="12345678901234567890123456789012"/>
</appSettings>

 

A cotinuación nos creamos una clase TestHandler que hereda de WebHookHandler. Este será el punto de nuestra aplicación que estará permanentemente a la escucha de que se notifique un WebHook. Para ello, implementaremos el siguiente código:

 public class TestHandler : WebHookHandler
    {
        public override Task ExecuteAsync(string receiver, WebHookHandlerContext context)
        {
            return Task.FromResult(true);
        }
    }

Ahora para probar agregaremos el siguiente código, que lo que hace es suscribirnos a todos los eventos del WebHook y tenemos llamadas a los métodos en el NotifyApiController y NotifyController. Para ello agregamos el siguiente código en la vista Views/Home/Index.cshtml


<form onsubmit="return subscribe()">
    Subscribe to all events <input type="submit" value="submit">
</form>
<form onsubmit="return unsubscribe()">
    Unsubscribe from all events <input type="submit" value="submit">
</form>
<form onsubmit="return notifymvc()">
    Trigger notification through MVC controller <input type="submit" value="submit">
</form>
<form onsubmit="return notifyapi()">
    Trigger notification through Web API controller <input type="submit" value="submit">
</form>

<script>
function subscribe() {
    $.ajax({
        type: "POST",
        url: "/api/webhooks/registrations",
        data: JSON.stringify({
            WebHookUri: "http://localhost:23224/api/webhooks/incoming/custom",
            Secret: "12345678901234567890123456789012",
            Description: "My first WebHook!"
        }),
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(data, status) { alert(status); },
        failure: function(errMsg) { alert(errMsg); }
    });
    return false;
}

function unsubscribe() {
    $.ajax({
        url: "/api/webhooks/registrations",
        type: 'DELETE',
        success: function (data, status) { alert(status); },
        failure: function(errMsg) { alert(errMsg); }
    });
    return false;
}

function notifymvc() {
    $.post("/notify/submit",
    { },
    function (data, status) { alert("Data: " + data + "\nStatus: " + status); });
    return false;
}

function notifyapi() {
    $.post("/api/notifyapi",
    { },
    function (data, status) { alert("Data: " + data + "\nStatus: " + status); });
    return false;
}
</script>

Si ahora nos subscribimos a los eventos que nos proporciona el WebHook, lanzamos uno de ellos y ponemos un punto de parada en el Handler, veremos lo siguiente:

 

Resumen

WebHooks es una nuevo patrón/utilidad muy útil para comunicar nuestra aplicación con terceros.

En el tiempo en el que el Cloud es una realidad, los WebHooks son una forma simple y sencilla que permite a nuestra aplicación la comunicación con terceras aplicaciones de la forma menos costosa posible. En siguientes artículos veremos cómo incorporarlos a SharePoint Online en sustitución de los Remote Event Receivers.

El código lo tenéis disponible para descargar en mi repositorio de GitHub 😉

Bibliografía

Compartir
Publicado por
Adrián Díaz

Este sitio web utiliza cookies para que tengas la mejor experiencia de usuario. Si continuas navegando, estás dando tu consentimiento para aceptar las cookies y también nuestra política de cookies (esperemos que no te empaches con tanta cookie 😊)