En discuss python org estamos discutiendo el lado del correo electrónico de Discourse. La mayor queja es la falta de encadenamiento. Investigué un poco en las cabeceras y parece que:
la cabecera Message-ID es al menos única
las cabeceras Reply-To y Referencesno se refieren a los Message-IDs de otros mensajes, y mucho menos al ID del mensaje al que están respondiendo
en cambio, se refieren a algún ID de mensaje ficticio basado en el número del tema
Esto significa que las personas que usan el correo electrónico ven (a) discusiones totalmente planas y sin encadenar y (b) el mensaje raíz aparentemente falta, porque las cabeceras In-Reply-To y References se refieren a un ID de mensaje que en realidad nunca aparece en ningún mensaje.
Esto es malo y viola la RFC 5322. Y hace que la experiencia del correo electrónico sea mucho peor de lo que fácilmente podría ser.
Como ejemplo, hay un hilo allí cuyo primer mensaje tiene estas cabeceras:
De nuevo, un Message-ID aceptable, pero In-Reply-To y References completamente sin sentido.
Esto debería ser fácil de arreglar. El primer mensaje no debería tener cabeceras In-Reply-To ni References. El segundo mensaje debería tener el Message-ID del primer mensaje en las cabeceras In-Reply-To y References.
Por favor, consulte la sección 3.6.4 de la RFC 5322 para obtener detalles:
Tal como están las cosas, los usuarios de correo electrónico ven discusiones planas y no estructuradas. Con estas correcciones, pueden tener una visualización encadenada sensata y fácil de seguir.
Solo estoy revisando la diferencia entre HEAD y esa corrección.
Me parece que current todavía siempre establece References, incluso si no hay un antecedente; topic_canonical_reference_id se usa como respaldo. Todavía creo que eso está mal, porque no hay ningún mensaje de correo electrónico con esa ID.
El In-Reply-To es un poco más correcto, en el sentido de que solo se establece si post.post_number!=1, pero todavía recurre a topic_canonical_reference_id:
el respaldo debería ser el Message-ID de la publicación n.º 1 si no hay referenced_post_message_ids, y notopic_canonical_reference_id
algo en el código de receipt-of-reply-emails debe estar eliminando la cabecera In-Reply-To de los mensajes de respuesta, porque deberían haber poblado correctamente el array referenced_post_message_ids (“lista”? Soy nuevo en Ruby)
Cameron, gracias por abrir este tema para discusión y proporcionar muchos detalles en tus publicaciones. Soy responsable de este “cajón de sastre”, de estos dos commits:
Hemos sido conscientes de algunos problemas en torno a la creación de hilos en clientes de correo electrónico como Thunderbird durante un tiempo, pero no representaba un gran número de consumidores de la creación de hilos de correo electrónico desde Discourse, por lo que se ha pospuesto. Pero ahora que esto sale a la luz, necesitamos dedicar tiempo a reexaminar el problema y trabajar en una solución.
Curiosamente, añadimos esta cabecera References al primer correo electrónico enviado y a todos los subsiguientes en su momento, ya que hace que la creación de hilos funcione correctamente en Gmail, pero estoy de acuerdo en que no es ideal y es probable que esté causando los problemas de creación de hilos, junto con no usar el Message-ID original en las cabeceras In-Reply-To y References del correo electrónico subsiguiente.
Por favor, ten paciencia mientras reviso viejas discusiones y el código y trabajo en esto. Mientras tanto, ¿eres consciente de otros clientes de correo electrónico que se estén utilizando y que estén experimentando problemas? Por ejemplo, sé que este es un problema en Thunderbird, pero ¿qué hay de otros? Gracias.
Lo sentimos, pero su mensaje de correo electrónico a
["incoming+8349bd9eb1f2b582df4f32dbe85c3363@meta.discoursemail.com"]
(titulado Re: [Discourse Meta] [bug] Los mensajes de correo electrónico de Discourse se están
enhebrando incorrectamente) no funcionó.
Razón:
Lo sentimos, los nuevos usuarios solo pueden poner 2 enlaces en una publicación.
Si puede corregir el problema, inténtelo de nuevo.
Lo pondré en el foro donde puedo atrapar y revisar…
Cameron, gracias por abrir este tema para discusión y proporcionar
muchos detalles en tus publicaciones. Soy responsable de esta caja de Pandora,
de estos dos commits:
3b13f1146b2a406238c50d6b45bc9aa721094f46
Esto parece estar bien. ¿Guarda este id con el registro de la base de datos para que las respuestas entrantes puedan vincularse al mensaje del foro antecedente?
Además, ¿quieres que verifique que el sufijo sea sintácticamente legal para RFC5322, en términos de caracteres permitidos?
82cb67e67b83c444f068fd6b3006d8396803454f
Este segundo commit parece abordar otro problema que hemos visto: si una publicación proviene de un correo electrónico, el message-id saliente enviado a los usuarios de correo electrónico no es el message-id del mensaje de origen del autor. Esto resulta en dos mensajes diferentes desde el punto de vista de un cliente de correo, y probablemente rompe las respuestas hechas al original en lugar de la copia enviada por el foro. Por ejemplo:
Para: el foro
CC: uno de los participantes
El participante recibirá (bueno, puede) una copia del foro y una copia directa del autor, y estos serán mensajes distintos en su extremo porque tendrán message-ids diferentes.
Iba a hacer un segundo informe de error sobre este problema después de resolver el problema de las cabeceras in-reply-to y references, que es mucho más importante.
Hemos sido conscientes de algunos problemas en torno a la creación de hilos durante un tiempo en clientes de correo electrónico como Thunderbird, pero no ha representado un gran número de consumidores de creación de hilos de correo electrónico de Discourse, por lo que se ha pospuesto, pero ahora que esto sale a la luz, necesitamos dedicar tiempo a reexaminar el problema y trabajar en una solución.
Yo y varios otros usamos mutt. Estoy feliz de hacer lo que sea necesario para ayudar a depurar esto y revisar el código. También he sido administrador de sistemas de correo durante mucho tiempo en vidas anteriores.
[quote=“Cameron Simpson, post:1, topic:233499,
username:cameron-simpson”]
Es el primer mensaje. No debería tener una cabecera References, porque no hay ningún mensaje en ningún lugar con ese id.
[/quote]
Curiosamente, agregamos esta cabecera References al primer correo electrónico enviado y a todos los subsiguientes en ese momento, ya que hace que la creación de hilos funcione correctamente en Gmail,
Creo que una cabecera References correcta (ausente en la primera publicación, como in-reply-to en las respuestas) también debería funcionar. Pero GMail tiene una relación bastante laxa con los estándares de correo en ocasiones. Tengo un acuerdo con gmail; también puedo hacer algo de depuración allí. Y en principio, podemos usar esta misma discusión como campo de pruebas, tal vez.
pero estoy de acuerdo en que no es ideal y probablemente esté causando los problemas de creación de hilos
junto con no usar el Message-ID original en las cabeceras In-Reply-To y References del correo electrónico subsiguiente.
Por favor, tened paciencia conmigo mientras reviso discusiones antiguas y el código y trabajo en esto.
No te preocupes.
Mientras tanto, ¿estás al tanto de otros clientes de correo electrónico que se estén
utilizando y que estén experimentando problemas? Por ejemplo, sé que este es un
problema en Thunderbird, pero ¿en alguno más? Gracias.
Definitivamente mutt. Al menos con mutt es muy fácil ver las cabeceras y también ver la cadena del árbol de respuestas, que a menudo se oculta en otros clientes.
La creación de hilos de correo electrónico se define completamente por las cabeceras Message-ID e In-Reply-To. La cabecera References comenzó con USENET para los seguimientos, y admitía (allí) múltiples message-ids; In-Reply-To admite solo uno. Parece que References también está presente ahora en RFC5322, y revisaré su semántica.
De acuerdo, esto es algo bastante importante, por favor ten paciencia. Primero, gracias por otra respuesta detallada y la oferta de depuración/revisión, es muy útil De hecho, he estado investigando esto esta mañana y, sorprendentemente, la organización en hilo en una vista unificada funciona en Thunderbird para la mayoría de los casos, y creo que la cabecera References que apunta consistentemente al OP ayuda con eso (por ejemplo, el tema Reference en esta cadena que siempre está presente es \u003ctopic/53@discoursehosted.martin-brennan.com\u003e.\n\n
\n\nEl caso en el que la organización en hilo no funciona como se esperaba es:\n\n1. Se crea una publicación dentro de Discourse y se envía un correo electrónico a quienes siguen el tema luego\n2. Alguien más responde a esa publicación y se envía un correo electrónico a quienes siguen el tema\n\nEn el caso del segundo correo electrónico, obtiene una cabecera In-Reply-To y References incorrecta, ya que genera una en esta línea discourse/lib/email/sender.rb at 98bacbd2c6b9fe57167cd32af5eb4839b4a5d1f6 · discourse/discourse · GitHub en lugar de usar una existente. Debería usar el Message-ID del correo electrónico que se envió primero. En la captura de pantalla, aquí es donde deberían colocarse los mensajes que siguen este patrón:\n\n
\n\n\n\n[quote="Cameron Simpson, post:8, topic:233499, username:cameron-simpson"]\nEsto parece correcto. ¿Guarda este id con el registro de la base de datos para que las respuestas entrantes puedan vincularse al mensaje del foro antecedente?\n[/quote]\n\nLa respuesta es: depende. Si se crea una publicación en Discourse a partir de un correo electrónico entrante, como este tuyo, usamos el Message-ID original entrante de esa publicación cuando alguien responde a ella para las cabeceras In-Reply-To y References según:\n\ndiscourse/lib/email/sender.rb at 98bacbd2c6b9fe57167cd32af5eb4839b4a5d1f6 · discourse/discourse · GitHub lo contrario, simplemente usamos la referencia del OP del tema y generamos una nueva referencia, lo que obviamente es lo que está causando todos los problemas. En todos los casos, generamos un nuevo Message-ID cada vez que se envía un correo electrónico saliente, lo que parece correcto y a la par con otros clientes de correo.\n\n[quote="Cameron Simpson, post:8, topic:233499, username:cameron-simpson"]\nEste segundo commit parece abordar otro problema que hemos visto: si una publicación proviene de un correo electrónico, el message-id saliente enviado a los usuarios de correo no es el message-id del mensaje fuente del autor. Esto resulta en dos mensajes diferentes desde el punto de vista de un cliente de correo, y probablemente rompe las respuestas hechas al original en lugar de la copia enviada desde el foro.\n[/quote]\n\nCreo que entiendo lo que quieres decir, ¿sucede así?\n\n1. cameron envía un correo electrónico a Discourse desde mutt que recibe Message-ID: 74398756983476983@mail.com\n2. Discourse crea una publicación y almacena el Message-ID contra la publicación con un registro IncomingEmail\n3. johndoe está siguiendo el tema, por lo que se le envía un correo electrónico desde Discourse con un Message-ID: topic/222/44@discourse.com y sin referencia al Message-ID original 74398756983476983@mail.com\n\n¿Suena correcto, que simplemente “pasemos” ese Message-ID a quienes siguen el tema en lugar de generar el nuestro, ya que ya es único? ¿Qué sucede entonces en el cliente de correo de johndoe si cameron también lo incluyó en copia en ese mensaje saliente original? Esto sí parece un problema separado, por lo que sería bueno abrir otro tema de error para ello.\n\n[quote="Cameron Simpson, post:8, topic:233499, username:cameron-simpson"]\nYo y varios otros usamos mutt.\n[/quote]\n\nConfiguraré un cliente mutt localmente para ver lo que tú también estás viendo, nunca he probado esta funcionalidad en un cliente basado en texto (solo Gmail y Thunderbird), así que tengo curiosidad por ver cómo se ve de todos modos.\n\n-----\n\nMi idea para abordar estos problemas esta mañana fue desechar los sufijos generados aleatoriamente que se generan cuando enviamos cabeceras Message-ID en correos electrónicos y en su lugar cambiar a un esquema donde usamos el user_id tanto del usuario que envía como del que recibe. El beneficio de esto es que no hay necesidad de almacenar el Message-ID en ningún lugar (excepto cuando un correo electrónico entrante crea una publicación) y, por lo tanto, las cabeceras References y In-Reply-To siempre serán consistentes. Permítanme dar un ejemplo. Digamos que tenemos estos usuarios:\n\n* martin - user_id 25\n* cameron - user_id 44\n* sam - user_id 78\n* bob - user_id 999\n\nY luego tenemos este tema, topic_id 233499, con publicaciones a partir de post_id 100 como el OP. El formato se convertiría en topic/#{topic_id}/#{post_id}.s#{sender_user_id}r#{receiver_user_id}. El orden de las operaciones se vería así:\n\n1. martin crea el OP\n * A cameron se le envía un correo electrónico con estas cabeceras:\n * Message-ID: topic/233499.s25r44@meta.discourse.org\n * References: topic/233499@meta.discourse.org\n * A sam se le envía un correo electrónico con estas cabeceras:\n * Message-ID: topic/233499.s25r78@meta.discourse.org\n * References: topic/233499@meta.discourse.org\n\n2. cameron responde por correo electrónico\n\n * A discourse se le envía un correo electrónico con estas cabeceras desde mutt:\n * Message-ID: 43585349859734@test.com\n * References: topic/233499@meta.discourse.org topic/233499.s25r44@meta.discourse.org\n * In-Reply-To: topic/233499.s25r44@meta.discourse.org\n\n3. discourse (como cameron, del correo electrónico anterior) crea la publicación 101\n\n * A sam se le envía un correo electrónico desde discourse con estas cabeceras:\n * Message-ID: topic/233499/101.s44r78@meta.discourse.org\n * References: 43585349859734@test.com topic/233499@meta.discourse.org\n * In-Reply-To: 43585349859734@test.com\n\n2. sam responde por correo electrónico a cameron\n\n * A discourse se le envía un correo electrónico con estas cabeceras desde gmail:\n * Message-ID: 5346564746574@gmail.com\n * References: topic/233499/101.s44r78@meta.discourse.org topic/233499@meta.discourse.org\n * In-Reply-To: topic/233499/101.s44r78@meta.discourse.org\n\n4. discourse (como sam, del correo electrónico anterior) crea la publicación 102\n\n * A cameron se le envía un correo electrónico desde discourse con estas cabeceras:\n * Message-ID: topic/233499/102.s78r44@meta.discourse.org\n * References: 5346564746574@gmail.com topic/233499@meta.discourse.org\n * In-Reply-To: 5346564746574@gmail.com\n\n5. bob crea la publicación 103 en el tema, no en respuesta a nadie (tenga en cuenta que las Referencias aquí incluyen el Message-ID enviado a ambos usuarios para el correo electrónico del OP)\n * A cameron se le envía un correo electrónico con estas cabeceras:\n * Message-ID: topic/233499/103.s999r44@meta.discourse.org\n * References: topic/233500@meta.discourse.org topic/23499.s25r44@meta.discourse.org\n * A sam se le envía un correo electrónico con estas cabeceras:\n * Message-ID: topic/233499/103.s999r78@meta.discourse.org\n * References: topic/233499@meta.discourse.org topic/23499.s25r78@meta.discourse.org\n\n6. cameron responde por correo electrónico\n\n * A discourse se le envía un correo electrónico con estas cabeceras desde mutt:\n * Message-ID: 6759850728742572@test.com\n * References: topic/233499@meta.discourse.org topic/233499/103.s999r44@meta.discourse.org\n * In-Reply-To: topic/233499/103.s999r44@meta.discourse.org\n\nbandeja de entrada de cameron\n\n* martin - OP del tema\n * ENVIADO -\u003e a: discourse, RE: OP del tema\n * sam - respuesta a la segunda publicación\n * bob - respuesta en el tema a ninguna publicación en particular\n * ENVIADO -\u003e a: discourse, RE: publicación de bob\n\nbandeja de entrada de sam\n\n* martin - OP del tema\n * cameron - segunda publicación\n * ENVIADO -\u003e a: discourse, RE: segunda publicación\n * bob - respuesta en el tema a ninguna publicación en particular\n\nCreo que esto es correcto, ¿podrías revisar lo que he escrito en estas cabeceras y verificar si es lo que esperarías de este escenario? Lo único de lo que no estoy muy seguro es de si he cubierto todas las Referencias, y por supuesto estaría probando esto en un conjunto de correos electrónicos en vivo en una rama de desarrollo antes de implementarlo. Tampoco he probado nada en mutt todavía.\n\n-----\n\nComo nota aparte, también investigué lo que hace GitHub con sus correos electrónicos de notificación, y noté que hacen algo similar donde tienen una Reference omnipresente (discourse/discourse/pull/252@github.com) que se utiliza en todos los correos electrónicos relacionados con ese “tema”, que en este caso es una solicitud de extracción de GitHub:\n\n\nReferences: \u003cdiscourse/discourse/pull/252@github.com\u003e \u003cdiscourse/discourse/pull/252/issue_event/7042100517@github.com\u003e\nIn-Reply-To: \u003cdiscourse/discourse/pull/252/issue_event/7042100517@github.com\u003e\n
By Martin Brennan via Discourse Meta at 22Jul2022 06:34:
Okay this is kind of huge, please bear with me. First, thanks for
another detailed reply and the offer of debugging / review, it is
really helpful I’ve actually been looking into this this morning
and, surprisingly, the threading in a unified view works in Thunderbird
for most cases, and I think the References header consistently
pointing to the OP helps with that (for example the topic Reference
in this chain which is always present is <topic/53@discoursehosted.martin-brennan.com>.
I’ve just reread RFC5322 section 3.6.4 closely. It has moved on from
earlier versions (822 and 2822), and has merged the email In-Reply-To
headers, USENET References headers and modern
reply-citing-more-that-one previous messages.
The short summary:
The Message-ID is a single persisent identifier for a message
The In-Reply-To contains all the message-ids of which this message
is a direct reply, so if I reply to a pair of messages it will have
those 2 message-ids
The References is a reply chain of antecedant message-ids from the
OP to the preceeding message. So indeed it should always start with
the OP message-id.
So for a discussions like this, pretending that labels are message-ids:
It is also leagel to include “reply1 reply2” in the references (the
other chain to reply5) but the RFC explicitly recommends against that
becaause some clients expect the references to be a single linear chain
of replies, not some flattened digraph.
So my recommendation for constructing the references is to use the
references of the “primary” antecedant message with the primary
antecedant message’s message-id appended. That way you always get a
linear chain in the correct order.
Interestingly there seems to be some threading there.
But notice: the top post has a little “is a reply” arrow. Even though it
is post 1. I expect that is because of the “topic” references entry,
which make TB think there was a earlier message (which of course there
was not).
In mutt-land we see almost no threading at all:
23Jul2022 06:24 Olha via Discus - ┌>[Py] [Users] I need an advise discuss-users 5.7K
22Jul2022 17:12 Paul Jurczak vi - ├>[Py] [Users] I need an advise discuss-users 5.5K
22Jul2022 13:21 Rob via Discuss - ├>[Py] [Users] I need an advise discuss-users 6.8K
22Jul2022 12:53 vasi-h via Disc - ├>[Py] [Users] I need an advise discuss-users 5.5K
22Jul2022 11:38 Cameron Simpson - ├>[Py] [Users] I need an advise discuss-users 14K
22Jul2022 10:27 Rob via Discuss - ├>[Py] [Users] I need an advise discuss-users 6.6K
22Jul2022 06:14 vasi-h via Disc r ┴>[Py] [Users] I need an advise discuss-users 6.5K
which is because every message’s In-Reply-To points directly at the
fictitious “topic” message-id. Mutt probably ignores the References
because it is a mail reader, and References originates in USENET news.
Maybe Thunderbird is using the references or augumenting the in-reply-to
with references information.
You only need to consult one of In=-Reply-To or References to do
threading; the former comes from email and the latter from USENET.
You’re supporting both (which is great!) so we need to make them
consistent.
(Aside: there’s also discussion about USENET mirroring, because several
python people consume the lists via a USENET interface. Again, a
separate topic.)
[…]
[quote=“Cameron Simpson, post:8, topic:233499,
username:cameron-simpson”]
This looks fine. Does it save this id with the db record so that inbound
replies can be tied to the antecedant forum message?
[/quote]
The answer is – it depends. If a post is created in Discourse from an inbound email, such as this one of yours, we use that post’s original inbound Message-ID when someone replies to it for the In-Reply-To and References headers as per:
Otherwise we are just using the topic OP reference and just generating a new reference, which obviously is what is causing all the issues. In all cases we generate a new Message-ID every time an outbound email is sent, which seems correct and on par with other mail clients.
Alas, not quite. If you’re the origin of the message (i.e. authored in
Discourse), generating the message-id is fine. If there’s no message-id
(illegal) generating one is standard practice (usually by MTAs). But if
you’re passing a message on (authored in email), the existing message-id
should be preserved.
To my mind you need to be doing 3 things:
having a stable message-id and not replacing the message-id from an
inbound message
generating correct In-Reply-To, which is easily computed from the
immediate antecedant message(s) i.e. antecedant(s)-Message-ID
generating correct References, which is easily computed as
antecedant-References + antecedant-Message-ID
For point 1, looking at the code you cite, you probably want the email
message id to be (Pythonish syntax, sorry):
def message_id(post):
return post.incoming_email.message_id or discourse_message_id(post)
i.e. to be the post’s email message-id if it originated from email,
otherwise the Discourse message-id using something like the algorithm
you outline later in this message: anything (a) stable and (b)
syntacticly valid.
Then computing the In-Reply-To and References fields is simple
mechanical stuff as in points 2 and 3.
I think I see what you mean, does it go like this:
cameron sends email to Discourse from mutt which gets Message-ID: 74398756983476983@mail.com
Discourse creates a post and stores the Message-ID with against the post with an IncomingEmail record
Correct.
johndoe is watching the topic, so they get sent an email from Discourse with a Message-ID: topic/222/44@discourse.com and no reference to the original Message-ID: 74398756983476983@mail.com
No. You really want to pass through IncomingEmail.message_id as the Message-ID in the email to johndoe. It’s the same message.
Does that sound correct, that we should just “pass on” that Message-ID to those watching the topic instead of generating our own since it’s already unique? What then happens in johndoe’s mail client if
cameron also CC’d him on that original outbound message? This does sound like a separate issue so it would be good to open another bug topic for it.
By passing it on, the original message (cameron->cc:johndoe) and the
Discourse forwarded message (cameron->Discourse->johndoe) have the same
message-id and the same message contents. The receiving mail system
stores both. The mail reader sees both, and either presents both or
keeps just one (this is a policy decision of the mail reader - keeping
just one is common). Because they’re the same message, in general it
does not matter which is kept.
If we ignored discourse and considered a message which was
a copy of the message via the list and also via direct email. They’re
the same message, with the same message-id.
I will set up a mutt client locally to see what you are also seeing, I have never tested this functionality in a text-based client (only Gmail and Thunderbird) so I am keen to see how it looks anyway.
Happy to help with settings. For threaded view you need to set the
sorting to threadeed. Mutt is very configurable.
My line of thinking to address these issues this morning was to dispose
with the randomly generated suffixes generated when we send Message-ID headers in emails and instead change to a scheme where we
use the user_id of both the sending and receiving user. The benefit
of this is that there is no need to store the Message-ID anywhere
(apart from when an inbound email creates a post) and so References
and In-Reply-To headers will always be consistent.
Yes, that is much better. Noting that the inbound email message-id
should override the Discourse derived message-id for the outbound email.
(Most mail systems use random strings because there’s no surrounding
context such as the discourse topic message structure - messages are
considered alone; but the only real requirement is persistent
uniqueness.)
Let me give an example. Say we have these users:
martin - user_id 25
cameron - user_id 44
sam - user_id 78
bob - user_id 999
And then we have this topic, topic_id 233499, with posts starting from post_id 100 as the OP. The format would become topic/#{topic_id}/#{post_id}.s#{sender_user_id}r#{receiver_user_id}.
There should not be a References header in the OP. It isn’t
needed for threading and effectively pretends there’s some “post 0”
which doesn’t exist. It meeans every OP (a) looks like a reply, which it
is not and (b) looks like the thing to which it is a reply is missing
from the reader’s mailbox.
This makes different message-ids for each outbound copy of the OP.
That’s bad. They need to be the same. Supposing sam CCs cameron
directly in a reply. The In-Reply-To will cite a mesage-id cameron
has never received.
You can just drop the sender_user_id and receiver_user_id from the
message-id field and get a single unique id which every receiver sees.
The uniqueness constraint is the post itself, not the individual
email-level “message” object.
Re the References, the OP should not have one. TB and everything else
will be fine. If they’re threading using References instead of In-Reply-To, the References in the reply messages are enough.
Here’s the start of a mailing list discussion thread in Mutt:
16Jul2022 01:09 Rob Boehne - │├>[Python-Dev] Re: [SPAM] Re: Swit python-dev 9.2K
16Jul2022 01:33 Peter Wang - │├> python-dev 3.0K
16Jul2022 00:24 Skip Montanaro - ├>[Python-Dev] Re: Switching to Dis python-dev 4.2K
16Jul2022 04:49 Erlend Egeberg - ├>[Python-Dev] Re: Switching to Dis python-dev 10K
16Jul2022 04:20 Mariatta - ├>[Python-Dev] Re: Switching to Dis python-dev 10K
15Jul2022 21:18 Petr Viktorin - [Python-Dev] Switching to Discourse python-dev 4.2K
Ignore that I sort my email newest-on-top. See that there’s no arrow on
the initial post (at the bottom). That messgae has no References and
no In-Reply-To. All the others have In-Reply-To (and possibly References, but this is an email mailing list so not necessarily; as I
mentioned before they’re complimentary.)
If I repeat my Discourse example from earlier:
23Jul2022 06:24 Olha via Discus - ┌>[Py] [Users] I need an advise discuss-users 5.7K
22Jul2022 17:12 Paul Jurczak vi - ├>[Py] [Users] I need an advise discuss-users 5.5K
22Jul2022 13:21 Rob via Discuss - ├>[Py] [Users] I need an advise discuss-users 6.8K
22Jul2022 12:53 vasi-h via Disc - ├>[Py] [Users] I need an advise discuss-users 5.5K
22Jul2022 11:38 Cameron Simpson - ├>[Py] [Users] I need an advise discuss-users 14K
22Jul2022 10:27 Rob via Discuss - ├>[Py] [Users] I need an advise discuss-users 6.6K
22Jul2022 06:14 vasi-h via Disc r ┴>[Py] [Users] I need an advise discuss-users 6.5K
See they all have a leading arrow? That is because the mail client
believes they are all replies to a common (and missing) root message,
which is because of the “topic” message-id in the References header.
Whereas post 1 is actually the bottom message displayed above.
Summary:
your plan is good, provided you drop the sender and receiver from the
message-id - they’re unnecessary and in fact the receiver will cause
trouble (the sender is just redundant).
drop the “topic” pseudo-message-id from the References - it misleads
email clients (including TB, even if it isn’t visually evident)
cameron replies via email
discourse is sent an email with these headers from mutt:
Yes, again with the caveat that there should not be a “topic” reference.
As expected, there is a reference to the OP message-id. Though it should
be the same message-id that sam sees for the OP.
discourse (as cameron, from the above email) creates post 101
sam is sent an email from discourse with these headers:
And here it goes wrong. The Message-ID should be 43585349859734@test.com from the .incoming_post.message_id field.
(Well, in my mind this is post.message_id(), which returns post.incoming_post.message_id for an email generated post and your
Discourse generated one otherwise).
Consider: I compose and send my reply with message-id 43585349859734@test.com. For continuity reasons, I keep a copy of that
in my local folder, where it shows as a reply to the OP. Ideally
Discourse also sends me a copy of my own post (this is a policy setting
on many mailing lists), so I get Discourse’s version also. That should
have the same message-id, because it is the same message, just via a
different route.
Discourse’s message is not “in reply to” my message. It is my
message, just forwarded.
This effect cascades through your following examples. The actual process
should be simpler than you’ve made it.
Think of it this way. If I reply to a post from email, it effectively is
like me emailing sam (and the others) via Discourse. Discourse
forwards my message to the email-receiving subscribers, and
“incidentally” keeps a copy on the forum
As a side note, I also looked into what GitHub do with their
notification emails, and noticed they do a similar thing where they
have an ever-present Reference
(discourse/discourse/pull/252@github.com) that is used in all the
emails related to that “topic” which in this case is a GitHub pull
request:
Hoo, github. What a disaster their issue emails are
However, in their scenario, the PR is the OP. So a reference directly
to the pull is sane. You could use the “topic” message-id for post 1,
provided you didn’t also use the “topic/1” id as well. But there seems
little point - it is extra effort to special case post 1 - I’d just use
“topic/1” myself.
To add some complication. As I understand it, an admin can move a post
or topic. Doesn’t that break the “generate the message-id” scheme,
particularly if they move just a post? I’m somewhat of the opinion that
every post should have a _message_id field, filled in from the
incoming message (from email) or generated (posting via Discourse). Then
it is persistent and stable and robust against any shuffling of posts or
changes of algorithm.
Finally, there’s a small security consideration: you should ignore the
inbound email message-id (and potentially bounce the message) if it
claims the message-id of an existing post. Since as an author, I can put
anything I like in that header I’d go with just dropping the
message-id - accept the post, but don’t let it lie about being some
other post - give your copy the Discourse-generated id and then proceed
as normal.
Wow, gracias de nuevo por esta respuesta maravillosamente detallada. Probablemente me tomará un tiempo procesarla y convertirla en elementos procesables, así que ten paciencia con nosotros (además de esto, tengo otros proyectos internos de alta prioridad en los que estoy trabajando actualmente). Creo que con esta información podremos hacer que nuestros sistemas de subprocesos sean mucho más robustos y cumplan con las especificaciones. Puede que tenga más preguntas a medida que revise tu publicación, gracias Cameron.
Por Martin Brennan vía Discourse Meta el 25Jul2022 00:28:
Muchas gracias de nuevo por esta respuesta maravillosamente detallada. Probablemente me tome un tiempo procesarla y convertirla en elementos prácticos, así que tengan paciencia con nosotros (además de esto, tengo otros proyectos internos de alta prioridad en los que estoy trabajando actualmente). Creo que con esta información podremos hacer que nuestros sistemas de hilos sean mucho más robustos y cumplan las especificaciones. Puede que tenga más preguntas a medida que revise su publicación, gracias Cameron.
es decir, ha conservado mi message-id de correo electrónico original. Por lo tanto, In-Reply-To es correcto, y References al menos tiene mi message-id de correo electrónico.
Ah, esa es una observación interesante, no había notado la pequeña flecha.
Esto también es súper interesante. Creo (sin examinar el código) que Thunderbird hace eso, y probablemente la interfaz de Gmail también, ya que hace lo mismo.
Parece que estamos haciendo esto, pero supongo que no de manera consistente. Básicamente, necesitamos asegurarnos de que:
TODO #1 - Si una publicación tiene un registro IncomingEmail asociado, siempre usamos ese Message-ID al enviar correos electrónicos.
TODO #2 - No usar References al enviar correos electrónicos relacionados con el OP del tema.@cameron-simpson, una pregunta: si el OP se creó a través de un correo electrónico entrante, ¿usaríamos ese Message-ID en References para el OP o aún lo excluiríamos?
Esto es interesante, ¿pensé que cada destinatario del correo electrónico tenía que tener un Message-ID único? De hecho, creo que por eso seguimos el camino de agregar unicidad al Message-ID de cada destinatario, para evitar comportamientos de spam, mirando hacia atrás en nuestro tema interno. Quizás @supermathie, que está en nuestro equipo de infraestructura y estuvo haciendo muchas pruebas con el correo electrónico a principios de año, podría opinar aquí también.
Lo que dices es que es más bien la publicación la que debe determinar un único Message-ID para todos los destinatarios. Entonces, ¿quizás generamos uno para cada publicación que genera un correo electrónico? Luego también podríamos mover el IncomingEmail.message_id aquí también. Tentativamente, el cambio que necesitaríamos hacer es:
TODO #3 - Agregar un outbound_message_id a la tabla Post. Generarlo una vez cuando se envía un correo electrónico por primera vez en relación con la publicación. Usarlo para las cabeceras References e In-Reply-To posteriores. Establecer su valor cuando una publicación se crea a partir de un IncomingEmail. El formato debe ser topic/:topic_id/:post_id/:random_alphanumeric_string@host por ejemplo, topic/233499/33545/gvy8475y7c45y87554c@meta.discourse.org
Después de este cambio, mi primer ejemplo se convertiría en esto:
martin crea el OP
cameron recibe un correo electrónico con estas cabeceras:
Con la consideración también de que el OP no tiene un manejo especial, ya no tendrá el formato topic/:topic_id@hostname.
TODO #4 - Asegurar que se generen las cabeceras In-Reply-To y References correctas basadas en los registros PostReply y la nueva columna outbound_message_id en la tabla Post
Creo que tenemos alguna consideración para esto, lo comprobaré.
Definitivamente parece que sí :sonrisa_sudorosa:
¿Puedes confirmar que los TODOs aquí suenan razonables, Cameron? Realmente no parece mucho ahora que lo miro. También me pregunto, cuando llegue a este trabajo, ¿estarías abierto a unirte a una instancia de Discourse de prueba conmigo que tenga los cambios de WIP desplegados para que podamos enviarnos correos electrónicos de ida y vuelta y probar que las cosas funcionan correctamente? Por supuesto, haré pruebas por mi cuenta antes de involucrarte.
Si no, está bien también, tengo Thunderbird y configuraré mutt y podré probarlo todo allí
@cameron-simpson una cosa que quería aclarar aquí es el ámbito de “message_id”.
Lo que inició todo este baile fue una fuerte sospecha de @supermathie de que nuestros message_ids no únicos estaban causando problemas.
Discourse genera correos electrónicos únicos por usuario para cada correo electrónico que envía. Así, por ejemplo, digamos que 2 usuarios están siguiendo este tema:
El Usuario 1 recibe la carga útil 1 con un enlace de cancelación de suscripción distinto dirigido al usuario 1
El Usuario 2 recibe la carga útil 2 con un enlace de cancelación de suscripción distinto dirigido al usuario 2
Si en ambos casos nuestro message id fuera, por ejemplo, discourse_topic_100/23 (topic_id/post_number), entonces estaríamos diciendo a los MTA que discourse_topic_100/23 puede tener 2 cargas útiles distintas. La hipótesis es que lo tratan como una señal de spam.
Oye Discourse… acabas de enviar dos correos electrónicos llamados discourse_topic_100/23, ¿qué pasa?
Dado que Discourse controla todo el transporte de correo electrónico y los correos electrónicos no se añaden a una lista CCO o CC como las listas de correo tradicionales, podemos permitirnos tener enlaces de cancelación de suscripción limpios por usuario.
¿Qué opinas? ¿Qué hay del simple cambio de usar discourse_topic_100/23/7333 (es decir, topic_id, post_number, user_id) como identificador único para el correo? Ciertamente es una carga útil única y podemos referirnos fácilmente a ella al generar correos para un usuario.
By Martin Brennan via Discourse Meta at 26Jul2022 00:27:
[quote=“Cameron Simpson, post:11, topic:233499,
username:cameron-simpson”]
Mutt probably ignores the References
because it is a mail reader, and References originates in USENET news.
Maybe Thunderbird is using the references or augumenting the in-reply-to
with references information.
You only need to consult one of In=-Reply-To or References to do
threading; the former comes from email and the latter from USENET.
You’re supporting both (which is great!) so we need to make them
consistent.
[/quote]
This is also super interesting. I believe (without examining the source) Thunderbird does do that, and likely the Gmail UI as well since it does the same thing.
I think mutt will use both, but probably just In-Reply-To if present, falling back to References. I’d need to check the source.
With References you do at least know the full chain to the OP; with In-Reply-To you more or less need the antecedant messages around to
stitch things together. For mailing lists I usually keep the whole
thread locally until it’s done anyway, and I expect that is common.
We do seem to be doing this but I guess not consistently? Basically we need to make sure that:
TODO #1 - If a post has an associated IncomingEmail record, we always use that Message-ID when sending email.
Yes. This is why I was thinking it might be sanest to have an explicit
field for the message-id, and to fill it in once. Then use that from
then on always, regardless of any changes to the process in which the
message-id is manufactured in the code later.
TODO #2 - Do not use a References when sending out emails related to the OP of the topic .
Yes. The OP has no antecedant, so there’s no References or In-Reply-To.
@cameron-simpson one question though – if the OP was created via an
inbound email, would we use that Message-ID in References for the
OP or still exclude it?
Still exclude. But use it as the persistent message-id for the OP.
So a message authored by email (OP or reply) gets its message-id from
the email. One authored on the web gets one when the user presses
Submit, generated by Discourse. From then on, that’s the message-id,
however created.
[quote=“Cameron Simpson, post:11, topic:233499,
username:cameron-simpson”]
You can just drop the sender_user_id and receiver_user_id from the
message-id field and get a single unique id which every receiver sees.
The uniqueness constraint is the post itself, not the individual
email-level “message” object.
[/quote]
This is interesting, I thought every recipient of the email had to have a unique Message-ID?
No. The message-id identifies the “message”. Not the individual copy. I
might post to the forum and CC someone directly. If that someone gets a
copy direct from me and also via the forum, they should have the same
message-id.
In fact I believe this is why we went down the path of adding
uniqueness to each recipient’s Message-ID, to avoid spam behaviours,
looking back on our internal topic. Perhaps @supermathie , who is on
our infra team and was doing a bunch of testing with email earlier in
the year, could weigh in here too?
Maybe. But on that face of it, threading is indeed broken. Certainly
sending the same message to many people should have the same message-id,
and generally, as a forwarder (email->discourse->email-recipients)
discourse shoud not be modifying the message-ids.
What you are saying is that it’s more that the post should be the thing determining a single Message-ID for all recipients. So perhaps we just generate one for each post that generates an email?
Every post should have one stable unique message-id for use in the email
side. If the post originated from an email, that original message-id
should be used. Otherwise (via the web interface) Discourse should be
generating a message-id and storing it with the post.
Then we could also move the IncomingEmail.message_id to here as well.
Sure. Having a distinct set of fields (message-id seems enough)
containing the email-side state should do it.
Tentatively, the change we would need to make is:
TODO #3 - **Add a outbound_message_id to the Post table. Generate
it once when an email is first sent in relation to the post.
If you got the post from an email, you should be using that, not
generating a new one.
Use if for subsequent References and In-Reply-To headers. Set its
value when a post is created from an IncomingEmail.
Yes. To the message-id from the email.
Format should be topic/:topic_id/:post_id/:random_alphanumeric_string@host e.g. topic/233499/33545/gvy8475y7c45y87554c@meta.discourse.org**
For ones you generate yourselves, this looks good to me.
After this change my first example would become this:
But note: the message-id only needs to be stable and unique. If the topic/:topid_id/:post_id@host is stable and will never be regenerated,
that will do. But if you’re concerned about that (eg db restores or
migrations or imports bringing those same numbers) then the random
string will make it robust against collision.
Note that the message-id left part is dot-atom-text, defined here:
which is alphas and digits and a limited set of punctuation characters
(which includes “/”).
Note the angle brackets. The message-id is formally the bit between the
angle brackets, and the angle brackets are mandatory. Syntax here:
With the consideration also that the OP does not have special handling, it will no longer be in the format topic/:topic_id@hostname.
Sounds good.
TODO #4 - Ensure that correct In-Reply-To and References headers are generated based on PostReply records and the new outbound_message_id column on the Post table
Thanks.
I think we have some consideration for this, I will double-check.
+1
It definitely seems that way
Can you confirm the TODOs here sound reasonable Cameron?
They seem correct to me.
It really doesn’t seem like much now that I look at it. I also wonder,
when I get to this work would you be open to joining a testing
Discourse instance with me that will have the WIP changes deployed to
it so we can email back and forth and test that things are working
correctly? I will of course do testing of my own before I involve you.
Certainly. Happy to help in whatever way.
If not, that’s fine too – I have Thunderbird and will be setting up mutt and I can test it all out there
Aún creo que puedes enviar mensajes distintos con el mismo message-id, incluso con pequeñas diferencias como esta.
Las listas de correo ordinarias hacen esto todo el tiempo en mayor o menor medida. Al menos siempre ocurre alguna manipulación de las cabeceras. Pero el cuerpo del mensaje también se modifica a veces. Un ejemplo egregio es python-list, que descarta los adjuntos que no son de texto. El mensaje continúa con el mismo message-id. Y casi todas las listas añaden un aviso al final con, por ejemplo, un enlace a la página de administración de la lista o un enlace para darse de baja. Eso no habrá estado en el mensaje cuando llegó.
Y ha habido largas discusiones sobre la firma de contenido que giran en torno a lo que debe cubrir una firma.
Así que estaría totalmente de acuerdo con que añadas tu enlace de cancelación de suscripción específico para el destinatario y conserves el message-id original. Los beneficios superan con creces la pérdida de encadenamiento si dieras a cada copia del mensaje un message-id individual.
De nuevo, considera al usuario de correo electrónico. Puedo responder a un mensaje de Discourse y añadir una copia a una persona externa interesada. Quizás reciba una copia de Discourse, o quizás no. Pero si lo hiciera, debería tener el message-id de origen, incluso con tu aviso adicional. De lo contrario, tendrá 2 copias de mi mensaje, pero su sistema de correo no sabrá que son copias del mismo mensaje. Se producirán problemas.
Así que, en resumen: No creo que tu texto adicional de cancelación de suscripción, muy menor, justifique message-id distintos. Conserva solo uno.
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 (para este propósito, Para/De/Responder a/Cancelar suscripción/etc.) y un cuerpo diferente (está personalizado por usuario (¿creo? ¿No sucede esto en el modo de lista de correo?)).
¿Qué es exactamente el mensaje? Tratando 5322 como dogma:
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” la 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. 5322 también dice:
Hay muchas instancias en las que los mensajes se “cambian”, pero esos cambios 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 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 tales encabezados
los campos no cambia la identidad del mensaje y, por lo tanto, el original
se conserva el campo “Message-ID:”. 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, no cualquier diferencia sintáctica particular que
aparece (o no aparece) en el mensaje.
Supongo que se reduce a si el remitente del mensaje cambia cuando Discourse lo envía.
¿Quizás deberíamos usar Resent-Message-ID y sus amigos?
Siempre ha estado ahí, desde 822. Pero como dices más tarde, sí, se ha actualizado.
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 “Identificador de Hilo” 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”.
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.
Y sí, vi fuertes indicios durante las pruebas de que la determinación de spam estaría ligada a un Message-ID. Si se volviera a ver más tarde (mismo usuario o diferente usuario) sería mucho más probable que se marcara como spam.
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.
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: ya es bastante difícil que el correo electrónico se entregue cuando no hay visibilidad de los principales proveedores.
Pero veo un fuerte argumento para hacer que Discourse se comporte más como software de lista de correo en modo de lista de correo. @martin, creo que no personalizamos el cuerpo del mensaje en modo de lista de correo, ¿verdad? ¿Crees que tiene sentido adoptar un enfoque más estricto para conservar y reutilizar Message-IDs en modo de lista de correo?
No quiero estar en una situación en la que lo perfecto sea enemigo de lo suficientemente bueno aquí.
Ahora usamos “sufijo aleatorio” en los mensajes y esto está causando indudablemente problemas.
Tenemos 3 opciones sobre la mesa:
IDs de mensaje aleatorios que no se pueden referenciar.
IDs de mensaje estables por tema/publicación/usuario.
IDs de mensaje estables por par tema/publicación.
Actualmente estamos en el planeta (1) que está causando estragos.
Me preocupa que podamos llegar a una parálisis de decisiones entre (2) y (3).
¿Quizás simplemente comenzamos con (2) reconociendo que agregar CC adicionales a un correo electrónico de Discourse puede causar un comportamiento inesperado, y al menos detener la mayor parte del problema aquí?
¡Ah! Pensé que ya estábamos haciendo: topic/#{topic_id}/#{post_id}.s#{sender_user_id}r#{receiver_user_id}
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.
De manera similar, con la cabecera References, me inclinaría a que esté ausente para la publicación n.º 1 en un tema 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.