jueves, 9 de noviembre de 2017

Soy un perezoso

Desde que tengo un churumbel me estaba acostumbrado a consultar la página de alertas nacionales de productos peligrosos cada varios días con el fin de estar informado de juguetes y utensilios defectuosos o engañosos que supongan un peligro para el vástago. Puede parecer una tontería; pero una vez le compramos a la criatura, en una papelería local de dueños no orientales, una pintura de dedos JOVI (sí, sí, la de toda la vida) que iba a ser retirada del mercado por contener una cantidad de arsénico y aluminio incompatibles con la vida basada en el carbono.


El problema es que soy muy perezoso y es un tedio tremendo mirar la lista de alertas cada 2 o 3 días, y no ver ninguna novedad durante un mes entero. "Seguro que puedo encontrar una manera de mandarme las novedades (push automático) en vez de tener que ir a mirar en la web varias veces a la semana (pull manual) ..." pense yo. Y la encontré. :)

Primeramente investigué la web de alertas para decidir una estrategia de web scraping. Un simple vistazo a un request en la página con el depurador del Chrome me reveló que la información de las alertas está contenida en un fichero JavaScript al que se le puede hacer un GET http sin más complicaciones. (http://www.aecosan.msssi.gob.es/AECOSAN/resources/js/consumo/datos_notificaciones.js)  ¡Cojonudo! No tengo que lidiar con el HTML y el DOM, no hay necesidad de XPATH, ni XQUERY, ni nada por el estilo.

Ahora que procesar el fichero JavaScript como fichero de texto también prometía ser aburrido de la hostia:
listadoNotis.addNotificacion(333, '2017', '333/2017', '26/10/2017', 'VEHÍCULO, MARCA NISSAN, MODELOS ALMER (N16 Y V10), TERRANO (R20), NAVARA (D22), PATROL (Y61) Y X-TRAIL (T30) (FABRICADOS DEL 2004 AL 2012)', '333-2017.pdf', '333-2017.jpg', 'Vehículos y accesorios', 'Generalidad de Cataluña');
listadoNotis.addNotificacion(332, '2017', '332/2017', '26/10/2017', 'CUERDAS ELÁSTICAS (PULPO) PARA EQUIPAJES CON 2 CIERRES, MARCA GERIMPORT, 120 CM', '332-2017.pdf', '332-2017.jpg', 'Cuerdas para equipaje', 'Junta de Castilla y León');

Pero, como soy perezoso, decidí aprender JavaScript y NodeJs para poder procesar el fichero con cuatro líneas de código:

function ListaAlertas(){
    this.miLista = [];
    this.addNotificacion: function(a, b, c, d, e, f, g, h, i) {miLista.unshift({a,b,c,d,e,f,g,h,i})};
    jsString = HTTPRequest(ficheroAlertasPath).body; // http://../datosNotificaciones.js
    var fillFunction = new Function('listadoNotis', jsString);
    fillFunction(this);
}

donde jsString es una cadena de texto con el cuerpo del fichero descargado.

new Function('listadoNotis', jsString); crea una función que recibe un parametro 'listadoNotis' y tiene por cuerpo el texto de jsString ( listadoNotis.addNotificacion(333, '2017',...) ).

Al ejecutar fillFunction() y pasarle por parámetro una clase con la función addNotificacion ; ésta se lanza por cada alerta y rellena mi array con la información.

Ahora sólo queda mandarme las noticias y una de las formas más comodas (a la vez que fácil, recordad que soy muy perezoso) es usar Telegram y un bot que te lo da todo hecho (API http, infraestructura de la comunicación, aplicación de cliente, etc).

Me cree un bot y un canal de distribución privado a través de la plataforma de Telegram, y añadí el bot como administrador del canal para que tuviera permisos para escribir mensajes en él.

Después sólo tuve que usar una librería en NodeJs para interactuar con la API del bot para enviar esta información al canal privado iterando el array de alertas, y hacer que este código se lance una vez al día:

var CronJob = require('cron').CronJob;
new CronJob({
  cronTime: '*/50 * * * *', 
  onTick: launchService,
  start: true
});

Y ya tenía un servicio que consultaba las alertas de consumo, y si había alguna nueva me llegaba un mensaje de Telegram de mi querido bot al canal de distribución; como si fuese un colega que me manda un mensaje para quedar a tomar unas cañas. :D

También aproveché para juguetear un poco con las funciones generadoras a la hora de sincronizar llamadas asíncronas; esto lo hice pre async/await; ya sabía usar promesas (no me aportaría nada nuevo) y quería aprender sobre los generadores.

El código lo tenéis en GitHub. No es bonito y no está currado, pero puede ayudar a algún lector que quiera empezar a montarse un sistema de notificaciones automáticas a través de Telegram.

Happy coding bastardillos!

5 comentarios:

  1. Pero mira que eres perezoso!!! :DDD

    ResponderEliminar
  2. Gran trabajo! Yo hace que no enredo con nada más o menos desde que llegó el segundo..

    Yo voy a ser más perezoso aún, pero no me gustaría dejar pasar la oportunidad de aprovecharme te tu tiempo... Como padre preocupado, me puedes añadir al chat de telegram??? :D

    ResponderEliminar
    Respuestas
    1. Esta down. Lo tenia en OpenShift con redis en un plan grtuito pero el cambio de plataforma que ha hecho RedHat no me permite tener la imagen de la app y de redis a la vez y ademas no me da https para el webhook del bot de telegram si no es pagando cuota mensual.
      Me puse en contacto con varias asociaciones de consumidores para ver si alguna estaba interesada en mantener el servicio pagando el hosting pero no recibi ni siquiera una respuesta negativa; directamente pasaron del tema. Me pregunto a que se dedicaran las asociaciones de consumidores de este pais... (aparte de que algunos vivan como marqueses del cuento de hacerse de la junta directiva de la asociacion si es suficientemente grande)

      Eliminar
  3. ¡Cagoen! Seguramente a las asociaciones de consumidores les pasa lo mismo que a muchas empresas, no atienden el correo...

    ResponderEliminar
    Respuestas
    1. Tienes el codigo en GitHub. Siempre puedes clonar el repositorio y hostearlo en tu casa usando https://letsencrypt.org/ para https... ;)

      Eliminar