miércoles, 8 de noviembre de 2023

Amplitude: Entendiendo los tipos de medición en User Composition

El gráfico Composición de usuarios (User Composition) en Amplitude muestra el desglose de usuarios activos en función de una única propiedad de usuario. Este tipo de graficos en Amplitude proporciona información sobre quiénes son sus usuarios y qué propiedades comparten.

En la secciòn "Measured as" disponemos de 3 opciones para efectuar la medicion de la composicion "Most Recent Value", "All Values" y "Cross Property Values":

  1. Most Recent Value (Valor más reciente):
    Este enfoque considera únicamente el valor más reciente de una propiedad para cada usuario.

    - El valor se extrae del evento más reciente en el que el usuario participó.
    - Cada usuario aparecerá en solo un grupo en función de su valor más reciente.
    - Por ejemplo, si estás analizando la propiedad "País" y un usuario cambió su país de residencia, solo se considerará el país más reciente en el gráfico.
    - Otro ejemplo, si tienes una propiedad de usuario llamada “Plan de Suscripción” y un usuario cambia de un plan gratuito a uno de pago, el valor más reciente de esa propiedad reflejará el plan de pago.

  2. All Values (Todos los valores):
    Aquí se incluyen todos los valores que tus usuarios activos han tenido para la propiedad en cuestión durante el período de análisis.
    - Ten en cuenta que el gráfico de User Composition solo incluye usuarios activos, por lo que los valores de propiedades relacionados con eventos inactivos no se tendrán en cuenta.
    - Si un usuario ha tenido varios valores para una propiedad a lo largo del tiempo, todos esos valores se considerarán en este enfoque.

  3. Cross Property Values (Valores cruzados de propiedades):
    Este enfoque muestra conjuntos de propiedades que los usuarios activos han tenido dentro del rango de tiempo seleccionado.
    - Los grupos son mutuamente excluyentes, lo que significa que un usuario solo puede caer en un grupo.
    - Por ejemplo, si estás analizando las propiedades "Género" y "Edad", los usuarios se agruparán según combinaciones específicas de género y edad.

viernes, 13 de octubre de 2023

Enmascarar email con Javascript

Cuando se trata de proteger la privacidad en línea, ocultar direcciones de correo electrónico es una práctica común. En este breve artículo, exploraremos el uso de expresiones regulares (regex) en un ejemplo de código React para lograr este propósito. Vamos a analizar el siguiente código:
import { useState } from "react";

const email = "my.custom.email@domain.com";
const regex = /(\w{3}).*/g;

export function App() {
  const [hide, setHide] = useState(false);
  const renderEmail = hide
    ? email.replace(regex, "$1********@********")
    : email;

  return (
    <div>
      {renderEmail}
      <br />
      <button
        type="button"
        onClick={() => {
          setHide((prev) => !prev);
        }}
      >
        {hide ? "Show email" : "Hide email"}
      </button>
    </div>
  );
}

Desglose del Regex:

En este código, se utiliza la expresión regular /(\w{3}).*/g para ocultar parte de la dirección de correo electrónico. Desglosemos cada parte:
  • /: Delimita el inicio y el final de la expresión regular.
  • (\w{3}): Captura los primeros tres caracteres de la dirección de correo electrónico y los almacena en el grupo de captura $1.
  • .*: Coincide con el resto de la dirección de correo electrónico.

Desventajas y solución:

Aunque esta técnica puede ser efectiva, presenta algunas desventajas:
  • Dependencia del lado del cliente: Este enfoque depende del código ejecutándose en el lado del cliente, lo que significa que no proporciona una solución integral de seguridad. Recuerda que la seguridad es un tema complejo, y estas soluciones deben usarse con precaución y en combinación con otras medidas de seguridad.
  • Limitado a direcciones específicas: Este regex asume que las direcciones de correo electrónico siempre tendrán al menos tres caracteres antes del símbolo '@', lo cual puede no ser cierto en todos los casos. Aquí propongo dinamizar la captura de los elementos con regex de la siguiente manera:
const regex = /(.*)@.*/g;
const renderEmail = hide
    ? email.replace(regex, (match, group1) => {
        const usernameLength = group1.length;
        return `${group1.substring(0, usernameLength / 2)}${'*'.repeat(usernameLength / 2)}@${'*'.repeat(6)}`
})
    : email;
    • Se define una expresión regular (/(.*)@.*/g) que busca una cadena que tenga algún texto antes y después del símbolo '@' en una dirección de correo electrónico.
    • Luego, el reemplazo se realiza tomando el texto antes del símbolo '@' y reemplazando la segunda mitad de ese texto con asteriscos. También se reemplaza la parte después del '@' con asteriscos.

Configurar correo Gmail corporativo con Thunderbird

Thunderbird
Thunderbird

Thunderbird, el cliente de correo electrónico libre y de código abierto, está de vuelta con un nuevo enfoque. La nueva versión de Thunderbird, que se lanzó en octubre de 2023, presenta un nuevo diseño, nuevas funciones y un nuevo enfoque en la privacidad y la seguridad.

Cómo agregar una cuenta de Gmail corporativo a Thunderbird

Agregar una cuenta de Gmail corporativo a Thunderbird es un proceso relativamente sencillo. Sigue estos pasos:

1. Asegúrate de que tu cuenta de Gmail corporativo esté habilitada para IMAP. Para activar IMAP en la consola de administración, ve a https://gmail.com/ y haz clic en Settings (icono de engranaje ubicado en la parte superior derecha)See all settingsForwarding and POP/IMAP. Asegúrate que IMAP está activado (IMAP is enabled). Activar en caso de que no lo esté.

Activar IMAP en Gmail


2. Abre Thunderbird.

3. En Thunderbird, haz clic en Settings > Account Actions > Add Mail Account.


Agregar cuenta de correo en Thunderbird

4. Introduce el Nombre de tu empresa, tu dirección de correo electrónico de Gmail corporativo, (la contraseña aún no):

Llenar formulario inicial de agregar cuenta en Thunderbird

5. La misma contraseña para correos corporativos no puede ser usada para iniciar sesión en Thunderbird, en este caso, debemos usar una contraseña alterna que debemos crear a continuación. Para ello, usaremos la guía oficial que ofrece Google:

|. Ve a tu Google Account.

2.  Seleccionar Seguridad (o "Security"). 

3. Debajo de la sección "Signing in to Google," selecciona "2-Step Verification" (y proceder con la autenticación que Google solicite)

Verificación de dos pasos 

 4. Al final de la pagina, seleccionar "App passwords" o "Contraseñas de aplicaciones".

Botón final de contraseñas de aplicaciones

5. Ingrese un nombre que te ayude a recordar la contrasña de la aplicacion.
6. Seleccionar Generar. 
7. Copia la contraseña que aparece en tu pantalla. La contraseña tendrá 16 caracteres y no debe ser compartida jamás.
Contraseña de aplicación generada (demo)

6. Volviendo a Thunderbird, necesitaremos pegar la contraseña de aplicación generada anteriormente en el campo de Contraseña o Password.

Pegando contraseña de aplicación de Google en Thunderbird

7. Configurar manualmente los parámetros restantes siguiendo las instrucciones de soporte de Google:

Incoming Mail (POP) Server

pop.gmail.com

Requires SSL: Yes

Port: 995

Outgoing Mail (SMTP) Server

smtp.gmail.com

Requires SSL: Yes

Requires TLS: Yes (if available)

Requires Authentication: Yes

Port for TLS/STARTTLS: 587

If you use Gmail with your work or school account, check with your administrator for the correct SMTP configuration.


Configuración manual de los protocolos para Incoming & Outgoing Server


8. Clic en Re-test y luego en Done, Thunderbird se conectará a tu cuenta de Gmail corporativo y sincronizará tus correos electrónicos, contactos y calendario.

viernes, 15 de septiembre de 2023

No pude hacer pan de trigo pero si pan de yuca

¡He conseguido hacer exitosamente pan de yuca, este es mi pan favorito! Me encanta demasiado este pan y tenía que aprender a prepararlo, pero antes de preparar este pan tuvieron que pasar varios días y 3 intentos fallidos para hacer pan. El primer intento hice la masa con su respectiva levadura, queso, harina de trigo, sal y azúcar, la amasé un par de minutos y la dejé en reposo para que la levadura se activara. 1 hora después la masa seguía igual y no había crecido ni un milímetro, sabía que algo andaba mal, pero como era mi primer pan decidí meterlo al horno, después de 60 minutos había hecho un desastre, por fuera se miraba fenomenal, pero por dentro la masa estaba dura y fea. Ese día con mucho dolor tuve que tirar a la basura todo el resultado, nadie comería ese pan.

Supe que en ese primer intento mi error fue no dejar activar la levadura, así que para el segundo intento usé los mismos ingredientes, pero esta vez amase por mucho más tiempo y usé otra levadura porque quizás la que tenía en casa estaba dañada, también recurrí a un método que encontré en internet que consiste en dejar que la levadura se active por separado en un mínimo de harina de trigo con agua tibia, luego este se revuelve con el resto de la masa y esperé que la levadura se activara, 2 horas después noté que la levadura había hecho efecto, pero era muy mínimo e insuficiente, aun así decidí continuar y hornear. El resultado fue otro desastre, aunque no tanto como el 1.er intento, esta vez pude comer pan, pero solo las partes que quedaron parcialmente bien, el resto tuve que botarlo, intenté darlo a las aves a través de la ventana de mi casa y ni las palomas quisieron comerlo.

Mis dos intentos anteriores siempre los hice en la tarde, pensé que quizás si empezaba desde temprano a preparar la masa podría dar el tiempo suficiente para activar la levadura, para este momento recién había aprendido que la levadura se activa dependiendo de la temperatura ambiente y que en zonas de frío es muy difícil, así entendí que por esta razón fallaba mi proceso, pues donde estoy la temperatura por lo general está bajo los 16 grados centígrados. Sabiendo esto, decidí hacer un tercer intento, esta vez amasando la masa por mucho tiempo y dejando la masa esperando que la levadura se activara durante muchas horas, también intenté replicar un ambiente húmedo y temperatura ideal para la levadura poniendo el horno a una temperatura de 25 grados más o menos y con agua en el fondo del horno en otro recipiente para intentar humedecer el interior del horno. En la tarde noche decidí hornear lo que sería el 3.er desastre.

Frustrado de no poder hacer pan, pero sabiendo que principalmente la falla fue activar la levadura, decidí parar mis intentos de hacer pan de trigo. Tuve una charla con una amiga que sabe hacer pan y le he comentado todos los problemas que tuve, ella me ha sugerido hacer pan de yuca porque no requiere activar la levadura, cuando escuché eso mi cerebro se iluminó y rápidamente recuperé mis esperanzas de hacer pan. Al siguiente día fui a la tienda y compré 1 libra de almidón de yuca, 500 gramos de queso campesino y 1 litro de leche entera para luego comenzar a preparar el pan, lo amase con otros ingredientes que ya tenía en casa y deje un rato que la levadura se activara, obviamente sabía que no lo lograría, pero había que intentarlo una última vez. Como imaginarán, ningún hongo de levadura se movió, todo siguió igual, la masa no había crecido ni cambiado de color, pero esto no me importaba en absoluto porque sabía que para este pan eso no era muy relevante. Hice las bolitas de pan con las manos, y lo dejé sobre la bandeja de latón que previamente había preparado con mantequilla en la superficie para evitar que se pegara el pan. Después de 20 minutos de horneado ya había logrado hacer por primera vez pan de yuca, quedó esponjoso y muy delicioso, todo perfecto, excepto que durante el horneado el pan creció tanto que se pegaron los unos con los otros. Tengo pendiente hacer una segunda versión mejorada, esta vez con las bolitas de pan más pequeñas y más separadas para evitar que se peguen.

miércoles, 16 de agosto de 2023

Tras la huella del Error: Cómo Solucioné un Problema de Render en React

Ayer, miércoles 16 de agosto, desde el equipo de QA me llegó un reporte de un error en uno de los desarrollos que había realizado, un error atípico y difícil de diagnosticar. Estuve en la mañana colocando Logs y debuggers por todos lados, los componentes afectados en los últimos cambios aparentemente no mostraban inconsistencias y renderizaciones fuera de lo normal. Pude replicar el error, pues sucedía al desplazarme por una serie de Tabs y el contenido correspondiente a cada Tab provocaba bloqueos en el sitio web. Usar la extensión React Devtools era imposible, pues al tener un error de bloqueo total de la pagina no era posible navegar, inspeccionar y usar extensiones de Chrome durante el crash.

Al tener un bloqueo de la pagina web es común pensar en una serie de excepciones que van rompiendo todo, también es cierto que en un contexto de desarrollo web puede tratarse de iteraciones indefinidas de un mismo elemento, componente o función, por eso, al llegar a la conclusión de que el problema debía ser un renderizado incontrolado de algún componente de React esta debía ser la sospecha #1.

Primer intento

Revisión superficial del problema y diagnostico inicial. Los nuevos cambios involucraban llamados a diferentes Queries de Grahpql y renderizado de componentes nuevos, por ello fue necesario validar los siguientes puntos:
  • Peticiones: Desde el navegador web, abrir el inspeccionador de elementos e ir hasta el Tab "Red" (o "Network" en Inglés) para validar que no existan llamados recurrentes e innecesarios de los queries de Graphql.
    • Resultado: Todo a la normalidad.
  • Errores en consola: Revisar que no se tengan errores o advertencias en la consola del navegador (Tab "Consola").
    • Resultado: Todo a la normalidad.
  • Profiling: Intentar hacer Profiling de los componentes de React usando la extension React Devtools.
    • Resultado: No se pudo realizar profiling debido al bloqueo de la pagina al momento de activar la opción cuando el bug se había presentado.
  • Error Boundary: Agregar como padre uno de los componentes custom llamado ErrorBoundary que sirve par capturar errores en los componentes hijos.
    • Resultado: No hubo errores, por lo tanto ErrorBoundary estaba puesto en vano.

Segundo intento

Lo primero que debía hacer era descartar que se trataba de un error en los componentes principales, por eso, el segundo intento para detectar el problema fue abrir el inspeccionador de elementos de Google Chrome y desde la opción de "Fuentes" (o "Sources" en Inglés) activar la casilla "Detenerse cuando se detecten excepciones". Una vez activada la detección de excepciones se procede a navegar en el sitio web para desencadenar todo tipo de excepciones sea cual sea que ocurran durante la navegación, así cuando el Bug se presente lo podremos ver en cuestión (siempre y cuando arroje una excepción).

Un par de horas después, había realizado el proceso de depuración de varios errores, encontrando y solucionando algunos problemas mínimos con la ayuda del step-by-step del inspecionador del navegador web. Este primer intento se consolida al detectar varios errores provocados por la carga Lazy Load de algunos componentes de React, sin embargo, tenia que intentar esta opción a pesar que no sirva para detectar errores de renderizado infinito en React. En conclusión, este segundo intento me sirvió para encontrar puntos de mejora y validaciones extra, pero no para hallar el problema real.

Tercer intento

Después de despejar la mente, almorzar y caminar un rato por la calle, volví a casa, hice masa de pan y la puse en un recipiente para que la levadura se activara y la masa creciera, luego abrí el sitio web de Mercado Libre (o MELI) para buscar algunos productos de intereses, y al cabo de unos minutos no había comprado nada pero si me encontraba inspeccionando el sitio web con la extension de React Devtools, encontré que algunos componentes de MELI se están renderizando de forma innecesaria con solo hacer unas pocas acciones como un hover, también vi que usan servicios Graphql y las traducciones de los productos vienen desde Backend.

En fin, durante esta inspección he terminado descubriendo de forma accidental y activando la casilla "Highlight updates when components render" ubicada en "React Developer Tools > View Settings > General > Highlight updates when components render". Activar la visualización de cambios me permitió ver cada update en los componentes de MELI, esta característica resultó ser muy útil para identificar qué componentes se están actualizando durante la navegación en el sitio web.


Una vez encontrada y activada esta característica, seguí indagando sobre el problema inicial. Durante el primer diagnostico, al intentar hacer Profiling durante la replicación del problema no se lograba iniciar y procesar debido al bloqueo de la pagina, provocando un colapso de todo el sitio web e impidiendo realizar cualquier acción, la única salida era el cierre forzado de la pestaña del navegador, sin embargo, una vez dejando activada la visualización de cambios podía navegar por el sitio web y luego replicar el problema para poder observar segundos antes del colapso qué componentes se estaban renderizando de manera descontrolada. Y así fue que logré identificar el componente a corregir.

Todo se resumió a un problema, regeneración de referencias de objetos que pasan como props a otros componentes. Los componentes recibían estos props y realizaban una acción con un useEffect, este luego realizaba otra acción que cambiaba la referencia de una de sus dependencias, y así sucesivamente hasta el final de los tiempos. Esto provocaba una cantidad de iteraciones indefinidas en el ciclo de ejecución de un componente, haciendo que a su vez los componentes hijos también sufrieran un re-renderizado. En fin, todo esto ocurrió al trabajar en la versión "16" de React, en las versiones posteriores también deben haber problemas de infinite loops en useEffects pero se deberían controlan mejor para evitar crashes en el sitio web.

Conclusiones

  • La Persistencia en la Depuración: A pesar de la complejidad y frustración inicial, aprendí la importancia de persistir en la depuración y no rendirte ante problemas difíciles de diagnosticar.
  • Enfoque Iterativo: Descubrí que abordar un problema técnico de manera iterativa, probando diferentes enfoques y herramientas, puede llevar finalmente a la identificación y resolución del problema.
  • Exploración de Herramientas de Desarrollo: Mi experiencia mostró la utilidad de aprovechar al máximo las herramientas de desarrollo disponibles, como el inspector de elementos y las extensiones como React Devtools, para analizar y entender el comportamiento de tus componentes.
  • Descubrimiento Casual: A veces, los descubrimientos más valiosos pueden surgir de manera casual. El hallazgo accidental de la opción "Highlight updates when components render" ilustra cómo explorar diversas características puede revelar soluciones inesperadas.
  • Control de Referencias y Ciclos de Vida: Aprendí sobre la importancia de controlar las referencias y las actualizaciones en los componentes de React, especialmente al trabajar con efectos en el ciclo de vida de los componentes.

Amplitude: Entendiendo los tipos de medición en User Composition

El gráfico Composición de usuarios ( User Composition ) en Amplitude muestra el desglose de usuarios activos en función de una única propi...