Objetivos
El objetivo del proyecto, en su parte de redes sociales, consiste en monitorizar publicaciones relacionadas con los Sanfermines para extraer datos de las mismas y presentarlos dentro de una página web amigable.
Entre toda la información disponible en ese océano interminable de contenido llamado Internet, optamos por recoger lo siguiente:
- Toda la información proveniente de Twitter relacionada con las fiestas
- Todas las fotos procedentes de Instagram localizadas por la zona de Pamplona.
Entorno
El entorno está montado en un servidor VPS bastante sencillo. Dispone de 8GB de RAM y un disco duro SSD de 35 GB.
Para recoger toda la información es necesario construir una serie de procesos así como montar una infraestructura para almacenar y consultar los datos. Además necesitamos una base de datos y un servidor web.
Para manejar estos procesos de forma sencilla se tomó la decisión de utilizar una serie de contenedores de Docker. Esto permite reutilizar o actualizar el proyecto con mucha facilidad. Al mismo tiempo facilita gestionar los logs, la red interna y las variables de entorno.
Elección de la base de datos
Dado que el objetivo fundamental es extraer información de una serie de publicaciones, optamos por hacer uso de Elasticsearch. Es una herramienta de la que ha hablé hace unas semanas, con la que ya tenemos experiencia, y que ofrece unas excelentes capacidades para filtrar y agregar información.
Servidor web
El servidor web está realizado en Node.js, utilizando Express.js. Dicho servidor se comunica con Elasticsearch utilizando la API REST y se dedica, además de servir la propia aplicación web, a construir las consultas para extraer los datos y a transformarlas en los objetos JSON que posteriormente sirven para construir los gráficos.
Es un servidor sencillo, compuesto de 3 piezas:
– Servidor: encargado de escuchar peticiones, con un par de middlewares para habilitar compresión y crear un log.
– QueryBuilder: una clase encargada de construir las peticiones a Elasticsearch a partir de una consulta básica. Dispone de métodos para añadir filtros como ubicación y fecha, y la consulta básica se encarga de filtrar cualquier cosa no deseada (publicaciones no relacionadas con los Sanfermines, usuarios excluidos, etc).
– GraphicUtils: esta clase se encarga de convertir las respuestas de las agregaciones de Elasticsearch en objetos que pueden ser entendidos por la aplicación.
Procesos para tratar los datos
Hay 4 procesos Java encargados de recopilar datos, los 4 hacen uso de una librería con el código necesario para procesarlos y almacenarlos.
Lo primero fue preparar un conjunto de palabras relacionadas con los sanfermines para monitorizar. A la hora de recoger los tweets, hacemos uso de 3 apis diferentes.
La API de streaming (StreamingConsumer)
Esta API nos permite conectarnos a Twitter, especificar un conjunto de palabras y recibir en tiempo real todos los tweets que se van produciendo. El problema es que estos tweets vienen en el momento en el que se producen, por lo que todavía no disponen de un conteo de favoritos y retweets. Debido a esto a todos los tweets se les añade un campo «updated» que nos permite seleccionar los tweets que más tiempo llevan sin actualizar. Lo que nos lleva a la siguiente API.
La API de status (StatusUpdater)
Esta API nos permite pedir a Twitter un listado de los tweets de los que deseamos obtener información. El proceso encargado de consumir los tweets provenientes de esta API ejecuta una consulta para obtener una lista de los posts que debe actualizar, y va siguiendo dicha lista hasta que los actualiza en su totalidad. Una vez ha terminado, vuelve a comenzar. Como en ocasiones un tweet puede haber sido borrado, se aprovecha para eliminarlo de la base de datos.
La API de búsqueda (SearchConsumer)
Esta API permite recoger tweets que cumplen ciertas condiciones. Es útil para recuperar tweets perdidos tras un reinicio.
Para Instagram utilizamos un único proceso. Este proceso se encarga de pedir periódicamente las publicaciones más recientes que se han realizado en determinadas ubicaciones geográficas.
Tratamiento de las publicaciones
Cuando una publicación entra, se realiza un tratamiento de los datos. Para empezar, se transforman las fechas para que tengan todas el mismo formato. También se extraen las palabras tanto del título como del cuerpo de la publicación, y se procesan para crear un campo «cloud» que permite generar una nube de palabras. Se realiza lo mismo con los hashtags y las menciones. Por último, se insertan algunos metadatos; como la fecha de la última actualización.
Conclusión
El resultado final es un servidor capaz de consumir tratar información proveniente de Internet en tiempo real, fácil de desplegar y de ampliar gracias al uso de Docker.
Este artículo es parte de la serie relatando nuestra experiencia en la construcción del proyecto San Fermín en directo.