Los mensajes de correo electrónico de Discourse se enroscan incorrectamente

Disculpas de antemano por el tono de lo que sigue. Sueno exasperado, porque estoy un poco exasperado.

Por Michael Brown vía Discourse Meta el 27 de julio de 2022 14:06:

Lo siento, me estoy poniendo al día ahora, aquí hay algunas ideas, algunas de las cuales ya han sido abordadas…

La dificultad aquí es que lo que se envía desde Discourse es un mensaje diferente al entrante. Tiene metadatos diferentes (a efectos de esto, Para/De/Responder a/Cancelar suscripción/etc.) y un cuerpo diferente (está personalizado por usuario (¿creo? ¿Esto no sucede en el modo lista de correo?)).

¿Qué es exactamente el mensaje? Tratando 5322 como la verdad absoluta:

Un mensaje consta de campos de encabezado, opcionalmente seguidos por un cuerpo de mensaje.

El campo “Message-ID:” proporciona un identificador de mensaje único que se refiere a una versión particular de un mensaje particular.
[énfasis mío]

Es esa “versión particular” lo que me hace pensar que sería inapropiado reenviar un mensaje entrante con un Message-ID diferente. Sin embargo, si cambias tu punto de vista de Discourse como “Software de Foro” a Discourse como “Software de Lista de Correo”, entonces de alguna manera tiene sentido hacerlo, así que entiendo de dónde vienes.

Bueno, desafortunadamente esto depende de una lectura demasiado literal, tal vez leyendo un contexto que no está ahí.

Cada mensaje de correo electrónico ve sus encabezados modificados a medida que el sistema de correo lo procesa. Si nada más, se agregan encabezados Received: en cada paso, y varios sistemas agregan varios encabezados que indican resultados de filtrado de spam y firmas. Ninguno de esos desencadena una modificación del message-id, y de hecho hacerlo haría que el message-id fuera totalmente disfuncional.

Con respecto al contenido, como ya se mencionó, casi todas las listas de correo agregan contenido al texto del cuerpo, generalmente un pie de página con un enlace a la página de administración de la lista o un enlace para cancelar la suscripción. Tampoco desencadenan un cambio de message-id.

De hecho, casi nada que reenvíe un mensaje cambia el message-id. Porque eso rompería el encadenamiento y la detección de duplicados para los clientes de usuario final.

Veo que sigues citando lo que yo estaba a punto de citar :slight_smile:

5322 también dice:

Hay muchas instancias en las que los mensajes se “modifican”, pero esas modificaciones no constituyen una nueva instancia de ese mensaje y, por lo tanto, el mensaje no obtendría un nuevo identificador de mensaje. Por ejemplo, cuando los mensajes se introducen en el sistema de transporte, a menudo se les anteponen campos de encabezado adicionales, como campos de rastreo (descritos en la sección 3.6.7) y campos reenviados (descritos en la sección 3.6.6). La adición de dichos campos de encabezado no cambia la identidad del mensaje y, por lo tanto, se conserva el campo “Message-ID:” original. En todos los casos, es el significado que el remitente del mensaje desea transmitir (es decir, si este es el mismo mensaje o un mensaje diferente) lo que determina si el campo “Message-ID:” cambia o no, no cualquier diferencia sintáctica particular que aparezca (o no aparezca) en el mensaje.

Supongo que se reduce a si el remitente del mensaje cambia cuando Discourse lo envía.

Creo que has malinterpretado las cosas aquí. Permíteme enfatizar:

En todos los casos, es el significado que el remitente del mensaje desea transmitir (es decir, si este es el mismo mensaje o un mensaje diferente) lo que determina si el campo “Message-ID:” cambia

El remitente es el autor, no un MTA como Discourse.

Si publico en Discourse por correo electrónico, quiero que mi mensaje llegue a los lectores tal como está, semánticamente hablando. Cualquier nota adicional como enlaces de cancelación de suscripción no cambia la semántica de lo que he dicho en mi mensaje.

Sigue siendo el mismo mensaje.

¿Quizás deberíamos usar Resent-Message-ID y sus amigos?

Absolutamente no. Son para que un usuario reenvíe un mensaje. Por ejemplo, si reenviara un mensaje a otra persona. No son para relés de correo (como listas y Discourse).

Siempre ha estado ahí, desde 822. Pero como dices más tarde, sí, se ha actualizado.

Ay. Pensé que era solo USENET en ese momento. Me retracto.

5322 también habla directamente de la forma en que Discourse y Github lo usan:

El campo “In-Reply-To:” puede usarse para identificar el mensaje (o mensajes) al que el nuevo mensaje es una respuesta, mientras que el campo “References:” puede usarse para identificar un “hilo” de conversación.

Posiblemente de forma ligeramente incorrecta, probablemente debido a la falta de un encabezado “Thread Identifier” adecuado. Pero esta interpretación puede no ser lo que los autores del RFC pretendían… no aborda mensajes con “References” pero sin “In-Reply-To”.

Me dice que los dos campos cubren la misma información:

  • References muestra un hilo lineal (generalmente) hasta el OP
  • In-Reply-To muestra el padre, e implica el mismo hilo en conjunto con los mensajes anteriores hasta el OP

Lo complicado de esto es que no estamos enviando un correo electrónico, estamos enviando N, uno por destinatario, para que sus metadatos individuales (Cancelar suscripción, etc.) sean correctos.

Esto no es complicado. El significado de los mensajes es el mismo, las personalizaciones son menores y semánticamente irrelevantes. No justifican message-ids nuevos o distintos.

Y sí, vi fuertes indicios durante las pruebas de que la determinación de spam estaría ligada a un Message-ID. Si se volvía a ver más tarde (mismo usuario o usuario diferente) sería mucho más probable que se marcara como spam.

¿Puedes mostrar algunas de estas instancias? Porque los message-ids permiten la deduplicación en el extremo del usuario final. Y ten en cuenta que muchas medidas “antispam” son basura mal concebida. La cantidad de cosas que he rechazado como posible spam por razones completamente espurias… romper el correo electrónico para solucionar un mal filtrado de spam roto es una mala elección.

Hasta el día de hoy, nunca pongo en copia a personas con direcciones de Gmail porque el filtrado de spam de Gmail me conoce y desecha las cosas. Si solo envío a la lista, lo reciben. Si pongo en copia su dirección de Gmail, (a) la marca como spam y (b) luego también marca el mensaje de la lista de correo como spam (¡mismo message-id!). El usuario final no ve mi mensaje. Esta lógica es completamente espuria e irreparable.

Los beneficios aquí, para ser justos, son enteramente para encadenar correctamente los correos electrónicos en ciertos clientes de correo a expensas de la entregabilidad.

Suspiro. Para todos los clientes de correo electrónico. Y una razón importante por la que la gente en el mundo de Python dice que simplemente no irá a Discourse es que el encadenamiento del lado del correo electrónico está roto. Muchas personas no usan foros, porque cada foro requiere que lo visiten. El correo electrónico les llega, pueden usar su lector preferido y su editor preferido, y el encadenamiento permite a las personas ver el flujo de la discusión claramente. Cuando funciona.

El topic/#{topic_id}/#{post_id}.s#{sender_user_id}r#{receiver_user_id} actual al menos lo hace consistente para un usuario en su buzón. La suposición

Mi mayor preocupación es la entregabilidad: es lo suficientemente difícil conseguir que el correo electrónico se entregue cuando no hay visibilidad de los principales proveedores.

Me gustaría ver evidencia. Las listas de correo hacen esto correctamente en todo el planeta. Discourse definitivamente y objetivamente rompe esto. Estoy tratando de arreglarlo.

Permítanme reiterar los dos problemas básicos aquí:

  • El In-Reply-To y References del OP citan un “message-id” de “tema” “pre-OP” ficticio, por lo que ningún usuario de correo electrónico tiene un hilo con un mensaje de inicio (el OP): todo, incluido el OP, parece un seguimiento.
  • Los correos electrónicos recibidos a través de Discourse y los correos electrónicos recibidos directamente, por ejemplo, a través de CC, tienen message-ids diferentes a pesar de ser el mismo mensaje semánticamente hablando; esto rompe el encadenamiento y la deduplicación.

Pero sí veo un fuerte argumento para hacer que Discourse se comporte más como software de lista de correo en modo lista de correo. @martin, creo que no personalizamos el cuerpo del mensaje en modo lista de correo, ¿verdad? ¿Crees que tiene sentido adoptar un enfoque más estricto en torno a la preservación y reutilización de Message-IDs en modo lista de correo?

Hay gente en el mundo de Python que encontró el “modo lista de correo” como demasiado “manguera de incendios”. Quieren recibir correos electrónicos para temas específicos, pero no para todo. El manejo del message-id debería ser el mismo para todo el lado del correo electrónico.

Soy una persona de “modo lista de correo” en discuss.python.org. Pero lo activé aquí (discourse.org) y lo desactivé inmediatamente. Necesito el modo dirigido aquí.

4 Me gusta

Por Michael Brown vía Discourse Meta el 27Jul2022 22:37:

¡Ah! Pensé que ya estábamos haciendo: topic/#{topic_id}/#{post_id}.s#{sender_user_id}r#{receiver_user_id}

{receiver_user_id} te pone en IDs de mensajes distintos por usuario final para la misma publicación de origen. Eso es malo tan pronto como los usuarios finales se comunican fuera de Discourse o reciben copias no a través de Discourse.

Me inclinaría a, en aras de equilibrar las preocupaciones de unicidad y entregabilidad del correo electrónico frente a las del modo lista de correo, hacer (2) para el modo lista de correo deshabilitado y (3) para el modo lista de correo habilitado.

Y como mencioné en mi publicación reciente, el modo lista de correo solo cubre un tipo de recepción de correo electrónico de Discourse. Todas las mismas preocupaciones se aplican si el receptor de correo electrónico está en modo lista de correo o simplemente en modo de correo electrónico para algunos temas/etiquetas.

Del mismo modo, con la cabecera References, me inclinaría a que esté ausente para la publicación n.º 1 en un tema.

Igualmente el In-Reply-To. ninguno debería estar presente, porque para estar presente tienen que hacer referencia a un mensaje ficticio por OP.

y que haga referencia al tema (por lo tanto topic/#{topic_id}) y a la publicación

a la que está respondiendo, si la hay.

No puedes referirte al ID de mensaje del “tema” a menos que haya habido una publicación con ese ID de mensaje que se haya enviado por correo electrónico. Si quieres ir por ese camino, trata de forma especial el ID de mensaje del OP para que sea el ID de mensaje del “tema” en lugar de ...../1.

3 Me gusta

Esto debería ser “antes de la OP”. Lo siento, Cameron Simpson.

Como dices, este es exactamente el problema que nos frustra:

Estoy de acuerdo en que esto debería cambiarse. El message-id del OP debería ser (en ausencia de uno que provenga del correo) (simplificado) topic/1 y no hacer referencia a otro mensaje.

El message ID no cambiaría, incluso si solo fuera una publicación de Discourse y nunca un correo electrónico.

Los mensajes posteriores pueden hacer referencia a ese.

¿Por qué debe existir un correo electrónico? Semánticamente, tener solo la publicación cumple los criterios. El mensaje al que responde existe, solo que no en la carpeta de correo electrónico de esa persona. Acabamos de llegar a la conclusión de que el mensaje es lo que importa, ya sea Cuerpo de Publicación o Cuerpo de Correo Electrónico. Se deduce que topic/#{topic_id}/1@site es un ID de mensaje único que hace referencia a esa publicación, ya sea que esté en un mensaje de correo electrónico o no.

No es diferente a recibir una respuesta a un correo electrónico que hace referencia a un correo electrónico que no está en tu bandeja de entrada. Sigue siendo una respuesta, por lo que References es legítimo y correcto.

Fundamentalmente estoy de acuerdo contigo. El purista en mí quiere que esto sea correcto. Pero la practicidad de necesitar que los correos electrónicos lleguen a las bandejas de entrada de las personas fue lo que llevó a esto. Para peor, mucha gente usa gmail y nunca entrena sus filtros, lo usa correctamente y se “desuscribe” informando como spam[1].

Estoy de acuerdo, creo que fuimos un poco demasiado literales al leer

Un identificador de mensaje se refiere a exactamente una instancia de un mensaje en particular

Después de darle vueltas a esto durante un tiempo, creo que deberíamos volver a lo que teníamos antes (eliminar la aleatorización) y fijar un único message-id por publicación y debería ser:

  • message_id_from_incoming_email || topic/#{topic_id}/#{post_num}@site (post_num del OP es 1)

Y cada vez que enviemos un correo electrónico, creo que es correcto agregar References a los padres hasta el OP y establecer In-Reply-To al ID de mensaje de publicación estable apropiado (o al OP si se responde al tema) ya que el Mensaje es la publicación. Pero esos campos para el OP deberían estar en blanco, sí.


  1. no es que gmail nos informe de esto, a pesar de que implementamos el bucle de retroalimentación. ↩︎

5 Me gusta

Gracias por sus respuestas @supermathie y @cameron-simpson, creo que hemos llegado a un consenso. Extraigo los TODOs en una sola publicación, y espero poder empezar a trabajar en ellos muy pronto:

  1. Cambiar el formato del Message-ID generado para que sea siempre \u003cdiscourse/post/:post_id@:hostname\u003e, esto es suficientemente único, es básicamente volver a lo que solíamos hacer. La referencia al OP usará ahora el ID de la primera publicación en lugar del ID del tema desnudo.
  2. Si una publicación tiene un registro IncomingEmail asociado, siempre usaremos ese Message-ID al enviar el correo electrónico, de lo contrario generaremos uno usando el formato anterior.
  3. No usar un References al enviar correos electrónicos para el OP del tema, todavía no hay nada a lo que Reference porque es el primer correo electrónico en el hilo.
  4. Asegurarse de que se generen las cabeceras In-Reply-To y References correctas basadas en los registros PostReply.

Esto tiene el potencial de dejar las cosas en un estado un poco turbio en cuanto a encadenamiento para los correos electrónicos ya enviados, pero haré todo lo posible para permitir el formato del que nos estamos alejando durante un período de transición también. ¡Gracias por su paciencia!

3 Me gusta

Solo para aclarar… ¿este no sería el hostname del servidor de donde se originó, sino la url del sitio? Si es hostname, entonces perdemos toda estabilidad cuando 3 hosts diferentes sirven el mismo sitio.

1 me gusta

Lo siento, sí, me refiero al dominio del sitio, por ejemplo, meta.discourse.org, que proviene de Email::Sender.host_for(Discourse.base_url), que ya usamos.

2 Me gusta

Buena idea, no había pensado en las mudanzas. ¿Es :post_id el ID de la publicación (post.id) o el número (dentro del tema)?

Si es el ID de la publicación, podemos simplificar y usar \u003cpost/:post_id@:hostname\u003e ya que eso nunca cambiará, entonces no necesitamos almacenar el Message-ID a menos que se anule el valor predeterminado.

Si no… ¿podríamos usar el ID de la publicación aquí? no hay razón para que esta parte tenga que ser larga, solo tiene que ser única.

2 Me gusta

Es el ID real, no el número de la publicación.

Ese es un buen punto, <post/:post_id@:hostname> probablemente funcionará bien y evita el requisito de columna adicional. Quizás para hacerlo más específico de Discourse podríamos agregar discourse al principio, por ejemplo, <discourse/post/543563@meta.discourse.org> (teniendo en cuenta que muchos sitios no tendrán ninguna mención de Discourse en el nombre de host). En este punto, son detalles menores.

Intentaré pensar en formas en que esto pueda salir mal. Supongo que si mueves una publicación a otro tema y luego alguien responde a la publicación por correo electrónico, su respuesta terminará en el nuevo tema en lugar del tema original. ¿Quizás eso esté bien? Otro riesgo es que la publicación se mueva a una categoría privada, pero creo que ya tenemos ese mismo riesgo y lo manejamos.

Solo estoy pensando en voz alta, debería estar bien, cubriré estas cosas cuando pruebe los cambios de todos modos :+1:

2 Me gusta

El argumento para incluir topic_id es que puedes romper deliberadamente el encadenamiento si las personas separan una publicación de un tema en otro tema.

Estoy indeciso al respecto. Puede ser de cualquier manera. Pero esa sería la idea.

1 me gusta

El argumento para usar solo el ID de la publicación es que es más estático, que es lo que queremos, ya que si mueves una publicación a otro tema, el ID de la publicación será el mismo en el Message-ID, pero el tema no será el mismo.

Creo que si terminamos moviendo la publicación y enviando correos electrónicos desde el nuevo tema, el nuevo hilo se creará correctamente de todos modos en el cliente de correo, ya que las cadenas de encabezado References e In-Reply-To serán diferentes. De todos modos, me aseguraré de probar este escenario y ver si hace lo que esperamos. Nada se fusionará en el núcleo hasta que los diversos escenarios funcionen como se espera.

1 me gusta

Basándome en estas discusiones adicionales @cameron-simpson, he actualizado los TODOs a esto, publicándolos aquí para que recibas la actualización ya que las ediciones de Discourse no llegarán por correo electrónico:

  1. Cambiar el formato del Message-ID generado para que siempre sea \u003cdiscourse/post/:post_id@:hostname\u003e, esto es lo suficientemente único, es básicamente volver a lo que solíamos hacer. La referencia a la OP ahora usará el ID de la primera publicación en lugar de solo el ID del tema desnudo.
  2. Si una publicación tiene un registro IncomingEmail asociado, siempre usamos ese Message-ID al enviar correos electrónicos, de lo contrario, generamos uno usando el formato anterior.
  3. Agregar una nueva columna outbound_message_id a los registros Post que se completará con a) el Message-ID del correo electrónico entrante si está creando la publicación o b) el Message-ID saliente que generamos en el caso de publicaciones creadas por la interfaz web de Discourse.
  4. No usar encabezados References o In-Reply-To al enviar correos electrónicos para la OP del tema, no hay nada a lo que Reference o responder todavía porque es el primer correo electrónico en el hilo.
  5. Asegurarse de que los encabezados In-Reply-To y References correctos se generen basándose en los registros PostReply.
1 me gusta

¿Esto cubre también las citas (por ejemplo, una publicación que cita 10 publicaciones diferentes, por lo que hace referencia a ellas)?

1 me gusta

Por Sam Saffron vía Discourse Meta el 29Jul2022 02:31:

¿Esto cubre también las citas (por ejemplo, una publicación que cita 10 publicaciones diferentes, ¿así que las referencia?)

In-Reply-To solo puede citar un antecedente, así que elige uno. References puede referenciar a más de uno, pero el RFC lo desaconseja explícitamente porque no todas las aplicaciones cliente pueden esperar otra cosa que una cadena lineal desde esta publicación hasta la OP.

Estaría de acuerdo con cualquiera de las dos para References, pero me inclinaría por la conservadora. El cálculo fácil es:

  • In-Reply-To: usa el message-id del primer mensaje citado (o cualquier cita única que elijas según alguna política)
  • References: las References de la misma única publicación antecedente elegida arriba más el message-id de esa misma publicación

Estos serían estables, predecibles y correctos.

Saludos,
Cameron Simpson cs@cskk.id.au

2 Me gusta

References está desaconsejado de usarse de esta manera:

Nota: Algunas implementaciones analizan el campo “References:” para mostrar el “hilo de la discusión”. Estas implementaciones asumen que cada mensaje nuevo es una respuesta a un solo padre y, por lo tanto, que pueden retroceder a través del campo “References:” para encontrar el padre de cada mensaje que figura allí. Por lo tanto, se desaconseja intentar formar un campo “References:” para una respuesta que tenga varios padres; cómo hacerlo no se define en este documento.

2 Me gusta

Por Martin Brennan vía Discourse Meta el 29Jul2022 01:57:

Basado en estas discusiones adicionales @cameron-simpson actualicé los TODOs
a esto, publicándolos aquí para que recibas la actualización ya que las
ediciones de Discourse no llegarán por correo electrónico:

  1. Cambiar el formato del Message-ID generado para que siempre sea \u003cdiscourse/post/:post_id@:hostname\u003e, esto es suficientemente único, básicamente volvemos a lo que solíamos hacer. La referencia a la OP ahora usará el ID de la primera publicación en lugar del ID del tema desnudo.
  2. Si una publicación tiene un registro IncomingEmail asociado, siempre usamos ese Message-ID al enviar correo electrónico, de lo contrario generamos uno usando el formato anterior.
  3. No usar un References al enviar correos electrónicos para la OP del tema, todavía no hay nada a lo que Reference porque es el primer correo electrónico en el hilo.

También omitiría el In-Reply-To en los correos electrónicos de la OP.

  1. Asegurar que las cabeceras In-Reply-To y References correctas sean
    generadas basadas en los registros PostReply.

Sí.

Personalmente, iría un paso más allá teniendo una columna para el ID de mensaje del lado del correo electrónico. De esa manera, una vez que hayas asignado un ID de mensaje para la publicación (del correo electrónico de origen si es de correo electrónico, o generado si es de la interfaz web), permanecerá estable independientemente de lo que pueda suceder en el código ahora o más adelante. es decir, incluso si no hay IncomingEmail, la generación del ID de mensaje ocurre solo una vez, en lugar de ser recalculada (lo que podría cambiar).

es decir, hacerlo estable una vez creado almacenándolo.

Tienes una relación IncomingEmail por lo que parece. Quizás tengas (o podrías usar) una relación OutgoingEmail para el estado adicional de los mensajes de correo electrónico salientes, creada la primera vez que una publicación se reenvía por correo electrónico.

Sé que el flujo es básicamente que eso sucede cuando se realiza una publicación, pero puedo imaginar algunas funciones posteriores para el usuario como:

  • por favor, reenvíame correos electrónicos para todo este tema, ahora que estoy interesado
  • si ocurre una edición en una publicación, considera enviar el mensaje actualizado con el mismo ID de mensaje

La razón por la que el segundo ejemplo viene a la mente es que tenemos más cosas que informar :slight_smile: Una es que Discourse parece hacer un esfuerzo para eliminar la parte citada de las respuestas publicadas en la parte superior para mantener la publicación concisa, o algo así. Escribí una publicación larga en el mundo de Python hace unas semanas que se truncó severamente. Entré y la edité en el foro con el texto original de mi copia personal. Pero un destinatario dijo que tenía la versión completa, y me preguntaba si Discourse enviaba actualizaciones de edición como mensajes de reemplazo con el mismo ID. Lo que sería bastante bueno dependiendo del manejo del cliente del usuario final.

1 me gusta

Por Martin Brennan vía Discourse Meta el 29Jul2022 00:36:

  1. Añadir un nuevo outbound_message_id a la tabla Post, para que podamos estar seguros de que el hilo sobrevive incluso si una publicación cambia de tema o algo así, almacenar el Message-ID aquí para ambos casos anteriores.

Sí, creo que esto es importante, independientemente de cómo se implemente (relación o columna de lo que sea). Creo que lo dije en tus TODOs revisados.

  1. No usar References al enviar correos electrónicos para el OP del tema, ya que todavía no hay nada a lo que Reference porque es el primer correo electrónico del hilo.
  2. Asegurarse de que las cabeceras In-Reply-To y References correctas se generen basándose en los registros de PostReply y la nueva columna outbound_message_id en la tabla Post.

Esto tiene el potencial de dejar las cosas en un estado un poco turbio en cuanto a hilos para los correos electrónicos ya enviados, pero haré todo lo posible para permitir el formato del que nos estamos alejando durante un período de transición. ¡Gracias por tener paciencia!

No hay nada que podamos hacer por los correos electrónicos existentes. ¡Simplemente asegúrate de que los hilos funcionen bien de ahora en adelante!

¡Gracias!
Cameron Simpson cs@cskk.id.au

1 me gusta

Tenemos EmailLog, pero esos registros se limpian cada 90 días y no creo que sea una buena opción para esto. Simplemente haré esto:

1 me gusta

Se trataba de evitar almacenarlo por completo… pero ahora que lo pienso, el ID de la publicación nunca cambiará, pero el nombre de host sí. Así que deberíamos almacenarlo inmediatamente después de guardar en todos los casos.

No estaría de más que messageid fuera una propiedad de cada Post, inmutable para siempre…

¿No sería esta una versión diferente del mensaje? De la especificación:

El campo “Message-ID:” proporciona un identificador de mensaje único que se refiere a una versión particular de un mensaje particular. … Un identificador de mensaje pertenece a exactamente una versión de un mensaje particular; las revisiones posteriores del mensaje reciben cada una nuevos identificadores de mensaje.

Así que probablemente nuestro message-id generado debería ser: \u003cdiscourse/post/:post_id/rev/:revision_num\u003e (posiblemente omitiendo /rev/:revision_num para la primera revisión). Esto permitiría a los destinatarios de correo electrónico recibir las actualizaciones de edición en primer lugar, considerando que

1 me gusta

Sí, lo haré. En cuanto a estas otras discusiones sobre ediciones y revisiones, creo que es un tema muy complejo en el que no deberíamos meternos ahora mismo… arreglemos primero nuestros pecados de encadenamiento :slight_smile:

1 me gusta