Caso real: Webicaster.com

Portada del podcast Drupalízate
Drupalízate es un podcast semanal creado por mí, donde hablo sobre desarrollo web basado en Drupal.
El contenido central es resolver las típicas dudas que pueda tener alguien que tiene o quiere tener una web en Drupal.
Aparte de resolver dudas de "clientes", también se habla de tips, recomendaciones y buenas prácticas para el Developer que recién empiezan en este mundo.
Audio y notas del episodio

En este episodio te comento todo el proyecto Webicaster.com por dentro.

Búsquedas y gráficos estadísticos con ElasticSearch, uso del módulo Flags, código custom y uso de paddle.com.

 

Para ver las estadísticas (se cogen de una base de datos postgres y se migran a Elasticsearch) puedes verlas en:

https://webicaster.com/es/stats

Transcripción automática de este episodio de audio (puede contener errores)

 Bienvenido o bienvenida aquí otra semana más en el podcast de Drupalizarte, donde yo, Robert Menetray, te cuento cosas que hago aquí en Drupal. Estamos en la serie de episodios hablando de casos reales, de proyectos míos propios, que para si llegas y no sabes de qué estoy hablando, escúchate episodios pasados, pero básicamente hablo sobre proyectos míos, de side projects míos, que no son de clientes míos, sino que son proyectos propios, básicamente por temas legales. Porque no puedo comentar depende de qué cosas, proyectos de clientes, pero como son proyectos míos pues puedo decir todo y cómo está hecho por dentro y no esconder nada. He dicho todo esto. Esta semana toca hablar sobre... por cierto, antes de nada, que me olvido, tema de feedback. Me podéis dar feedback en mi web, minetai.com, hay el mail de contacto o el formulario y me contactáis y me dais feedback por ahí, o en LinkedIn y en la newsletter, que también está en LinkedIn, me podéis poner un comentario por ahí y me decís qué cosas queréis que cuente yo en el podcast o si queréis que pueda mejorar o cosas que no cuento, pues esto, me dais feedback allí. Muchísimas gracias por el feedback. He dicho todo esto, ahora sí, esta semana toca hablar sobre Webicaster. Webicaster.com es un proyecto que hice yo, pues también hace como un año. Básicamente la definición más simple sería es un Tinder de podcasters, o sea tienes usuarios que son podcasters, gente que hace podcast, como yo ahora mismo, y gente que no tiene podcast, o sí, pero es gente que quiere ser entrevistada para aparecer en un podcast, con lo cual básicamente es una plataforma, es una web, donde se hacen match de usuarios. Usuarios que por un lado quieren ser entrevistados y usuarios que tienen un podcast donde entrevistan a gente. Así que la forma más simplista es un Tinder de podcasters. Esto, por supuesto, está montado con Drupal, en este caso no me acuerdo si fue un Drupal 8 o Drupal 9. Creo que es actualizadoría de Drupal 9, creo. ¿Por qué se ha montado con Drupal? Porque era un porfolio, un ejemplo de porfolio que creé yo mismo, y en el que quería sacar el juego, y una de las ventajas de este proyecto, o ventajas no, sería uno de los casos de uso, o mejor dicho, vamos a repasar los requisitos que me puse yo mismo. Primero sería, tiene que tener un buscador sí o sí de texto y facetado para filtrar por categorías, por ejemplo, pues si es podcaster o no, después en qué idiomas si es inglés o no, si el podcast es que puse duración, si tenías micrófono o no, o sea, si usabas un micrófono profesional, si se grababa en vídeo o podcast, o si se grababa el audio. Al final, cuatro características que permitiesen filtrar por filtros facetados. Esto no tiene ninguna dificultad, esto es poner el módulo search up y poner, en mi caso, le puse el elastic search, y con esto sin tocar el código ya tienes todo montado. Temas de frontend. Estuve probando con una de las plantillas que creo que en este caso no me acordaría de pago o gratuita, pero es una plantilla HTML, la adapté a Drupal y le cambié algún color, pero por cosas más, para hacer el mínimo frontend posible, porque una, no soy diseñador, y dos, no quiero perder tiempo en, digamos, tonterías de frontend cuando este proyecto, la verdad, si no es de frontend. Después, otro requisito, o sea, requisito de dedicar poco tiempo en frontend, otro requisito de lo de buscador, otro requisito era de que la idea inicial, que después se cambió, pero la idea inicial es que un usuario sólo puede contactar con otro usuario que haya hecho match, igual que Tinder. O sea, no puedes contactar con cualquier persona desde un inicio. Hazle darle me gusta y que la otra persona te de me gusta. Y si hay match, si los dos habéis dado me gusta, entonces podéis contactar. Esto como lo hago en Drupal y de la forma más simple, liviana y con apenas tocar código. Le estoy dando vueltas y al final lo usé con el módulo Flags. El módulo Flags, el Bandeas, no sé por qué se llama así la traducción, pero bueno, tampoco sé por qué se llama Flags, puedes flaggear, sería así, no sé si sería correcto, puedes marcar el, en este caso soy el nodos, que cada usuario puede quedar un nodo de soy podcaster y tengo este podcast o soy gente que yo que me equivocamente viste, a finales el usuario queda un nodo y otros usuarios pueden marcar, flaggear ese nodo de la persona. El marcador creo que le puse de palabra conectar o solicitar conexión o algo así. Y después sí que tuve que picar un poco de código de que en el evento de que alguien flaggea se haga una pequeña query y obtenga de la otra persona también lo ha flaggado mutuamente o no, pues en caso afirmativo envía un mail, básicamente enviaba un mail de que tienes una persona que te ha, que estáis en contacto. Y después tenía una virus que me permitía el listar las personas con las que ya había sido marcado, o sea matcheado, tenías un match con ella. Y después también había un pequeño código en el frontend, en el tweak, donde si había esa virus que devolvía resultados para el nodo actual te permitíamos, o sea se mostraba el formulario de contacto, si no, no. Con lo cual, reapeturemos, tengo el modulo flags que me permite tener toda la interacción de que el usuario pueda marcar o desmarcar, porque puede ser que quiera deshacer la conexión con otro usuario. Un pequeño código que en el evento del flag me envía un mail de, ¡hey! que alguien está interesado en ti. Y después en el frontend intento renderizar una virus y si la virus no se renderiza porque no tiene resultados, para filtrar contextualmente con el nodo actual que se está viendo, pues no se muestra el formulario de contacto. Si sí que tiene resultados porque sí que está flaggeado ese nodo con el usuario actual, pues se muestra el formulario y se permite el contacto, que se puso el modulo waveform. Con lo cual el código fue mínimo y permitía tener una funcionalidad que como requisito técnico inicial parecía tener todo el sentido del mundo. El problema es esto, que después nos dimos cuenta por el feedback de usuarios de que es un coñazo tener que esperar que alguien te marque y tú marcas a él, con lo cual esto a final se quitó. Con lo cual ya fue bien que se dedique hace poco tiempo y poco código custom a hacer todo esto, porque fue muy simple después desmarcar esto y de no no, no hace falta, se pone un límite en el formulario para que no puedes enviar mil formularios en un día, pero no hace falta tener una conexión mutua y el tiempo que me ahorré, y en mi caso es sólo tiempo, pero si fue para el cliente final, el coste que te ahorras de tener que desarrollar esto para el cabo de un mes con el feedback, decir de ay no, echemos marcha atrás, pues el tiempo es dinero. También pues hago este tipo de proyectos para aprender cosas que normalmente no hago con proyectos de cómo las haría si un cliente me pidiera hacer esto, y así tengo más claro por dónde tirar y el menor tiempo posible para gastar en esto, para que a cliente la estimación le salga más barata. Y básicamente poca cosa más tenía este proyecto, básicamente sí que después... perdón, sí, me dejo una cosa importante. A raíz de todo esto, por temas de marketing, lo que hice también fue escapear una base de datos de podcast, y después de cada uno de los podcasts que tengo en la URL del feed, lo que hacía es, en el feed de podcast está el mail del podcaster, no siempre, pero muchas veces sí, con lo cual obtenía los mails de los podcasters. Con base de los mails de los podcasters, después hice una lista... perdón, lo digo mal, con los mails de los podcasters y los datos que había escapeado, pude hacer unas estadísticas de cuántos podcasts han publicado este año, cuántos podcasts y cuántos episodios en los últimos meses se han publicado en tantos podcasts. De podcasts de más de cinco episodios hay tanto por ciento, de podcasts de más de 20 episodios hay tanto por ciento. O sea, así estadísticas gráficas, moronas, para compartir en redes, y con esto y los mails, enviaba un mail a los podcasters de, ¡ey mía! ¿qué he hecho estas estadísticas? Como no es un mail publicitario como tal, sino diciendo, ¡ey mía! ¿a qué estoy haciendo esto? ¿qué te parece? No se infringe el tema de la ley de GDPR y estas cosas. Pues ahí está en una zona gris, ahí en medio, porque básicamente no estoy vendiendo nada. Bueno, en total, con el tema de estadísticas, se montó DUPAL y un código custom de PHP, escapeaba los contenidos de los podcasts, lo metía todo en Elasticsearch para no, digamos, no hinchar la base de datos de MySQL con datos que no me interesa tener en DUPAL, así que todos los datos se metían directamente en Elasticsearch. En Elasticsearch, después, las consulas que se hacían agrupadas, eran para mostrar estadísticas, con lo cual se hizo un código custom de generación de estadísticas, que si un caso os voy a poner la ruta de la página de estadísticas para que veáis cómo queda y más o menos lo rápido que va. Son cuatro millones de podcasts, se está generando estadísticas en tiempo real de cuatro millones de podcasts, para que veáis la potencia que tiene Elasticsearch. Así que fue un proyecto en el que, primero, me interesaba el tema de cómo hacer match con usuarios, después, a mitad de proyecto, salió la idea de, no, vamos a escribear podcasts y vamos a hacer el tema de estadísticas con muchísimos datos y que por rendimiento no sea una patata, o sea, que no tarden diez minutos en generarme un gráfico. Y, básicamente, todo esto funcionó. Así que, raquí yo toqué el código custom, aprendí bastante del tema de agregaciones y hacer gráficos con Elasticsearch y nada, poca cosa más. Ah, y por cierto, la voz también es multidioma, pero esto ya será por supuesto, es en inglés y en español, ¿vale? Por cierto, el tema de multidioma, últimamente estoy trasteando, probando, de que detecte automáticamente el idioma del navegador del usuario. Bueno, básicamente esto, si el navegador del usuario está en español, la web automáticamente te redirige la versión española, si no, la versión en inglés. La única cosa que comentar es que tengo que añadir que si el navegador del usuario está en catalán, porque tengo la mayoría de mis conocidos son catalanes, pues que también te redirige a la versión española, porque en algún caso me redirigía la versión en inglés. El único tip que te puedo dar por temas de idiomas. ¿Por qué lo hago así? Por temas de que cuando lo completía por redes, es más fácil tener un único link que sea la página principal y que automáticamente, como no especifico idioma en el link, hace la redirección a español o inglés. Fue por el simple hecho este. Y como está funcionando bastante bien, en otros proyectos míos lo estoy aplicando igual. En proyectos de clientes, depende del caso, puede ser más recomendable tener la típica configuración que no hace una redirección automática, sino que tienes el barra en barra es y que por defecto siempre redirige a la idioma principal, pero que no detecte el idioma del navegador, porque en algunos casos puede ser más complicado, sobre todo cuando tienes webs con muchos idiomas. Pero bueno, que esto. Me sirven como laboratorio de pruebas para hacer pruebas de estas, que con un cliente real no le diría de no voy a probar a hacer las success para hacer estadísticas y no sé si puedo hacerlas, o no sé cómo ir a ver si están bien de rendimiento. Ya lo he hecho y sé que por rendimiento pueden trabajar con cuatro millones de podcasts, pues ahora me atrevo perfectamente a hacer una estimación y trabajar con Elasticsearch para hacer estadísticas. Dicho todo esto, ¿qué coste ha tenido esto? ¿Cuánto estoy pagando yo el servidor para hacer una web tipo, entre comillas, Tinder de macho de usuarios? Tener el tema de lo típico en tu parlogging de usuarios, web multidioma, después de un Elasticsearch para temas de búsquedas, el Elasticsearch para temas de estadísticas, la sección de blog también, que esto no lo comentaba porque también tiene un blog multidioma, donde se publican artículos que hace meses que no publico nada. Bueno, al final la típica web, digamos, de un SaaS. Ah, y por cierto, me olvidaba de esto. Tema de pasar a pagos. En este proyecto se instaló y se hizo custom un módulo, que a todo esto creo que no lo publicaron en tu parlogger.org y lo podía intentar arreglar un poco y publicarlo. De pasar a de pagos. En este caso en concreto no se usó Drupal Commerce, porque recarga mucho la web y para lo que quería yo, que es que el usuario pague y cuando paga se le asigna un rol y ya está, no me hace falta un e-commerce como tal. Dije, esto es demasiado, no voy a meter todo en e-commerce. Después, estuve investigando, esto ya no es de Drupal, sino es más de tema de emprendimiento. Si usa Stripe o otras plataformas de pagos, Stripe es el programa que tiene, yo pensando que lo petaría que tendría muchos usuarios que pagasen, Stripe no te gestiona las facturas como tal y tampoco te gestiona los impuestos, con lo cual es un marrón y es dedicado tiempo a gestión de facturas. Y dije, uy, esto es un marrón, mejor no. Y usé otra herramienta que es Paddle y básicamente es poner unos e-guarante y otra cosa más. Así que hice un pequeño módulo que implementa el tema de la pasada de pagos con Paddle y la gestión de que el usuario una vez está hecho el login, tiene su página con los datos que tiene Paddle y puede cambiar su suscripción. Al final es una gestión de suscripciones recurrentes mensuales. O sea que con Drupal, eso sí con código custom un poco, me permite la gestión de pagos recurrentes mensuales o anuales, porque la diferencia es ninguna. Vas a la configuración de Paddle y luego cambias allí y me permite los pagos. Y automáticamente si no se paga, se le quita al usuario el rol y si el usuario ha pagado correctamente se le asigna el rol que yo he configurado. En este caso no sé qué le puse porque tenía como dos o tres planes de pago. Dependiendo de lo que pagaba se asignaba un rol u otro. Y dependiendo del rol que tuviera en Drupal, pues podía haber un abuse o no o podía ser X cosas o no. Por ejemplo, el límite de mails, de formularios de contacto que podía enviar, era distinto. Al final el tipo de proyectos de tenga una membresía de pago con distintos roles, que dependiendo de lo que paguen pueden ser unas cosas u otras, en Drupal es, si tienes X roles, por configuración, puedes hacer X cosas. La dificultad es cómo detectar lo que ha pagado y cómo le asignas el rol. Con el Drupal Commerce, digamos que lo encuentro demasiado grande para este tipo tan simple de requisito. Así que como digo, no sé, te haré una mañana y ese pequeño módulo este que me conecta con Paddle. La ventaja de Paddle, que creo que no lo he dicho, es que te gestiona automáticamente él las facturas. El que cobra es Paddle. El que hace las facturas es Paddle, no soy yo. Y a final de mes, si alguien paga y se registra, y llega al mínimo que creo que es de 50 dólares, me emite una factura Paddle a mí con todo el monto acumulado. Con lo cual yo no tengo que hacer una gestión de facturas, solo cobro una vez con todo. Que en verdad no he cobrado nunca porque nunca he llegado al mínimo de 50 dólares con este proyecto. Este fue más de un proyecto de laboratorio de pruebas y probar cómo había esto. Si me viene un cliente y me dice que es que con una pasada de pagos de membresías no es tan complicado, no hace falta un e-commerce con tantas cosas. Algo más simple y que en una mañana se puede programar. Así que perfecto. Después que me he ido. Tema de servidor, ¿qué estoy pagando? Este es más pequeño que lo que tengo en mi aviso. Basicamente lo tengo también en Heznet, que como dije es una empresa alemana de servidores virtuales. Lo tengo en el Cloud de Heznet. Es un servidor con dos CPUs solo, 4 GB de RAM, sobre todo como ya dije en mi aviso porque el ASDIC me consume mucha RAM y un servidor pequeño de menos de 2 GB no me sirve, así que tuve que ampliar a uno de 4. Son dos CPUs, 4 GB de RAM, 40 de disco duro, que me sobra la verdad, y 20 TDR de transferencia, que me sobra muchísimo. ¿Cuándo me cuesta esto? 4,40 euros al mes. Se suman los backups, con lo cual serán 5 euros. 5 euros al mes por tener este tipo de web lo encuentro baratísimo. Y lo mismo que dije en el aviso, me sale tan barato porque me lo gestiono yo. Si fuera un cliente que no tengo ni idea o no quiero tener idea de gestión de servidores, pues me tocaría pagarle a alguien para que me lo gestione. En mi caso, para reducir costos, me lo gestiono todo yo, lo tengo todo dockerizado, muy similar a lo que tengo con el aviso. Tengo un docker para PHP, un docker de MayaDB, un docker de NGINX, uno de Redis también, lo tengo puesto, y el de las XR, creo que ya está. Intento que sea una web lo más optimizada posible pensando en rendimiento para que consuma lo mínimo posible, para que el servidor mensualmente me cueste lo mínimo posible. También es una web que tiene, digamos, poco tráfico. No tiene un tráfico... Sí que de vez en cuando entra un usuario, pero es mucho menor que lo que tiene el aviso, por ejemplo. El aviso sí que tiene un tráfico constante por SEO. WebCaster apenas tiene tráfico por SEO. Y creo que ya está. Pongo algo más. Esto es para que veáis lo que se puede llegar a hacer con un poco de código custom, sobre todo por el tema de pasar de pagos y por el tema de estadísticas. Aquí comentar una cosa que me olvidaba. El tema de estadísticas. Intenté usar... Hay módulos en Drupal que tracen estadísticas en base a las views. Hay sub módulos que puedes activar para que una view te lo pinte en formato gráfico. Con el estilo visual, por ejemplo, de los Google Charts. No conseguí que me funcionasen como yo quería. No hay mucha flexibilidad, digamoslo así, y no me generaba los gráficos que yo quería. Con lo cual por eso, a final, opté por hacer gráficos con código custom, que al final me está pintando un bloque y yo el bloque lo pongo donde yo quiero. Básicamente fue un motivo. Hubiese sido mucho más rápido, y lo intenté pero no pude, de usar un módulo que configuras una view y en la view se te pone que el cómo se hace de renderizar la view es con un gráfico de Google Charts para que visualmente se vean decentes. Lo hice por código y puse que también se renderice usando la API de Google Charts. Esto, si es un gráfico simplista, lo podrías hacer con Views Chart o algo así. No, es que tendría que buscarlo, no me acuerdo. Puesto que sepas que hay módulos que extienden al módulo Views y que te permiten pintar gráficos, pero que son para gráficos, digamos, limitados o simples. En mi caso no me servían. Y creo que ya está, es que esto que no me apunte no me haga un guion, después voy loco para grabar. Bueno, nada más. La semana que viene no sé de qué proyecto voy a hablar aún, tengo varios, pero seguramente si no me dais feedback de nada, por esto, voy a grabar de otro proyecto. Tengo uno que quizás sea interesante porque tiene ahora mismo, a día de hoy, 70 GB de base de datos, que a ver si lo arreglo y lo optimizo un poco. Pero es interesante comentar, sobre todo por el tema de volumen de datos a gestionar. Y nada más. Hasta la semana que viene, dadme feedback y buen finde.

¿Tienes algún proyecto en mente?

Si quieres hacer algo en Drupal tal vez puedas contratarme.

Ya sea para consultoría, desarrollo o mantenimiento de sitios web Drupal.