En los últimos meses, han surgido varias solicitudes en diversos grupos de Discourse para mejorar el análisis de correos electrónicos entrantes. Expresadas como historias de usuario, estas peticiones pueden clasificarse ampliamente de la siguiente manera:
- «Me gustaría tener la capacidad de utilizar las mismas funciones HTML al responder por correo electrónico que las que puedo usar al publicar en el sitio web».
- «Me gustaría poder ver y buscar los mensajes de nuestra lista de correo».
- «Me gustaría que el contenido creado por correo electrónico, tanto mediante respuestas por correo como mediante importación masiva, estuviera siempre bien formateado y se analizara con precisión».
A continuación enlazaré ejemplos reales de estas solicitudes, pero por ahora lo importante es entender que cada una de estas tres peticiones «diferentes» en realidad busca lo mismo: un análisis más preciso de los correos electrónicos entrantes.
Hace unos meses envié un correo a @sam sugiriendo que Discourse utilizara la API de análisis de correo electrónico comercial que ofrece nuestra empresa. Sam me sugirió crear un post exploratorio aquí para explicar los beneficios que aportaría la integración con nuestra API en comparación con la solución actual de análisis de correos entrantes de Discourse, y también cómo podría integrarse nuestra API como un complemento.
Abordaré ambos temas en detalle, comenzando por el estado actual de la solución de análisis de correos de Discourse. Y, para beneficio de quienes no han pasado los últimos años pensando en el análisis de correos, también incluiré algo de contexto sobre el problema.
Este post es bastante largo, pero siéntete libre de saltar entre secciones. Aquí está lo que se cubrirá:
- El estado actual del análisis de correos en Discourse
- Los beneficios de un mejor análisis de correos
- Personajes de usuario de las partes interesadas
- La API de análisis de correos de FWD:Everyone
A. Eliminación de firmas y respuestas
B. Normalización del marcado HTML
C. Soporte de idiomas
D. Estilizado con CSS - Integración propuesta
- Pruebas de la API
El estado actual del análisis de correos en Discourse
Discourse ya cuenta con una función de respuesta por correo electrónico que convierte las respuestas de los usuarios en nuevas publicaciones del foro dentro de un tema. Esta función funciona de la siguiente manera:
- Un usuario recibe una notificación por correo electrónico que contiene una nueva publicación en un tema del foro que está observando.
- El usuario responde a ese correo.
- Esta respuesta por correo se convierte en una nueva publicación en el tema del foro correspondiente.
Conceptualmente, esta es una función invaluable; es el flujo de trabajo preferido por muchas personas y es imprescindible para muchas comunidades basadas en listas de correo que están considerando migrar a Discourse.
El problema es que, cuando estas respuestas por correo se convierten en publicaciones del foro, a menudo se representan con formato incompleto o incorrecto, o incluso con texto faltante. Esto es profundamente problemático, por razones que exploraré a continuación.
Los problemas comunes incluyen:
- Viñetas que no se representan correctamente
- Saltos de línea faltantes entre el texto
- Saltos de línea adicionales entre el texto
- Texto escrito por el usuario eliminado por completo
Y cuando digo que estos problemas son comunes, no me refiero a que ocurran ocasionalmente al enviar correos en idiomas extranjeros utilizando clientes de correo poco comunes. Me refiero a que ocurren frecuentemente al enviar mensajes básicos de respuesta por correo desde Gmail y Outlook en inglés.
Aquí hay dos ejemplos reales de usuarios que se quejan de estos problemas, ambos de la lista de correo [Python-Dev]:
https://www.prettyfwd.com/t/Wco-c1ZCR7mUwiww0j6s9w/#message-5
https://www.prettyfwd.com/t/Wco-c1ZCR7mUwiww0j6s9w/#message-36
(Prettyfwd utiliza la API de análisis de correos de FWD:Everyone.)
Aunque no he probado la importación de contenido desde listas de correo existentes con Discourse, puedo afirmar por experiencia que, sea cual sea la tasa de error para las respuestas por correo, la tasa de error al representar hilos completos de correo será al menos un orden de magnitud mayor. Esto se debe a la mayor complejidad al eliminar firmas y respuestas, tener en cuenta las respuestas en línea, lidiar con marcado profundamente anidado, etc.
Como ejemplo real, esta retrospectiva de migración de Mailman a Discourse, escrita por Tanya Lattner (presidenta de la fundación LLVM), alude a estos problemas en la sección de preocupaciones técnicas:
Pregunté y resulta que lo que específicamente les molesta es el alto porcentaje de correos que carecen de contenido debido a un corte prematuro. Dado que las discusiones y documentación previas de los últimos 19 años del archivo de la lista de correo son invaluables, sienten que no podrán dejar de usar Mailman hasta que este problema se resuelva por completo.
Entonces, ¿cómo sabemos si el estado actual del análisis de correos en Discourse es «suficientemente bueno»? Ofrecería esto como una prueba de tres partes:
- Los usuarios deben confiar plenamente en que, si utilizan la función de respuesta por correo, su contenido se analizará con precisión y se verá tan bien como si lo hubieran publicado a través de la interfaz web.
- Los administradores del foro deben confiar en que, si permiten la respuesta por correo, esto no generará trabajo adicional ni quejas.
- Los empleados de Discourse deben confiar lo suficiente en la función como para promoverla activamente como una forma de primer nivel de participar.
A menos que podamos afirmar con total confianza que se cumplen cada una de estas condiciones, incluso si la respuesta por correo existe como función, la gran mayoría de los beneficios potenciales nunca se materializarán.
Esto es lo que está ocurriendo actualmente.
Es decir, caracterizaría el código existente de análisis de correos como una solución 80-20, pero en un contexto donde una solución 80-20 realmente no tiene sentido; el problema es que, incluso si, por ejemplo, el 80 % de los correos se analizan correctamente, es poco probable que obtengas ni siquiera el 10 % de los beneficios potenciales.
Así que, aunque la respuesta por correo (y la importación masiva de correos) ya existen, los usuarios finalmente no obtienen la experiencia que buscan, se genera trabajo adicional para moderadores y personal, las comunidades pierden contenido valioso y crecimiento de usuarios, etc.
Los beneficios de un mejor análisis de correos
El software social solo tiene éxito en la medida en que satisface las necesidades humanas.
Las razones por las que la gente publica en foros web incluyen querer compartir conocimientos con otros, querer influir en sus opiniones, querer ser vistos como generalmente inteligentes, como expertos en un dominio, como quienes aportan contribuciones valiosas en el mundo real, etc.
Y cuando se trata de comunicación basada en texto, la probabilidad de lograr estos resultados depende no solo de lo que se dice, sino también de la tipografía con la que se dice.
Por eso hay libros enteros sobre el espacio en blanco en Shakespeare. Es en parte por lo que el New York Times se toma más en serio que el New York Post. Y es una gran parte de la razón por la que Facebook venció a MySpace.[1]
Cuando el texto que escribe un usuario termina mal formateado sin culpa alguna de su parte, las necesidades humanas que impulsan a las personas a usar software social ya no se satisfacen. De hecho, está ocurriendo lo contrario; los usuarios parecen estúpidos.
Incluso quienes no utilizan la función de respuesta por correo terminan perdiendo autoridad y respeto si otras publicaciones en el tema (y en el foro en general) terminan pareciendo un desastre.
Personajes de usuario de las partes interesadas
Aunque todos se benefician cuando las publicaciones se representan consistentemente con una tipografía estéticamente agradable, los personajes de usuario que pueden beneficiarse especialmente de un mejor análisis de correos entrantes incluyen:
- Personas que actualmente son miembros de listas de correo como [Python-Dev] y [Django-Dev], quienes comprenden plenamente los beneficios de Discourse y están contentos de ver que sus comunidades se muden a Discourse, pero solo si pueden continuar participando de una manera indistinguible de GNU Mailman, Google Groups, etc. Aquí hay un ejemplo real de este tipo de solicitud: https://www.prettyfwd.com/t/Wco-c1ZCR7mUwiww0j6s9w/#message-89
- Miembros de comunidades basadas en correo electrónico que generalmente estarían encantados de migrar a Discourse, pero que estarían mucho más entusiasmados con hacerlo si sus décadas de contenido existente fueran fácilmente buscables desde la misma plataforma.
- Usuarios casuales que revisan los foros de forma intermitente. Por ejemplo, en Growing Fruit estoy suscrito por correo electrónico a todos los temas sobre el cultivo de papayas norteamericanas. Durante el verano y el otoño visito ese foro varias veces al día para leer el flujo constante de nuevas publicaciones en estos temas, pero fuera de estos meses son principalmente las notificaciones por correo electrónico en estos temas las que me mantienen comprometido.
- Personas que solo usan la web de forma intermitente. A menudo se asume que, si la gente no usa la web regularmente, tiene algo que ver con la brecha digital, pero a menudo no es así. Hay muchas personas que son altamente inteligentes y técnicas, pero que están aisladas de la necesidad de usar la web regularmente debido a estar en la cima de sus campos. Un ejemplo del mundo real aquí es alguien como Donald Knuth, quien no usa la web regularmente a pesar de ser uno de los principales científicos de la computación vivos. Cada campo tiene personas como esta, y lograr que compartan sus conocimientos es invaluable. En mi experiencia, es poco probable que estas personas se conviertan en contribuyentes regulares de cualquier foro, pero si alguien les dice que hay un tema del que la gente está hablando que les interesaría, a menudo se suscribirán por correo electrónico y contribuirán a esos temas específicos.
La imagen general es que mejorar el análisis de correos entrantes no solo debería aumentar la participación de quienes ya son contribuyentes activos regulares de Discourse, sino también desbloquear a muchas comunidades que de otro modo querrían migrar a la plataforma, y también solicitar contenido altamente valioso de personas que de otro modo no contribuirían.
La API de análisis de correos de FWD:Everyone
La API de análisis de correos de FWD:Everyone hace dos cosas:
- Elimina con precisión firmas y respuestas de cada mensaje de correo, permitiendo al mismo tiempo respuestas en línea a texto citado.
- Toma el marcado HTML extremadamente complejo generado por los clientes de correo y normaliza ese marcado en las ~12 etiquetas HTML que generalmente están permitidas en sitios de contenido generado por usuarios, todo ello preservando la intención del autor en la mayor medida posible.
Explicaré ambos con más detalle, pero primero aquí hay un video que hice que explica el problema mostrando hilos de correo reales: https://www.youtube.com/watch?v=nPb3NQlz6V4
Eliminación de firmas y respuestas
La API de análisis de correos de FWD:Everyone funciona tanto con correos de texto plano como con HTML con igual precisión. La API utiliza preferentemente la parte del mensaje HTML cuando está disponible, porque
- Las funciones de formato HTML (como negrita, cursiva, citas en bloque, fragmentos de código, etc.) que el autor elige usar son una parte esencial del mensaje del autor, tan importantes como el texto en sí.
- Cuando los clientes de correo convierten la versión HTML de un mensaje a la versión de texto plano, a menudo lo hacen incorrectamente. Por ejemplo, no solo los clientes de correo a menudo no intentan representar funciones HTML como listas con viñetas en texto plano, sino que a menudo el texto dentro de los elementos de formato HTML está completamente ausente.
Por supuesto, algunos usuarios prefieren enviar correos de texto plano; debido a esto, los correos que solo contienen texto plano deben tener sus firmas y respuestas eliminadas con igual precisión.
La API de análisis de correos de FWD:Everyone hace esto, incluyendo el manejo correcto de respuestas en línea tanto en correos de texto plano como en HTML.
En términos de precisión, hay dos tipos de errores que pueden ocurrir en cualquier biblioteca de análisis de correos al eliminar firmas y respuestas:
- Falsos positivos — Cuando el texto que debe incluirse en el mensaje se excluye incorrectamente.
- Falsos negativos — Cuando el texto que no debe incluirse en el mensaje se incluye incorrectamente.
Es difícil dar estadísticas precisas de precisión porque diferentes comunidades de Discourse (con minúscula) utilizan el correo de manera muy diferente. Pero en comparación con la solución actual de análisis de Discourse, una expectativa realista podría ser:
- 100 veces menos falsos positivos al eliminar firmas y respuestas
- 10 veces menos falsos negativos al eliminar respuestas
- 1 a 10 veces menos falsos negativos al eliminar firmas: probablemente mejor, pero no un orden de magnitud completo.
Para contextualizar, los falsos positivos son generalmente mucho peores que los falsos negativos, ya que distorsionan lo que la persona escribió. Pero los falsos negativos también son muy malos, ya que hacen que el autor (y todos los demás en el foro) parezcan poco profesionales en el mejor de los casos, y directamente estúpidos en el peor.
El enfoque que adopta FWD:Everyone es evitar cualquier truco para eliminar firmas que pueda conducir a falsos positivos; el supuesto aumento de falsos negativos que esto provocaría se equilibra en gran medida simplemente habiendo dedicado mucho más trabajo a hacer que el algoritmo funcione de manera legítima, sin necesidad de tomar atajos.
La razón principal por la que la API de análisis de correos de FWD:Everyone será generalmente mucho más precisa que la solución actual de Discourse es que nuestra API fue diseñada para analizar hilos completos de correo, lo cual es un problema mucho más difícil que analizar publicaciones individuales de respuesta por correo. El resultado final es que nuestro producto está altamente sobreingenierizado, al menos en relación con las necesidades de Discourse y con la literatura previa existente.
Normalización del marcado HTML
Para que las respuestas enviadas por correo electrónico (y los hilos de correo importados) se vean iguales que cualquier otro contenido generado por usuarios, deben representarse finalmente utilizando el mismo subconjunto de HTML que se permite cuando los usuarios responden a través del sitio web.
Esto es sorprendentemente complicado.
Los correos redactados en clientes de correo como Gmail y Outlook se codifican utilizando alguna combinación de ~50 etiquetas HTML, ~25 atributos HTML y ~175 estilos CSS. Además, este marcado a menudo está fuertemente ofuscado; podrías esperar que un párrafo de texto se vea algo así:
<p>¡Algun texto!</p>
Pero en su lugar, incluso los párrafos simples a menudo se codifican utilizando combinaciones profundamente anidadas y completamente sin sentido de divs, spans, tablas, listas, etc. Esta es la principal fuente de complejidad tanto para eliminar respuestas como para normalizar el marcado.
Independientemente, después del análisis, cada mensaje se representa utilizando únicamente el siguiente marcado:
Elementos de bloque permitidos: <p>, <ul>, <ol>, <li>, <blockquote>, <pre>
Elementos en línea permitidos: <code>, <a>, <b>, <i>, <u>, <s>, <span>
Notas:
- Los únicos atributos permitidos (excepto en las etiquetas
<a>) son'style'y'dir'. - El único estilo en línea permitido es
'font-weight'. - Las etiquetas
<a>también pueden tener los atributos'href','rel','title'y'target'. - Los elementos
<span>se utilizan solo en casos limitados para asegurar que los pesos de fuente se propaguen correctamente. Por lo tanto, siempre se utilizan con un'font-weight'en línea. - En el futuro, la etiqueta
<img>también se utilizará para mostrar imágenes en línea.
Representar publicaciones en este subconjunto limitado de HTML permite que cualquier publicación enviada por correo se represente fácilmente utilizando exactamente la misma tipografía que las publicaciones enviadas a través de la interfaz web.
Todo esto se hace preservando la intención del autor en la mayor medida posible, al mismo tiempo que se asegura de que no puedan hacer cosas como agregar docenas de saltos de línea innecesarios entre párrafos.
Véase también: la sección «Estilizado con CSS» a continuación.
Soporte de idiomas
EmailReplyTrimmer actualmente tiene soporte total o parcial para 13 idiomas:
Inglés, noruego, francés, alemán, portugués, español, italiano, neerlandés, sueco, chino, ruso, polaco, ucraniano
En cambio, la API de análisis de correos de FWD:Everyone actualmente soporta más de 30 idiomas, incluyendo todos los idiomas que Discourse soporta actualmente:
Inglés, español, portugués, catalán, neerlandés, francés, alemán, italiano, noruego, danés, sueco, finlandés, ruso, polaco, ucraniano, turco, checo, rumano, húngaro, hebreo, árabe, persa, chino, japonés, coreano, hindi, indonesio, tailandés, filipino, afrikáans
La API de análisis de correos de FWD:Everyone soporta completamente los idiomas RTL (de derecha a izquierda). Esto significa que no solo el texto fluirá correctamente de derecha a izquierda en idiomas como el árabe, sino que también se aplicarán los atributos apropiados al marcado HTML para que funciones como las viñetas se representen en el lado correcto de la página.
La API a veces también funcionará en idiomas adicionales dependiendo del cliente de correo utilizado, pero el conjunto oficial de idiomas soportados se ha probado como mínimo para funcionar con Gmail, Outlook y Apple Mail. Los clientes de correo menos populares se prueban explícitamente en los idiomas donde tienen mayor uso. Y dado que la API se prueba contra miles de hilos de correo de listas de correo públicas, hay innumerables correcciones para comportamientos erráticos del mundo real de origen desconocido.
Nota: que soportar una amplia variedad de idiomas es importante no solo para mostrar texto en esos idiomas. Es muy común que las personas escriban texto en inglés, pero tengan su cliente de correo configurado para usar, por ejemplo, hebreo. Por lo tanto, en casos como este, analizar correctamente una respuesta en inglés requeriría no solo soportar completamente el hebreo, sino también soportar idiomas de derecha a izquierda en general.
Soportar idiomas de una amplia variedad de familias lingüísticas también ayuda a asegurar que Unicode se procese y almacene correctamente, en lugar de de maneras que puedan causar problemas en el futuro a medida que se agregue soporte para más idiomas no occidentales.
Estilizado con CSS
Como se mencionó anteriormente, una fortaleza clave de nuestra API es su capacidad para normalizar el marcado HTML de una manera reflexiva y lógica. Este proceso de normalización está diseñado para optimizar el texto para la legibilidad y la accesibilidad, al mismo tiempo que preserva la intención original del autor en la mayor medida posible.
Por lo tanto, todo el texto aparece solo dentro de elementos en línea o de bloque (sin texto flotante libre), y todos los elementos en línea aparecen solo dentro de elementos de bloque. Esto facilita el estilizado del texto, por ejemplo, para asegurar que diferentes elementos tengan la cantidad correcta de espacio en blanco entre ellos.
Como ejemplo de lo valioso que es esto, los clientes de correo permiten a los usuarios hacer cosas absurdas como insertar una lista con viñetas directamente antes o después de una línea de texto, sin salto de línea entre ellos. El código (vastamente simplificado) generado por un cliente de correo al hacerlo podría verse algo así:
<div>
Algún texto
<div> </div>
<span> • Una viñeta</span>
<div> </div>
Más texto
</div>
La API de análisis de correos de FWD:Everyone normalizaría el marcado anterior para que se vea así:
<p>Algún texto</p>
<ul>
<li>Una viñeta</li>
</ul>
<p>Más texto</p>
Este marcado normalizado es fácil de entender y estilizar, y visualmente ahora también hay saltos de línea antes y después de la lista con viñetas. Facilitadores como estos hacen que el texto se vea mejor y sea más fácil de leer, al mismo tiempo que preservan la intención del autor. Este tipo de facilitadores para el usuario aseguran que el gran contenido enviado por correo confiera consistentemente estatus social, en lugar de socavarlo.
El marcado simplificado y normalizado generado por nuestra API también asegura que, al pensar en cómo estilizar el texto, los diseñadores y desarrolladores solo necesiten pensar en qué salida permite la API, en lugar de cómo podría haberse formateado el correo original. Y dado que la salida permitida por la API es virtualmente idéntica a lo que permite el cliente web de Discourse, esto debería ser casi una solución plug-and-play.
Integración propuesta
La funcionalidad de respuesta por correo se integraría con Discourse como un complemento, que luego podría activarse de forma predeterminada para todas las instancias de Discourse alojadas.
El código existente de análisis de correos se utilizaría para las instancias de Discourse que no tengan este complemento activado.
Además, en el caso de que la API de análisis de correos de FWD:Everyone estuviera temporalmente no disponible, cualquier mensaje entrante se procesaría utilizando el código existente de análisis de correos. Luego, una vez que la API esté nuevamente en línea, cualquier mensaje que no haya sido editado a través de la interfaz web desde su publicación podría volver a procesarse por la API.
El complemento también podría estar disponible para instancias de Discourse autoalojadas para que se active de forma opcional.
Para los grupos que migran desde listas de correo existentes a Discourse, cada hilo de correo en la lista de correo también podría analizarse mediante la API, pero esto probablemente se integraría en los scripts y procesos de migración existentes de Discourse en lugar de hacerse mediante un complemento.[2]
Pruebas de la API
La API está completamente disponible para que cualquiera la pruebe, aunque con un límite de tasa muy bajo para usuarios no autenticados.
Para aquellos con cuentas de Gmail, las formas más fáciles de probar la API son:
- Ir a https://www.prettyfwd.com e instalar el complemento de G Suite.
- Ir a https://api-demo.fwdeveryone.com y usar el OAuth del lado del cliente para jugar con la API.
Las diferencias clave entre estas dos herramientas basadas en la web y la API real son que las primeras:
- No procesarán hilos que contengan mensajes estilizados utilizando tablas HTML.
- No eliminarán respuestas en el primer mensaje de un hilo. (Por ejemplo, si un hilo tiene más de 100 mensajes, Gmail lo divide en varios hilos.)
Para probar la API directamente mediante código, hay scripts de inicio tanto para Python como para Ruby:
Y aquí está la documentación relevante, incluidos problemas conocidos y la hoja de ruta del producto:
[1] Viewing American class divisions through Facebook and MySpace.
[2] Al importar contenido masivo desde una lista de correo existente, vale la pena realizar primero una verificación rápida de sanidad en algunos hilos para asegurar que se estén analizando correctamente. Algunos grupos se analizarán con una precisión casi perfecta tal como están, pero otros pueden beneficiarse enormemente de un par de horas de trabajo preventivo. Por ejemplo, algunos software de listas de correo requieren un poco de código personalizado para cada lista para eliminar cualquier texto agregado al final de cada mensaje, mientras que para otros software de listas de correo esto puede hacerse de una manera predecible que funcionará para cualquier lista alojada en esa plataforma. Debido a posibles problemas como este, el proceso de importación masiva debería preferiblemente ejecutarse como parte de una migración supervisada en lugar de hacerse mediante un complemento.